summaryrefslogtreecommitdiff
path: root/daemons
diff options
context:
space:
mode:
authorandrew-elder <aelder@audioscience.com>2017-04-28 15:26:51 -0400
committerGitHub <noreply@github.com>2017-04-28 15:26:51 -0400
commit3a716d352430125181da647af4f8ddeabdf9151b (patch)
treea897a41f60fc766594b6543cd2a83c6af7e9a97d /daemons
parent76413ddd9e921445c9e775169fc07babd0b8530d (diff)
parent27182b036e83309e7bf6eb33ac49289aa020f537 (diff)
downloadOpen-AVB-3a716d352430125181da647af4f8ddeabdf9151b.tar.gz
Merge pull request #585 from christopher-s-hall/open-avb-next
Separate common port functionality from Ethernet port functionality
Diffstat (limited to 'daemons')
-rw-r--r--daemons/gptp/common/ap_message.cpp6
-rw-r--r--daemons/gptp/common/avbap_message.hpp10
-rw-r--r--daemons/gptp/common/avbts_clock.hpp44
-rw-r--r--daemons/gptp/common/avbts_message.hpp141
-rw-r--r--daemons/gptp/common/avbts_oscondition.hpp2
-rw-r--r--daemons/gptp/common/avbts_osipc.hpp2
-rw-r--r--daemons/gptp/common/avbts_oslock.hpp2
-rw-r--r--daemons/gptp/common/avbts_osnet.hpp2
-rw-r--r--daemons/gptp/common/avbts_osthread.hpp3
-rw-r--r--daemons/gptp/common/avbts_ostimer.hpp2
-rw-r--r--daemons/gptp/common/avbts_port.hpp1712
-rw-r--r--daemons/gptp/common/common_port.cpp709
-rw-r--r--daemons/gptp/common/common_port.hpp1344
-rw-r--r--daemons/gptp/common/ether_port.cpp908
-rw-r--r--daemons/gptp/common/ether_port.hpp624
-rw-r--r--daemons/gptp/common/ieee1588.hpp27
-rw-r--r--daemons/gptp/common/ieee1588clock.cpp19
-rw-r--r--daemons/gptp/common/ieee1588port.cpp1422
-rw-r--r--daemons/gptp/common/ptp_message.cpp78
-rw-r--r--daemons/gptp/linux/build/Makefile13
-rw-r--r--daemons/gptp/linux/src/daemon_cl.cpp10
-rw-r--r--daemons/gptp/linux/src/linux_hal_common.cpp17
-rw-r--r--daemons/gptp/linux/src/linux_hal_common.hpp13
-rw-r--r--daemons/gptp/linux/src/linux_hal_generic.cpp3
-rw-r--r--daemons/gptp/linux/src/linux_hal_generic.hpp4
-rw-r--r--daemons/gptp/windows/daemon_cl/daemon_cl.cpp6
-rw-r--r--daemons/gptp/windows/daemon_cl/windows_hal.cpp2
-rw-r--r--daemons/gptp/windows/daemon_cl/windows_hal.hpp20
28 files changed, 3825 insertions, 3320 deletions
diff --git a/daemons/gptp/common/ap_message.cpp b/daemons/gptp/common/ap_message.cpp
index c216e6b3..df121838 100644
--- a/daemons/gptp/common/ap_message.cpp
+++ b/daemons/gptp/common/ap_message.cpp
@@ -26,7 +26,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <ieee1588.hpp>
#include <avbts_clock.hpp>
#include <avbap_message.hpp>
-#include <avbts_port.hpp>
+#include <ether_port.hpp>
#include <avbts_ostimer.hpp>
#include <gptp_log.hpp>
@@ -55,11 +55,11 @@ APMessageTestStatus::~APMessageTestStatus()
{
}
-APMessageTestStatus::APMessageTestStatus(IEEE1588Port * port)
+APMessageTestStatus::APMessageTestStatus( EtherPort *port )
{
}
-void APMessageTestStatus::sendPort(IEEE1588Port * port)
+void APMessageTestStatus::sendPort( EtherPort * port )
{
static uint16_t sequenceId = 0;
diff --git a/daemons/gptp/common/avbap_message.hpp b/daemons/gptp/common/avbap_message.hpp
index fc72c0f5..4c66f758 100644
--- a/daemons/gptp/common/avbap_message.hpp
+++ b/daemons/gptp/common/avbap_message.hpp
@@ -88,9 +88,9 @@ class APMessageTestStatus {
public:
/**
* @brief Default constructor. Creates APMessageTestStatus
- * @param port IEEE1588Port
+ * @param port EtherPort
*/
- APMessageTestStatus(IEEE1588Port * port);
+ APMessageTestStatus( EtherPort *port );
/**
* @brief Destroys APMessageTestStatus interface
@@ -99,11 +99,11 @@ class APMessageTestStatus {
/**
* @brief Assembles APMessageTestStatus message on the
- * IEEE1588Port payload
- * @param port IEEE1588Port where the message will be assembled
+ * EtherPort payload
+ * @param port EtherPort where the message will be assembled
* @return void
*/
- void sendPort(IEEE1588Port * port);
+ void sendPort( EtherPort *port );
};
diff --git a/daemons/gptp/common/avbts_clock.hpp b/daemons/gptp/common/avbts_clock.hpp
index 0f7e60cf..464b90d1 100644
--- a/daemons/gptp/common/avbts_clock.hpp
+++ b/daemons/gptp/common/avbts_clock.hpp
@@ -36,7 +36,7 @@
#include <stdint.h>
#include <ieee1588.hpp>
-#include <avbts_port.hpp>
+#include <common_port.hpp>
#include <avbts_ostimerq.hpp>
#include <avbts_osipc.hpp>
@@ -121,7 +121,7 @@ private:
float _ppm;
int _phase_error_violation;
- IEEE1588Port *port_list[MAX_PORTS];
+ CommonPort *port_list[MAX_PORTS];
static Timestamp start_time;
Timestamp last_sync_time;
@@ -163,12 +163,13 @@ private:
/**
* @brief Add a new event to the timer queue
- * @param target IEEE1588Port target
+ * @param target EtherPort target
* @param e Event to be added
* @param time_ns Time in nanoseconds
*/
void addEventTimer
- ( IEEE1588Port * target, Event e, unsigned long long time_ns );
+ ( CommonPort *target, Event e,
+ unsigned long long time_ns );
/**
* @brief Deletes an event from the timer queue
@@ -176,7 +177,7 @@ private:
* @param e Event to be removed
* @return void
*/
- void deleteEventTimer(IEEE1588Port * target, Event e);
+ void deleteEventTimer( CommonPort *target, Event e );
public:
/**
* @brief Instantiates a IEEE 1588 Clock
@@ -467,12 +468,13 @@ public:
* @param index Port's index
* @return void
*/
- void registerPort(IEEE1588Port * port, uint16_t index) {
+ void registerPort( CommonPort *port, uint16_t index )
+ {
if (index < MAX_PORTS) {
port_list[index - 1] = port;
}
++number_ports;
- }
+ }
/**
* @brief Gets the current port list instance
@@ -480,7 +482,7 @@ public:
* @param ports [out] Pointer to the port list
* @return
*/
- void getPortList(int &count, IEEE1588Port ** &ports) {
+ void getPortList(int &count, CommonPort ** &ports) {
ports = this->port_list;
count = number_ports;
return;
@@ -494,13 +496,13 @@ public:
/**
* @brief Adds an event to the timer queue using a lock
- * @param target IEEE1588Port target
+ * @param target EtherPort target
* @param e Event to be added
* @param time_ns event time in nanoseconds
* @return void
*/
void addEventTimerLocked
- ( IEEE1588Port * target, Event e, unsigned long long time_ns );
+ ( CommonPort *target, Event e, unsigned long long time_ns );
/**
* @brief Deletes and event from the timer queue using a lock
@@ -508,7 +510,7 @@ public:
* @param e Event to be deleted
* @return
*/
- void deleteEventTimerLocked(IEEE1588Port * target, Event e);
+ void deleteEventTimerLocked( CommonPort *target, Event e );
/**
* @brief Calculates the master to local clock rate difference
@@ -542,15 +544,11 @@ public:
* @param asCapable asCapable flag
*/
void setMasterOffset
- ( IEEE1588Port * port, int64_t master_local_offset, Timestamp local_time,
- FrequencyRatio master_local_freq_offset,
- int64_t local_system_offset,
- Timestamp system_time,
- FrequencyRatio local_system_freq_offset,
- unsigned sync_count,
- unsigned pdelay_count,
- PortState port_state,
- bool asCapable );
+ ( CommonPort *port, int64_t master_local_offset,
+ Timestamp local_time, FrequencyRatio master_local_freq_offset,
+ int64_t local_system_offset, Timestamp system_time,
+ FrequencyRatio local_system_freq_offset, unsigned sync_count,
+ unsigned pdelay_count, PortState port_state, bool asCapable );
/**
* @brief Get the IEEE1588Clock identity value
@@ -574,7 +572,7 @@ public:
*/
void restartPDelayAll() {
int number_ports, i, j = 0;
- IEEE1588Port **ports;
+ CommonPort **ports;
getPortList( number_ports, ports );
@@ -590,7 +588,7 @@ public:
*/
int getTxLockAll() {
int number_ports, i, j = 0;
- IEEE1588Port **ports;
+ CommonPort **ports;
getPortList( number_ports, ports );
@@ -610,7 +608,7 @@ public:
*/
int putTxLockAll() {
int number_ports, i, j = 0;
- IEEE1588Port **ports;
+ CommonPort **ports;
getPortList( number_ports, ports );
diff --git a/daemons/gptp/common/avbts_message.hpp b/daemons/gptp/common/avbts_message.hpp
index 40472bd9..55492022 100644
--- a/daemons/gptp/common/avbts_message.hpp
+++ b/daemons/gptp/common/avbts_message.hpp
@@ -235,9 +235,10 @@ protected:
public:
/**
* @brief Creates the PTPMessageCommon interface
- * @param port IEEE1588Port where the message interface is connected to.
+ * @param port EtherPort where the message interface is
+ * connected to.
*/
- PTPMessageCommon(IEEE1588Port * port);
+ PTPMessageCommon( CommonPort *port );
/**
* @brief Destroys PTPMessageCommon interface
*/
@@ -359,7 +360,7 @@ protected:
* @param port IEEE1588 port
* @return void
*/
- virtual void processMessage(IEEE1588Port * port);
+ virtual void processMessage( EtherPort *port );
/**
* @brief Builds PTP common header
@@ -369,7 +370,8 @@ protected:
void buildCommonHeader(uint8_t * buf);
friend PTPMessageCommon *buildPTPMessage
- (char *buf, int size, LinkLayerAddress * remote, IEEE1588Port * port);
+ ( char *buf, int size, LinkLayerAddress * remote,
+ EtherPort *port );
};
/*Exact fit. No padding*/
@@ -505,7 +507,7 @@ class PTPMessageAnnounce:public PTPMessageCommon {
/**
* @brief Creates the PTPMessageAnnounce interface
*/
- PTPMessageAnnounce(IEEE1588Port * port);
+ PTPMessageAnnounce( CommonPort * port );
/**
* @brief Destroys the PTPMessageAnnounce interface
@@ -573,22 +575,25 @@ class PTPMessageAnnounce:public PTPMessageCommon {
/**
* @brief Processes PTP message
- * @param port IEEE1588Port
+ * @param port EtherPort
* @return void
*/
- void processMessage(IEEE1588Port * port);
+ void processMessage( EtherPort *port );
/**
- * @brief Assembles PTPMessageAnnounce message on the IEEE1588Port payload
- * @param port IEEE1588Port where the message will be assembled
+ * @brief Assembles PTPMessageAnnounce message on the
+ * EtherPort payload
+ * @param port EtherPort where the message will be
+ * assembled
* @param destIdentity [in] Destination PortIdentity
* @return void
*/
- void sendPort(IEEE1588Port * port, PortIdentity * destIdentity);
+ void sendPort
+ ( CommonPort *port, PortIdentity *destIdentity);
- friend PTPMessageCommon *buildPTPMessage(char *buf, int size,
- LinkLayerAddress * remote,
- IEEE1588Port * port);
+ friend PTPMessageCommon *buildPTPMessage
+ ( char *buf, int size, LinkLayerAddress *remote,
+ EtherPort *port );
};
/**
@@ -602,9 +607,9 @@ class PTPMessageSync : public PTPMessageCommon {
public:
/**
* @brief Default constructor. Creates PTPMessageSync
- * @param port IEEE1588Port
+ * @param port EtherPort
*/
- PTPMessageSync(IEEE1588Port * port);
+ PTPMessageSync( EtherPort *port );
/**
* @brief Destroys PTPMessageSync interface
@@ -613,10 +618,10 @@ class PTPMessageSync : public PTPMessageCommon {
/**
* @brief Processes PTP messages
- * @param port [in] IEEE1588Port
+ * @param port [in] EtherPort
* @return void
*/
- void processMessage(IEEE1588Port * port);
+ void processMessage( EtherPort *port );
/**
* @brief Gets origin timestamp value
@@ -627,15 +632,19 @@ class PTPMessageSync : public PTPMessageCommon {
}
/**
- * @brief Assembles PTPMessageSync message on the IEEE1588Port payload
- * @param port IEEE1588Port where the message will be assembled
+ * @brief Assembles PTPMessageSync message on the
+ * EtherPort payload
+ * @param port EtherPort where the message will be
+ * assembled
* @param destIdentity [in] Destination PortIdentity
* @return void
*/
- void sendPort(IEEE1588Port * port, PortIdentity * destIdentity);
+ void sendPort
+ (EtherPort *port, PortIdentity *destIdentity );
friend PTPMessageCommon *buildPTPMessage
- (char *buf, int size, LinkLayerAddress * remote, IEEE1588Port * port);
+ ( char *buf, int size, LinkLayerAddress * remote,
+ EtherPort *port );
};
/* Exact fit. No padding*/
@@ -841,22 +850,26 @@ public:
/**
* @brief Builds the PTPMessageFollowUP object
*/
- PTPMessageFollowUp(IEEE1588Port * port);
+ PTPMessageFollowUp( EtherPort *port );
/**
- * @brief Assembles PTPMessageFollowUp message on the IEEE1588Port payload
- * @param port IEEE1588Port where the message will be assembled
+ * @brief Assembles PTPMessageFollowUp message on the
+ * EtherPort payload
+ * @param port EtherPort where the message will be
+ * assembled
* @param destIdentity [in] Destination PortIdentity
* @return void
*/
- void sendPort(IEEE1588Port * port, PortIdentity * destIdentity);
+ void sendPort
+ ( EtherPort *port, PortIdentity *destIdentity );
/**
* @brief Processes PTP messages
- * @param port [in] IEEE1588Port
+ * @param port [in] EtherPort
* @return void
*/
- void processMessage(IEEE1588Port * port);
+ void processMessage( EtherPort *port );
+
/**
* @brief Gets the precise origin timestamp value
* @return preciseOriginTimestamp value
@@ -887,7 +900,8 @@ public:
}
friend PTPMessageCommon *buildPTPMessage
- (char *buf, int size, LinkLayerAddress * remote, IEEE1588Port * port);
+ ( char *buf, int size, LinkLayerAddress *remote,
+ EtherPort *port );
};
/**
@@ -910,22 +924,25 @@ class PTPMessagePathDelayReq : public PTPMessageCommon {
/**
* @brief Builds the PTPMessagePathDelayReq message
*/
- PTPMessagePathDelayReq(IEEE1588Port * port);
+ PTPMessagePathDelayReq( EtherPort *port );
/**
- * @brief Assembles PTPMessagePathDelayReq message on the IEEE1588Port payload
- * @param port IEEE1588Port where the message will be assembled
+ * @brief Assembles PTPMessagePathDelayReq message on the
+ * EtherPort payload
+ * @param port EtherPort where the message will be
+ * assembled
* @param destIdentity [in] Destination PortIdentity
* @return void
*/
- void sendPort(IEEE1588Port * port, PortIdentity * destIdentity);
+ void sendPort
+ ( EtherPort *port, PortIdentity *destIdentity );
/**
* @brief Processes PTP messages
- * @param port [in] IEEE1588Port
+ * @param port [in] EtherPort
* @return void
*/
- void processMessage(IEEE1588Port * port);
+ void processMessage( EtherPort *port );
/**
* @brief Gets origin timestamp value
@@ -936,7 +953,8 @@ class PTPMessagePathDelayReq : public PTPMessageCommon {
}
friend PTPMessageCommon *buildPTPMessage
- (char *buf, int size, LinkLayerAddress * remote, IEEE1588Port * port);
+ ( char *buf, int size, LinkLayerAddress *remote,
+ EtherPort *port );
};
/**
@@ -957,22 +975,25 @@ public:
/**
* @brief Builds the PTPMessagePathDelayResp object
*/
- PTPMessagePathDelayResp(IEEE1588Port * port);
+ PTPMessagePathDelayResp( EtherPort *port );
/**
- * @brief Assembles PTPMessagePathDelayResp message on the IEEE1588Port payload
- * @param port IEEE1588Port where the message will be assembled
+ * @brief Assembles PTPMessagePathDelayResp message on the
+ * EtherPort payload
+ * @param port EtherPort where the message will be
+ * assembled
* @param destIdentity [in] Destination PortIdentity
* @return void
*/
- void sendPort(IEEE1588Port * port, PortIdentity * destIdentity);
+ void sendPort
+ ( EtherPort *port, PortIdentity *destIdentity );
/**
* @brief Processes PTP messages
- * @param port [in] IEEE1588Port
+ * @param port [in] EtherPort
* @return void
*/
- void processMessage(IEEE1588Port * port);
+ void processMessage( EtherPort *port );
/**
* @brief Sets the request receipt timestamp
@@ -1005,7 +1026,8 @@ public:
}
friend PTPMessageCommon *buildPTPMessage
- (char *buf, int size, LinkLayerAddress * remote, IEEE1588Port * port);
+ ( char *buf, int size, LinkLayerAddress *remote,
+ EtherPort *port );
};
/**
@@ -1022,7 +1044,7 @@ public:
/**
* @brief Builds the PTPMessagePathDelayRespFollowUp object
*/
- PTPMessagePathDelayRespFollowUp(IEEE1588Port * port);
+ PTPMessagePathDelayRespFollowUp( EtherPort *port );
/**
* @brief Destroys the PTPMessagePathDelayRespFollowUp object
@@ -1030,19 +1052,22 @@ public:
~PTPMessagePathDelayRespFollowUp();
/**
- * @brief Assembles PTPMessageRespFollowUp message on the IEEE1588Port payload
- * @param port IEEE1588Port where the message will be assembled
+ * @brief Assembles PTPMessageRespFollowUp message on the
+ * EtherPort payload
+ * @param port EtherPort where the message will be
+ * assembled
* @param destIdentity [in] Destination PortIdentity
* @return void
*/
- void sendPort(IEEE1588Port * port, PortIdentity * destIdentity);
+ void sendPort
+ ( EtherPort *port, PortIdentity *destIdentity );
/**
* @brief Processes PTP messages
- * @param port [in] IEEE1588Port
+ * @param port [in] EtherPort
* @return void
*/
- void processMessage(IEEE1588Port * port);
+ void processMessage( EtherPort *port );
/**
* @brief Sets the response origin timestamp
@@ -1075,7 +1100,8 @@ public:
}
friend PTPMessageCommon *buildPTPMessage
- (char *buf, int size, LinkLayerAddress * remote, IEEE1588Port * port);
+ ( char *buf, int size, LinkLayerAddress *remote,
+ EtherPort *port );
};
/*Exact fit. No padding*/
@@ -1198,7 +1224,7 @@ public:
/**
* @brief Builds the PTPMessageSignalling object
*/
- PTPMessageSignalling(IEEE1588Port * port);
+ PTPMessageSignalling( EtherPort *port );
/**
* @brief Destroys the PTPMessageSignalling object
@@ -1216,22 +1242,25 @@ public:
/**
* @brief Assembles PTPMessageSignalling message on the
- * IEEE1588Port payload
- * @param port IEEE1588Port where the message will be assembled
+ * EtherPort payload
+ * @param port EtherPort where the message will be
+ * assembled
* @param destIdentity [in] Destination PortIdentity
* @return void
*/
- void sendPort(IEEE1588Port * port, PortIdentity * destIdentity);
+ void sendPort
+ ( EtherPort *port, PortIdentity *destIdentity );
/**
* @brief Processes PTP messages
- * @param port [in] IEEE1588Port
+ * @param port [in] EtherPort
* @return void
*/
- void processMessage(IEEE1588Port * port);
+ void processMessage( EtherPort *port );
friend PTPMessageCommon *buildPTPMessage
- (char *buf, int size, LinkLayerAddress * remote, IEEE1588Port * port);
+ ( char *buf, int size, LinkLayerAddress *remote,
+ EtherPort * port);
};
#endif
diff --git a/daemons/gptp/common/avbts_oscondition.hpp b/daemons/gptp/common/avbts_oscondition.hpp
index 5072cfab..93511391 100644
--- a/daemons/gptp/common/avbts_oscondition.hpp
+++ b/daemons/gptp/common/avbts_oscondition.hpp
@@ -109,7 +109,7 @@ public:
* @brief Creates OSCondition class
* @return Pointer to OSCondition object
*/
- virtual OSCondition * createCondition() = 0;
+ virtual OSCondition *createCondition() const = 0;
/**
* @brief Destroys OSCondition objects
diff --git a/daemons/gptp/common/avbts_osipc.hpp b/daemons/gptp/common/avbts_osipc.hpp
index 4d3daf3a..14819964 100644
--- a/daemons/gptp/common/avbts_osipc.hpp
+++ b/daemons/gptp/common/avbts_osipc.hpp
@@ -36,7 +36,7 @@
#include <stdint.h>
#include <ptptypes.hpp>
-#include <avbts_port.hpp>
+#include <ether_port.hpp>
/**@file*/
diff --git a/daemons/gptp/common/avbts_oslock.hpp b/daemons/gptp/common/avbts_oslock.hpp
index 9de07e58..c53b904b 100644
--- a/daemons/gptp/common/avbts_oslock.hpp
+++ b/daemons/gptp/common/avbts_oslock.hpp
@@ -103,7 +103,7 @@ class OSLockFactory {
* @param type Enumeration OSLockType
* @return Pointer to an enumeration of type OSLock
*/
- virtual OSLock * createLock(OSLockType type) = 0;
+ virtual OSLock *createLock(OSLockType type) const = 0;
virtual ~OSLockFactory() = 0;
};
diff --git a/daemons/gptp/common/avbts_osnet.hpp b/daemons/gptp/common/avbts_osnet.hpp
index bb190a8f..1319326c 100644
--- a/daemons/gptp/common/avbts_osnet.hpp
+++ b/daemons/gptp/common/avbts_osnet.hpp
@@ -325,7 +325,7 @@ class OSNetworkInterface {
/**
* @brief Watch for netlink changes.
*/
- virtual void watchNetLink(IEEE1588Port *pPort) = 0;
+ virtual void watchNetLink( CommonPort *pPort ) = 0;
/**
* @brief Provides generic method for getting the payload offset
diff --git a/daemons/gptp/common/avbts_osthread.hpp b/daemons/gptp/common/avbts_osthread.hpp
index d191b650..9464512f 100644
--- a/daemons/gptp/common/avbts_osthread.hpp
+++ b/daemons/gptp/common/avbts_osthread.hpp
@@ -47,6 +47,7 @@ typedef enum { osthread_ok, osthread_error } OSThreadExitCode;
* @brief Provides the OSThreadExitCode callback format
*/
typedef OSThreadExitCode(*OSThreadFunction) (void *);
+typedef void *OSThreadFunctionArg;
/**
* @brief Provides a generic interface for threads
@@ -81,7 +82,7 @@ public:
* @brief Creates a new thread
* @return Pointer to OSThread object
*/
- virtual OSThread * createThread() = 0;
+ virtual OSThread * createThread() const = 0;
/**
* @brief Destroys the new thread
diff --git a/daemons/gptp/common/avbts_ostimer.hpp b/daemons/gptp/common/avbts_ostimer.hpp
index f416f008..cacdfc95 100644
--- a/daemons/gptp/common/avbts_ostimer.hpp
+++ b/daemons/gptp/common/avbts_ostimer.hpp
@@ -65,7 +65,7 @@ public:
* @brief Creates the OSTimer
* @return Pointer to OSTimer object
*/
- virtual OSTimer * createTimer() = 0;
+ virtual OSTimer *createTimer() const = 0;
/*
* Destroys the OSTimer previsouly created
diff --git a/daemons/gptp/common/avbts_port.hpp b/daemons/gptp/common/avbts_port.hpp
deleted file mode 100644
index d1806099..00000000
--- a/daemons/gptp/common/avbts_port.hpp
+++ /dev/null
@@ -1,1712 +0,0 @@
-/******************************************************************************
-
- Copyright (c) 2009-2012, Intel Corporation
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
-******************************************************************************/
-
-#ifndef AVBTS_PORT_HPP
-#define AVBTS_PORT_HPP
-
-#include <ieee1588.hpp>
-#include <avbts_message.hpp>
-#include <avbap_message.hpp>
-
-#include <avbts_ostimer.hpp>
-#include <avbts_oslock.hpp>
-#include <avbts_osnet.hpp>
-#include <avbts_osthread.hpp>
-#include <avbts_oscondition.hpp>
-#include <ipcdef.hpp>
-#include <gptp_log.hpp>
-
-#include <stdint.h>
-
-#include <map>
-#include <list>
-
-/**@file*/
-
-#define GPTP_MULTICAST 0x0180C200000EULL /*!< GPTP multicast adddress */
-#define PDELAY_MULTICAST GPTP_MULTICAST /*!< PDELAY Multicast value */
-#define OTHER_MULTICAST GPTP_MULTICAST /*!< OTHER multicast value */
-#define TEST_STATUS_MULTICAST 0x011BC50AC000ULL /*!< AVnu Automotive profile test status msg Multicast value */
-
-#define PDELAY_RESP_RECEIPT_TIMEOUT_MULTIPLIER 3 /*!< PDelay timeout multiplier*/
-#define SYNC_RECEIPT_TIMEOUT_MULTIPLIER 3 /*!< Sync receipt timeout multiplier*/
-#define ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER 3 /*!< Announce receipt timeout multiplier*/
-
-#define LOG2_INTERVAL_INVALID -127 /* Simple out of range Log base 2 value used for Sync and PDelay msg internvals */
-
-/**
- * @brief PortType enumeration. Selects between delay request-response (E2E) mechanism
- * or PTPV1 or PTPV2 P2P (peer delay) mechanism.
- */
-typedef enum {
- V1,
- V2_E2E,
- V2_P2P
-} PortType;
-
-/**
- * @brief PortIdentity interface
- * Defined at IEEE 802.1AS Clause 8.5.2
- */
-class PortIdentity {
-private:
- ClockIdentity clock_id;
- uint16_t portNumber;
-public:
- /**
- * @brief Default Constructor
- */
- PortIdentity() { };
-
- /**
- * @brief Constructs PortIdentity interface.
- * @param clock_id Clock ID value as defined at IEEE 802.1AS Clause 8.5.2.2
- * @param portNumber Port Number
- */
- PortIdentity(uint8_t * clock_id, uint16_t * portNumber) {
- this->portNumber = *portNumber;
- this->portNumber = PLAT_ntohs(this->portNumber);
- this->clock_id.set(clock_id);
- }
-
- /**
- * @brief Implements the operator '!=' overloading method. Compares clock_id and portNumber.
- * @param cmp Constant PortIdentity value to be compared against.
- * @return TRUE if the comparison value differs from the object's PortIdentity value. FALSE otherwise.
- */
- bool operator!=(const PortIdentity & cmp) const {
- return
- !(this->clock_id == cmp.clock_id) ||
- this->portNumber != cmp.portNumber ? true : false;
- }
-
- /**
- * @brief Implements the operator '==' overloading method. Compares clock_id and portNumber.
- * @param cmp Constant PortIdentity value to be compared against.
- * @return TRUE if the comparison value equals to the object's PortIdentity value. FALSE otherwise.
- */
- bool operator==(const PortIdentity & cmp)const {
- return
- this->clock_id == cmp.clock_id &&
- this->portNumber == cmp.portNumber ? true : false;
- }
-
- /**
- * @brief Implements the operator '<' overloading method. Compares clock_id and portNumber.
- * @param cmp Constant PortIdentity value to be compared against.
- * @return TRUE if the comparison value is lower than the object's PortIdentity value. FALSE otherwise.
- */
- bool operator<(const PortIdentity & cmp)const {
- return
- this->clock_id < cmp.clock_id ?
- true : this->clock_id == cmp.clock_id &&
- this->portNumber < cmp.portNumber ? true : false;
- }
-
- /**
- * @brief Implements the operator '>' overloading method. Compares clock_id and portNumber.
- * @param cmp Constant PortIdentity value to be compared against.
- * @return TRUE if the comparison value is greater than the object's PortIdentity value. FALSE otherwise.
- */
- bool operator>(const PortIdentity & cmp)const {
- return
- this->clock_id > cmp.clock_id ?
- true : this->clock_id == cmp.clock_id &&
- this->portNumber > cmp.portNumber ? true : false;
- }
-
- /**
- * @brief Gets the ClockIdentity string
- * @param id [out] Pointer to an array of octets.
- * @return void
- */
- void getClockIdentityString(uint8_t *id) {
- clock_id.getIdentityString(id);
- }
-
- /**
- * @brief Sets the ClockIdentity.
- * @param clock_id Clock Identity to be set.
- * @return void
- */
- void setClockIdentity(ClockIdentity clock_id) {
- this->clock_id = clock_id;
- }
-
- /**
- * @brief Gets the clockIdentity value
- * @return A copy of Clock identity value.
- */
- ClockIdentity getClockIdentity( void ) {
- return this->clock_id;
- }
-
- /**
- * @brief Gets the port number following the network byte order, i.e. Big-Endian.
- * @param id [out] Port number
- * @return void
- */
- void getPortNumberNO(uint16_t * id) { // Network byte order
- uint16_t portNumberNO = PLAT_htons(portNumber);
- *id = portNumberNO;
- }
-
- /**
- * @brief Gets the port number in the host byte order, which can be either Big-Endian
- * or Little-Endian, depending on the processor where it is running.
- * @param id Port number
- * @return void
- */
- void getPortNumber(uint16_t * id) { // Host byte order
- *id = portNumber;
- }
-
- /**
- * @brief Sets the Port number
- * @param id [in] Port number
- * @return void
- */
- void setPortNumber(uint16_t * id) {
- portNumber = *id;
- }
-};
-
-/**
- * @brief Provides a map for the identityMap member of IEEE1588Port class
- */
-typedef std::map < PortIdentity, LinkLayerAddress > IdentityMap_t;
-
-/**
- * @brief Structure for initializing the IEEE1588 class
- */
-typedef struct {
- /* clock IEEE1588Clock instance */
- IEEE1588Clock * clock;
-
- /* index Interface index */
- uint16_t index;
-
- /* forceSlave Forces port to be slave */
- bool forceSlave;
-
- /* timestamper Hardware timestamper instance */
- HWTimestamper * timestamper;
-
- /* offset Initial clock offset */
- int32_t offset;
-
- /* net_label Network label */
- InterfaceLabel * net_label;
-
- /* automotive_profile set the AVnu automotive profile */
- bool automotive_profile;
-
- /* Set to true if the port is the grandmaster. Used for fixed GM in the the AVnu automotive profile */
- bool isGM;
-
- /* Set to true if the port is the grandmaster. Used for fixed GM in the the AVnu automotive profile */
- bool testMode;
-
- /* Set to true if the port's network interface is up. Used to filter false LINKUP/LINKDOWN events */
- bool linkUp;
-
- /* gPTP 10.2.4.4 */
- char initialLogSyncInterval;
-
- /* gPTP 11.5.2.2 */
- char initialLogPdelayReqInterval;
-
- /* CDS 6.2.1.5 */
- char operLogPdelayReqInterval;
-
- /* CDS 6.2.1.6 */
- char operLogSyncInterval;
-
- /* condition_factory OSConditionFactory instance */
- OSConditionFactory * condition_factory;
-
- /* thread_factory OSThreadFactory instance */
- OSThreadFactory * thread_factory;
-
- /* timer_factory OSTimerFactory instance */
- OSTimerFactory * timer_factory;
-
- /* lock_factory OSLockFactory instance */
- OSLockFactory * lock_factory;
-} IEEE1588PortInit_t;
-
-
-/**
- * @brief Structure for IEE1588Port Counters
- */
-typedef struct {
- int32_t ieee8021AsPortStatRxSyncCount;
- int32_t ieee8021AsPortStatRxFollowUpCount;
- int32_t ieee8021AsPortStatRxPdelayRequest;
- int32_t ieee8021AsPortStatRxPdelayResponse;
- int32_t ieee8021AsPortStatRxPdelayResponseFollowUp;
- int32_t ieee8021AsPortStatRxAnnounce;
- int32_t ieee8021AsPortStatRxPTPPacketDiscard;
- int32_t ieee8021AsPortStatRxSyncReceiptTimeouts;
- int32_t ieee8021AsPortStatAnnounceReceiptTimeouts;
- int32_t ieee8021AsPortStatPdelayAllowedLostResponsesExceeded;
- int32_t ieee8021AsPortStatTxSyncCount;
- int32_t ieee8021AsPortStatTxFollowUpCount;
- int32_t ieee8021AsPortStatTxPdelayRequest;
- int32_t ieee8021AsPortStatTxPdelayResponse;
- int32_t ieee8021AsPortStatTxPdelayResponseFollowUp;
- int32_t ieee8021AsPortStatTxAnnounce;
-} IEEE1588PortCounters_t;
-
-
-/**
- * @brief Provides the IEEE 1588 port interface
- */
-class IEEE1588Port {
- static LinkLayerAddress other_multicast;
- static LinkLayerAddress pdelay_multicast;
- static LinkLayerAddress test_status_multicast;
-
- PortIdentity port_identity;
- /* directly connected node */
- PortIdentity peer_identity;
-
- OSNetworkInterface *net_iface;
- LinkLayerAddress local_addr;
- int link_delay[4];
-
- /* Port Status */
- unsigned sync_count; // 0 for master, ++ for each sync receive as slave
- // set to 0 when asCapable is false, increment for each pdelay recvd
- unsigned pdelay_count;
- bool linkUp;
-
- /* Port Configuration */
- unsigned char delay_mechanism;
- PortState port_state;
- char log_mean_unicast_sync_interval;
- char log_mean_sync_interval;
- char log_mean_announce_interval;
- char log_min_mean_delay_req_interval;
- char log_min_mean_pdelay_req_interval;
- bool burst_enabled;
- static const int64_t ONE_WAY_DELAY_DEFAULT = 3600000000000;
- static const int64_t INVALID_LINKDELAY = 3600000000000;
- static const int64_t NEIGHBOR_PROP_DELAY_THRESH = 800;
- static const unsigned int DEFAULT_SYNC_RECEIPT_THRESH = 5;
- static const unsigned int DUPLICATE_RESP_THRESH = 3;
-
- unsigned int duplicate_resp_counter;
- uint16_t last_invalid_seqid;
-
- /* Signed value allows this to be negative result because of inaccurate
- timestamp */
- int64_t one_way_delay;
- int64_t neighbor_prop_delay_thresh;
-
- /*Sync threshold*/
- unsigned int sync_receipt_thresh;
- unsigned int wrongSeqIDCounter;
-
- /* Implementation Specific data/methods */
- IEEE1588Clock *clock;
-
- bool _syntonize;
-
- bool asCapable;
-
- /* Automotive Profile : Static variables */
- // port_state : already defined as port_state
- bool isGM;
- bool testMode;
- // asCapable : already defined as asCapable
- char initialLogPdelayReqInterval;
- char initialLogSyncInterval;
- char operLogPdelayReqInterval;
- char operLogSyncInterval;
- bool automotive_profile;
-
- // Test Status variables
- uint32_t linkUpCount;
- uint32_t linkDownCount;
- StationState_t stationState;
-
-
- /* Automotive Profile : Persistant variables */
- // neighborPropDelay : defined as one_way_delay ??
- // rateRatio : Optional and didn't fine this variable. Will proceed without writing it.
- // neighborRateRatio : defined as _peer_rate_offset ??
-
- // Automotive Profile AVB SYNC state indicator. > 0 will inditate valid AVB SYNC state
- uint32_t avbSyncState;
-
- int32_t *rate_offset_array;
- uint32_t rate_offset_array_size;
- uint32_t rate_offset_count;
- uint32_t rate_offset_index;
-
- FrequencyRatio _peer_rate_offset;
- Timestamp _peer_offset_ts_theirs;
- Timestamp _peer_offset_ts_mine;
- bool _peer_offset_init;
-
- int32_t _initial_clock_offset;
- int32_t _current_clock_offset;
-
- PTPMessageAnnounce *qualified_announce;
-
- uint16_t announce_sequence_id;
- uint16_t signal_sequence_id;
- uint16_t sync_sequence_id;
-
- uint16_t pdelay_sequence_id;
- PTPMessagePathDelayReq *last_pdelay_req;
- PTPMessagePathDelayResp *last_pdelay_resp;
- PTPMessagePathDelayRespFollowUp *last_pdelay_resp_fwup;
-
- /* Network socket description
- physical interface number that object represents */
- uint16_t ifindex;
-
- IdentityMap_t identity_map;
-
- PTPMessageSync *last_sync;
-
- OSThread *listening_thread;
-
- OSThread *link_thread;
-
- OSCondition *port_ready_condition;
-
- OSLock *pdelay_rx_lock;
- OSLock *port_tx_lock;
-
- OSLock *syncReceiptTimerLock;
- OSLock *syncIntervalTimerLock;
- OSLock *announceIntervalTimerLock;
- OSLock *pDelayIntervalTimerLock;
-
- OSThreadFactory *thread_factory;
- OSTimerFactory *timer_factory;
-
- HWTimestamper *_hw_timestamper;
-
- net_result port_send
- (uint16_t etherType, uint8_t * buf, int size, MulticastType mcast_type,
- PortIdentity * destIdentity, bool timestamp);
-
- InterfaceLabel *net_label;
-
- OSLockFactory *lock_factory;
- OSConditionFactory *condition_factory;
-
- bool pdelay_started;
- bool pdelay_halted;
- bool sync_rate_interval_timer_started;
-
- uint16_t lastGmTimeBaseIndicator;
-
- IEEE1588PortCounters_t counters;
-
- public:
- bool forceSlave; //!< Forces port to be slave. Added for testing.
-
- /**
- * @brief Serializes (i.e. copy over buf pointer) the information from
- * the variables (in that order):
- * - asCapable;
- * - Port Sate;
- * - Link Delay;
- * - Neighbor Rate Ratio
- * @param buf [out] Buffer where to put the results.
- * @param count [inout] Length of buffer. It contains maximum length to be written
- * when the function is called, and the value is decremented by the same amount the
- * buf size increases.
- * @return TRUE if it has successfully written to buf all the values or if buf is NULL.
- * FALSE if count should be updated with the right size.
- */
- bool serializeState( void *buf, long *count );
-
- /**
- * @brief Restores the serialized state from the buffer. Copies the information from buffer
- * to the variables (in that order):
- * - asCapable;
- * - Port State;
- * - Link Delay;
- * - Neighbor Rate Ratio
- * @param buf Buffer containing the serialized state.
- * @param count Buffer lenght. It is decremented by the same size of the variables that are
- * being copied.
- * @return TRUE if everything was copied successfully, FALSE otherwise.
- */
- bool restoreSerializedState( void *buf, long *count );
-
- /**
- * @brief Switches port to a gPTP master
- * @param annc If TRUE, starts announce event timer.
- * @return void
- */
- void becomeMaster( bool annc );
-
- /**
- * @brief Switches port to a gPTP slave.
- * @param restart_syntonization if TRUE, restarts the syntonization
- * @return void
- */
- void becomeSlave( bool restart_syntonization );
-
- /**
- * @brief Starts pDelay event timer.
- * @return void
- */
- void startPDelay();
-
- /**
- * @brief Stops PDelay event timer
- * @return void
- */
- void stopPDelay();
-
- /**
- * @brief Enable/Disable PDelay Request messages
- * @param hlt True to HALT (stop sending), False to resume (start sending).
- */
- void haltPdelay(bool hlt)
- {
- pdelay_halted = hlt;
- }
-
- /**
- * @brief Get the status of pdelayHalted condition.
- * @return True PdelayRequest halted. False when PDelay Request is running
- */
- bool pdelayHalted(void)
- {
- return pdelay_halted;
- }
-
- /**
- * @brief Starts Sync Rate Interval event timer. Used for the
- * Automotive Profile.
- * @return void
- */
- void startSyncRateIntervalTimer();
-
- /**
- * @brief Starts announce event timer
- * @return void
- */
- void startAnnounce();
-
- /**
- * @brief Starts pDelay event timer if not yet started.
- * @return void
- */
- void syncDone() {
- GPTP_LOG_VERBOSE("Sync complete");
-
- if (automotive_profile && port_state == PTP_SLAVE) {
- if (avbSyncState > 0) {
- avbSyncState--;
- if (avbSyncState == 0) {
- setStationState(STATION_STATE_AVB_SYNC);
- if (testMode) {
- APMessageTestStatus *testStatusMsg = new APMessageTestStatus(this);
- if (testStatusMsg) {
- testStatusMsg->sendPort(this);
- delete testStatusMsg;
- }
- }
- }
- }
- }
-
- if (automotive_profile) {
- if (!sync_rate_interval_timer_started) {
- if (log_mean_sync_interval != operLogSyncInterval) {
- startSyncRateIntervalTimer();
- }
- }
- }
-
- if( !pdelay_started ) {
- startPDelay();
- }
- }
-
- /**
- * @brief Gets a pointer to timer_factory object
- * @return timer_factory pointer
- */
- OSTimerFactory *getTimerFactory() {
- return timer_factory;
- }
-
- /**
- * @brief Restart PDelay
- * @return void
- */
- void restartPDelay() {
- _peer_offset_init = false;
- }
-
- /**
- * @brief Sets asCapable flag
- * @param ascap flag to be set. If FALSE, marks peer_offset_init as false.
- * @return void
- */
- void setAsCapable(bool ascap) {
- if (ascap != asCapable) {
- GPTP_LOG_STATUS("AsCapable: %s",
- ascap == true ? "Enabled" : "Disabled");
- }
- if(!ascap){
- _peer_offset_init = false;
- }
- asCapable = ascap;
- }
-
- /**
- * @brief Gets the asCapable flag
- * @return asCapable flag.
- */
- bool getAsCapable() { return( asCapable ); }
-
- /**
- * @brief Gets the AVnu automotive profile flag
- * @return automotive_profile flag
- */
- bool getAutomotiveProfile() { return( automotive_profile ); }
-
- /**
- * @brief Destroys a IEEE1588Port
- */
- ~IEEE1588Port();
-
- /**
- * @brief Creates the IEEE1588Port interface. Will be
- * deprecated when the Windows platform suports
- * Automotive profile.
- * @param clock IEEE1588Clock instance
- * @param index Interface index
- * @param forceSlave Forces port to be slave
- * @param timestamper Hardware timestamper instance
- * @param offset Initial clock offset
- * @param net_label Network label
- * @param condition_factory OSConditionFactory instance
- * @param thread_factory OSThreadFactory instance
- * @param timer_factory OSTimerFactory instance
- * @param lock_factory OSLockFactory instance
- */
- IEEE1588Port
- (IEEE1588Clock * clock, uint16_t index,
- bool forceSlave,
- HWTimestamper * timestamper,
- int32_t offset, InterfaceLabel * net_label,
- OSConditionFactory * condition_factory,
- OSThreadFactory * thread_factory,
- OSTimerFactory * timer_factory,
- OSLockFactory * lock_factory);
-
- /**
- * @brief Creates the IEEE1588Port interface.
- * @param init IEEE1588PortInit initialization parameters
- */
- IEEE1588Port(IEEE1588PortInit_t *portInit);
-
- /**
- * @brief Initializes the port. Creates network interface, initializes
- * hardware timestamper and create OS locks conditions
- * @return FALSE if error during building the interface. TRUE if success
- */
- bool init_port(int delay[4]);
-
- /**
- * @brief Currently doesnt do anything. Just returns.
- * @return void
- */
- void recoverPort(void);
-
- /**
- * @brief Watch for link up and down events.
- * @return Its an infinite loop. Returns NULL in case of error.
- */
- void *watchNetLink(void);
-
- /**
- * @brief Receives messages from the network interface
- * @return Its an infinite loop. Returns NULL in case of error.
- */
- void *openPort(IEEE1588Port *port);
-
- /**
- * @brief Get the payload offset inside a packet
- * @return 0
- */
- unsigned getPayloadOffset();
-
- /**
- * @brief Sends and event to a IEEE1588 port. It includes timestamp
- * @param buf [in] Pointer to the data buffer
- * @param len Size of the message
- * @param mcast_type Enumeration MulticastType (pdlay, none or other). Depracated.
- * @param destIdentity Destination port identity
- * @return void
- */
- void sendEventPort
- (uint16_t etherType, uint8_t * buf, int len, MulticastType mcast_type,
- PortIdentity * destIdentity);
-
- /**
- * @brief Sends a general message to a port. No timestamps
- * @param buf [in] Pointer to the data buffer
- * @param len Size of the message
- * @param mcast_type Enumeration MulticastType (pdelay, none or other). Depracated.
- * @param destIdentity Destination port identity
- * @return void
- */
- void sendGeneralPort
- (uint16_t etherType, uint8_t * buf, int len, MulticastType mcast_type,
- PortIdentity * destIdentity);
-
- /**
- * @brief Process all events for a IEEE1588Port
- * @param e Event to be processed
- * @return void
- */
- void processEvent(Event e);
-
- /**
- * @brief Gets the "best" announce
- * @return Pointer to PTPMessageAnnounce
- */
- PTPMessageAnnounce *calculateERBest(void);
-
- /**
- * @brief Adds a foreign master.
- * @param msg [in] PTP announce message
- * @return void
- * @todo Currently not implemented
- */
- void addForeignMaster(PTPMessageAnnounce * msg);
-
- /**
- * @brief Remove a foreign master.
- * @param msg [in] PTP announce message
- * @return void
- * @todo Currently not implemented
- */
- void removeForeignMaster(PTPMessageAnnounce * msg);
-
- /**
- * @brief Remove all foreign masters.
- * @return void
- * @todo Currently not implemented
- */
- void removeForeignMasterAll(void);
-
-
- /**
- * @brief Adds a new qualified announce the port. IEEE 802.1AS Clause 10.3.10.2
- * @param msg PTP announce message
- * @return void
- */
- void addQualifiedAnnounce(PTPMessageAnnounce * msg) {
- if( qualified_announce != NULL ) delete qualified_announce;
- qualified_announce = msg;
- }
- /**
- * @brief Gets the local_addr
- * @return LinkLayerAddress
- */
- LinkLayerAddress *getLocalAddr(void) {
- return &local_addr;
- }
-
- /**
- * @brief Gets the sync interval value
- * @return Sync Interval
- */
- char getSyncInterval(void) {
- return log_mean_sync_interval;
- }
-
- /**
- * @brief Sets the sync interval value
- * @param val time interval
- * @return none
- */
- void setSyncInterval(char val) {
- log_mean_sync_interval = val;;
- }
-
- /**
- * @brief Sets the sync interval back to initial value
- * @return none
- */
- void setInitSyncInterval(void) {
- log_mean_sync_interval = initialLogSyncInterval;;
- }
-
- /**
- * @brief Start sync receipt timer
- * @param waitTime time interval
- * @return none
- */
- void startSyncReceiptTimer(long long unsigned int waitTime);
-
- /**
- * @brief Stop sync receipt timer
- * @return none
- */
- void stopSyncReceiptTimer(void);
-
- /**
- * @brief Start sync interval timer
- * @param waitTime time interval in nanoseconds
- * @return none
- */
- void startSyncIntervalTimer(long long unsigned int waitTime);
-
- /**
- * @brief Gets the announce interval
- * @return Announce interval
- */
- char getAnnounceInterval(void) {
- return log_mean_announce_interval;
- }
-
- /**
- * @brief Sets the announce interval
- * @param val time interval
- * @return none
- */
- void setAnnounceInterval(char val) {
- log_mean_announce_interval = val;
- }
-
- /**
- * @brief Start announce interval timer
- * @param waitTime time interval
- * @return none
- */
- void startAnnounceIntervalTimer(long long unsigned int waitTime);
-
- /**
- * @brief Gets the pDelay minimum interval
- * @return PDelay interval
- */
- char getPDelayInterval(void) {
- return log_min_mean_pdelay_req_interval;
- }
-
- /**
- * @brief Sets the pDelay minimum interval
- * @param val time interval
- * @return none
- */
- void setPDelayInterval(char val) {
- log_min_mean_pdelay_req_interval = val;
- }
-
- /**
- * @brief Sets the pDelay minimum interval back to initial
- * value
- * @return none */
- void setInitPDelayInterval(void) {
- log_min_mean_pdelay_req_interval = initialLogPdelayReqInterval;
- }
-
- /**
- * @brief Start pDelay interval timer
- * @param waitTime time interval
- * @return none
- */
- void startPDelayIntervalTimer(long long unsigned int waitTime);
-
- /**
- * @brief Gets the portState information
- * @return PortState
- */
- PortState getPortState(void) {
- return port_state;
- }
-
- /**
- * @brief Sets the PortState
- * @param state value to be set
- * @return void
- */
- void setPortState( PortState state ) {
- port_state = state;
- }
-
- /**
- * @brief Gets port identity
- * @param identity [out] Reference to PortIdentity
- * @return void
- */
- void getPortIdentity(PortIdentity & identity) {
- identity = this->port_identity;
- }
-
- /**
- * @brief Gets the burst_enabled flag
- * @return burst_enabled
- */
- bool burstEnabled(void) {
- return burst_enabled;
- }
-
- /**
- * @brief Increments announce sequence id and returns
- * @return Next announce sequence id.
- */
- uint16_t getNextAnnounceSequenceId(void) {
- return announce_sequence_id++;
- }
-
- /**
- * @brief Increments signal sequence id and returns
- * @return Next signal sequence id.
- */
- uint16_t getNextSignalSequenceId(void) {
- return signal_sequence_id++;
- }
-
- /**
- * @brief Increments sync sequence ID and returns
- * @return Next synce sequence id.
- */
- uint16_t getNextSyncSequenceId(void) {
- return sync_sequence_id++;
- }
-
- /**
- * @brief Increments PDelay sequence ID and returns.
- * @return Next PDelay sequence id.
- */
- uint16_t getNextPDelaySequenceId(void) {
- return pdelay_sequence_id++;
- }
-
- /**
- * @brief Gets last sync sequence number from parent
- * @return Parent last sync sequence number
- * @todo Not currently implemented.
- */
- uint16_t getParentLastSyncSequenceNumber(void);
-
- /**
- * @brief Sets last sync sequence number from parent
- * @param num Sequence number
- * @return void
- * @todo Currently not implemented.
- */
- void setParentLastSyncSequenceNumber(uint16_t num);
-
- /**
- * @brief Gets a pointer to IEEE1588Clock
- * @return Pointer to clock
- */
- IEEE1588Clock *getClock(void);
-
- /**
- * @brief Sets last sync ptp message
- * @param msg [in] PTP sync message
- * @return void
- */
- void setLastSync(PTPMessageSync * msg) {
- last_sync = msg;
- }
-
- /**
- * @brief Gets last sync message
- * @return PTPMessageSync last sync
- */
- PTPMessageSync *getLastSync(void) {
- return last_sync;
- }
-
- /**
- * @brief Locks PDelay RX
- * @return TRUE if acquired the lock. FALSE otherwise
- */
- bool getPDelayRxLock() {
- return pdelay_rx_lock->lock() == oslock_ok ? true : false;
- }
-
- /**
- * @brief Do a trylock on the PDelay RX
- * @return TRUE if acquired the lock. FALSE otherwise.
- */
- bool tryPDelayRxLock() {
- return pdelay_rx_lock->trylock() == oslock_ok ? true : false;
- }
-
- /**
- * @brief Unlocks PDelay RX.
- * @return TRUE if success. FALSE otherwise
- */
- bool putPDelayRxLock() {
- return pdelay_rx_lock->unlock() == oslock_ok ? true : false;
- }
-
- /**
- * @brief Locks the TX port
- * @return TRUE if success. FALSE otherwise.
- */
- bool getTxLock() {
- return port_tx_lock->lock() == oslock_ok ? true : false;
- }
-
- /**
- * @brief Unlocks the port TX.
- * @return TRUE if success. FALSE otherwise.
- */
- bool putTxLock() {
- return port_tx_lock->unlock() == oslock_ok ? true : false;
- }
-
- /**
- * @brief Gets the hardware timestamper version
- * @return HW timestamper version
- */
- int getTimestampVersion() {
- return _hw_timestamper->getVersion();
- }
-
- /**
- * @brief Sets the last_pdelay_req message
- * @param msg [in] PTPMessagePathDelayReq message to set
- * @return void
- */
- void setLastPDelayReq(PTPMessagePathDelayReq * msg) {
- last_pdelay_req = msg;
- }
-
- /**
- * @brief Gets the last PTPMessagePathDelayReq message
- * @return Last pdelay request
- */
- PTPMessagePathDelayReq *getLastPDelayReq(void) {
- return last_pdelay_req;
- }
-
- /**
- * @brief Sets the last PTPMessagePathDelayResp message
- * @param msg [in] Last pdelay response
- * @return void
- */
- void setLastPDelayResp(PTPMessagePathDelayResp * msg) {
- last_pdelay_resp = msg;
- }
-
- /**
- * @brief Gets the last PTPMessagePathDelayResp message
- * @return Last pdelay response
- */
- PTPMessagePathDelayResp *getLastPDelayResp(void) {
- return last_pdelay_resp;
- }
-
- /**
- * @brief Sets the last PTPMessagePathDelayRespFollowUp message
- * @param msg [in] last pdelay response follow up
- * @return void
- */
- void setLastPDelayRespFollowUp(PTPMessagePathDelayRespFollowUp * msg) {
- last_pdelay_resp_fwup = msg;
- }
-
- /**
- * @brief Gets the last PTPMessagePathDelayRespFollowUp message
- * @return last pdelay response follow up
- */
- PTPMessagePathDelayRespFollowUp *getLastPDelayRespFollowUp(void) {
- return last_pdelay_resp_fwup;
- }
-
- /**
- * @brief Gets the Peer rate offset. Used to calculate neighbor rate ratio.
- * @return FrequencyRatio peer rate offset
- */
- FrequencyRatio getPeerRateOffset(void) {
- return _peer_rate_offset;
- }
-
- /**
- * @brief Sets the peer rate offset. Used to calculate neighbor rate ratio.
- * @param offset Offset to be set
- * @return void
- */
- void setPeerRateOffset( FrequencyRatio offset ) {
- _peer_rate_offset = offset;
- }
-
- /**
- * @brief Sets peer offset timestamps
- * @param mine Local timestamps
- * @param theirs Remote timestamps
- * @return void
- */
- void setPeerOffset(Timestamp mine, Timestamp theirs) {
- _peer_offset_ts_mine = mine;
- _peer_offset_ts_theirs = theirs;
- _peer_offset_init = true;
- }
-
- /**
- * @brief Gets peer offset timestamps
- * @param mine [out] Reference to local timestamps
- * @param theirs [out] Reference to remote timestamps
- * @return TRUE if peer offset has already been initialized. FALSE otherwise.
- */
- bool getPeerOffset(Timestamp & mine, Timestamp & theirs) {
- mine = _peer_offset_ts_mine;
- theirs = _peer_offset_ts_theirs;
- return _peer_offset_init;
- }
-
- /**
- * @brief Adjusts the clock frequency.
- * @param freq_offset Frequency offset
- * @return TRUE if adjusted. FALSE otherwise.
- */
- bool _adjustClockRate( FrequencyRatio freq_offset ) {
- if( _hw_timestamper ) {
- return _hw_timestamper->HWTimestamper_adjclockrate((float) freq_offset );
- }
- return false;
- }
-
- /**
- * @brief Adjusts the clock frequency.
- * @param freq_offset Frequency offset
- * @return TRUE if adjusted. FALSE otherwise.
- */
- bool adjustClockRate( FrequencyRatio freq_offset ) {
- return _adjustClockRate( freq_offset );
- }
-
- /**
- * @brief Gets extended error message from hardware timestamper
- * @param msg [out] Extended error message
- * @return void
- */
- void getExtendedError(char *msg) {
- if (_hw_timestamper) {
- _hw_timestamper->HWTimestamper_get_extderror(msg);
- } else {
- *msg = '\0';
- }
- }
-
- /**
- * @brief Initializes the hwtimestamper
- */
- void timestamper_init(void);
-
- /**
- * @brief Resets the hwtimestamper
- */
- void timestamper_reset(void);
-
-
- /**
- * @brief Gets RX timestamp based on port identity
- * @param sourcePortIdentity [in] Source port identity
- * @param sequenceId Sequence ID
- * @param timestamp [out] RX timestamp
- * @param counter_value [out] timestamp count value
- * @param last If true, removes the rx lock.
- * @return GPTP_EC_SUCCESS if no error, GPTP_EC_FAILURE if error and GPTP_EC_EAGAIN to try again.
- */
- int getRxTimestamp
- (PortIdentity * sourcePortIdentity, PTPMessageId messageId,
- Timestamp & timestamp, unsigned &counter_value, bool last);
-
- /**
- * @brief Gets TX timestamp based on port identity
- * @param sourcePortIdentity [in] Source port identity
- * @param sequenceId Sequence ID
- * @param timestamp [out] TX timestamp
- * @param counter_value [out] timestamp count value
- * @param last If true, removes the TX lock
- * @return GPTP_EC_SUCCESS if no error, GPTP_EC_FAILURE if error and GPTP_EC_EAGAIN to try again.
- */
- int getTxTimestamp
- (PortIdentity * sourcePortIdentity, PTPMessageId messageId,
- Timestamp & timestamp, unsigned &counter_value, bool last);
-
- /**
- * @brief Gets TX timestamp based on PTP message
- * @param msg PTPMessageCommon message
- * @param timestamp [out] TX timestamp
- * @param counter_value [out] timestamp count value
- * @param last If true, removes the TX lock
- * @return GPTP_EC_SUCCESS if no error, GPTP_EC_FAILURE if error and GPTP_EC_EAGAIN to try again.
- */
- int getTxTimestamp
- (PTPMessageCommon * msg, Timestamp & timestamp, unsigned &counter_value,
- bool last);
-
- /**
- * @brief Gets RX timestamp based on PTP message
- * @param msg PTPMessageCommon message
- * @param timestamp [out] RX timestamp
- * @param counter_value [out] timestamp count value
- * @param last If true, removes the RX lock
- * @return GPTP_EC_SUCCESS if no error, GPTP_EC_FAILURE if error and GPTP_EC_EAGAIN to try again.
- */
- int getRxTimestamp
- (PTPMessageCommon * msg, Timestamp & timestamp, unsigned &counter_value,
- bool last);
-
- /**
- * @brief Get the cross timestamping information.
- * The gPTP subsystem uses these samples to calculate
- * ratios which can be used to translate or extrapolate
- * one clock into another clock reference. The gPTP service
- * uses these supplied cross timestamps to perform internal
- * rate estimation and conversion functions.
- * @param system_time [out] System time
- * @param device_time [out] Device time
- * @param local_clock [out] Local clock
- * @param nominal_clock_rate [out] Nominal clock rate
- * @return True in case of success. FALSE in case of error
- */
- void getDeviceTime
- (Timestamp & system_time, Timestamp & device_time, uint32_t & local_clock,
- uint32_t & nominal_clock_rate);
-
- /**
- * @brief Gets the link delay information.
- * @return one way delay if delay > 0, or zero otherwise.
- */
- uint64_t getLinkDelay(void) {
- return one_way_delay > 0LL ? one_way_delay : 0LL;
- }
-
- /**
- * @brief Gets the link delay information.
- * @param [in] delay Pointer to the delay information
- * @return True if valid, false if invalid
- */
- bool getLinkDelay(uint64_t *delay) {
- if(delay == NULL) {
- return false;
- }
- *delay = getLinkDelay();
- return *delay < INVALID_LINKDELAY;
- }
-
- /**
- * @brief Sets link delay information.
- * Signed value allows this to be negative result because
- * of inaccurate timestamps.
- * @param delay Link delay
- * @return True if one_way_delay is lower or equal than neighbor propagation delay threshold
- * False otherwise
- */
- bool setLinkDelay(int64_t delay) {
- one_way_delay = delay;
- int64_t abs_delay = (one_way_delay < 0 ? -one_way_delay : one_way_delay);
-
- if (testMode) {
- GPTP_LOG_STATUS("Link delay: %d", delay);
- }
-
- return (abs_delay <= neighbor_prop_delay_thresh);
- }
-
- /**
- * @brief Sets the internal variabl sync_receipt_thresh, which is the
- * flag that monitors the amount of wrong syncs enabled before switching
- * the ptp to master.
- * @param th Threshold to be set
- * @return void
- */
- void setSyncReceiptThresh(unsigned int th)
- {
- sync_receipt_thresh = th;
- }
-
- /**
- * @brief Gets the internal variabl sync_receipt_thresh, which is the
- * flag that monitors the amount of wrong syncs enabled before switching
- * the ptp to master.
- * @return sync_receipt_thresh value
- */
- unsigned int getSyncReceiptThresh(void)
- {
- return sync_receipt_thresh;
- }
-
- /**
- * @brief Sets the wrongSeqIDCounter variable
- * @param cnt Value to be set
- * @return void
- */
- void setWrongSeqIDCounter(unsigned int cnt)
- {
- wrongSeqIDCounter = cnt;
- }
-
- /**
- * @brief Gets the wrongSeqIDCounter value
- * @param [out] cnt Pointer to the counter value. It must be valid
- * @return TRUE if ok and lower than the syncReceiptThreshold value. FALSE otherwise
- */
- bool getWrongSeqIDCounter(unsigned int *cnt)
- {
- if( cnt == NULL )
- {
- return false;
- }
- *cnt = wrongSeqIDCounter;
-
- return( *cnt < getSyncReceiptThresh() );
- }
-
- /**
- * @brief Increments the wrongSeqIDCounter value
- * @param [out] cnt Pointer to the counter value. Must be valid
- * @return TRUE if incremented value is lower than the syncReceiptThreshold. FALSE otherwise.
- */
- bool incWrongSeqIDCounter(unsigned int *cnt)
- {
- if( getAsCapable() )
- {
- wrongSeqIDCounter++;
- }
- bool ret = wrongSeqIDCounter < getSyncReceiptThresh();
-
- if( cnt != NULL)
- {
- *cnt = wrongSeqIDCounter;
- }
-
- return ret;
- }
-
- /**
- * @brief Sets the value of last duplicated SeqID
- * @param seqid Value to set
- * @return void
- */
- void setLastInvalidSeqID(uint16_t seqid)
- {
- last_invalid_seqid = seqid;
- }
-
- /**
- * @brief Get the value of last invalid seqID
- * @return Last invalid seq id
- */
- uint16_t getLastInvalidSeqID(void)
- {
- return last_invalid_seqid;
- }
-
- /**
- * @brief Sets the duplicate pdelay_resp counter.
- * @param cnt Value to be set
- */
- void setDuplicateRespCounter(unsigned int cnt)
- {
- duplicate_resp_counter = cnt;
- }
-
- /**
- * @brief Gets the current value of pdelay_resp duplicate messages counter
- * @return Counter value
- */
- unsigned int getDuplicateRespCounter(void)
- {
- return duplicate_resp_counter;
- }
-
- /**
- * @brief Increment the duplicate PDelayResp message counter
- * @return True if it equals the threshold, False otherwise
- */
- bool incrementDuplicateRespCounter(void)
- {
- return ++duplicate_resp_counter == DUPLICATE_RESP_THRESH;
- }
-
- /**
- * @brief Sets the neighbor propagation delay threshold
- * @param delay Delay in nanoseconds
- * @return void
- */
- void setNeighPropDelayThresh(int64_t delay) {
- neighbor_prop_delay_thresh = delay;
- }
-
- /**
- * @brief Changes the port state
- * @param state Current state
- * @param changed_external_master TRUE if external master has changed, FALSE otherwise
- * @return void
- */
- void recommendState(PortState state, bool changed_external_master);
-
- /**
- * @brief Maps socket addr to the remote link layer address
- * @param destIdentity [in] PortIdentity remote
- * @param remote [in] remote link layer address
- * @return void
- */
- void mapSocketAddr
- (PortIdentity * destIdentity, LinkLayerAddress * remote);
-
- /**
- * @brief Adds New sock addr map
- * @param destIdentity [in] PortIdentity remote
- * @param remote [in] remote link layer address
- * @return void
- */
- void addSockAddrMap
- (PortIdentity * destIdentity, LinkLayerAddress * remote);
-
- /**
- * @brief Sets current pdelay count value.
- * @param cnt [in] pdelay count value
- * @return void
- */
- void setPdelayCount(unsigned int cnt) {
- pdelay_count = cnt;
- }
-
- /**
- * @brief Increments Pdelay count
- * @return void
- */
- void incPdelayCount() {
- ++pdelay_count;
- }
-
- /**
- * @brief Gets current pdelay count value. It is set to zero
- * when asCapable is false.
- * @return pdelay count
- */
- unsigned getPdelayCount() {
- return pdelay_count;
- }
-
- /**
- * @brief Sets current sync count value.
- * @param cnt [in] sync count value
- * @return void
- */
- void setSyncCount(unsigned int cnt) {
- sync_count = cnt;
- }
-
- /**
- * @brief Increments sync count
- * @return void
- */
- void incSyncCount() {
- ++sync_count;
- }
-
- /**
- * @brief Gets current sync count value. It is set to zero
- * when master and incremented at each sync received for slave.
- * @return sync count
- */
- unsigned getSyncCount() {
- return sync_count;
- }
-
- /**
- * @brief Gets link up count
- * @return Link up count
- */
- uint32_t getLinkUpCount() {
- return linkUpCount;
- }
-
- /**
- * @brief Gets link down count
- * @return Link down count
- */
- uint32_t getLinkDownCount() {
- return linkDownCount;
- }
-
- /**
- * @brief Sets the Station State for the Test Status message
- * @param StationState_t [in] The station state
- * @return none
- */
- void setStationState(StationState_t _stationState) {
- stationState = _stationState;
- if (stationState == STATION_STATE_ETHERNET_READY) {
- GPTP_LOG_STATUS("AVnu AP Status : STATION_STATE_ETHERNET_READY");
- }
- else if (stationState == STATION_STATE_AVB_SYNC) {
- GPTP_LOG_STATUS("AVnu AP Status : STATION_STATE_AVB_SYNC");
- }
- else if (stationState == STATION_STATE_AVB_MEDIA_READY) {
- GPTP_LOG_STATUS("AVnu AP Status : STATION_STATE_AVB_MEDIA_READY");
- }
- }
-
- /**
- * @brief Gets the Station State for the Test Status
- * message
- * @return station state
- */
- StationState_t getStationState() {
- return stationState;
- }
-
-
- /**
- * @brief Gets the lastGmTimeBaseIndicator
- * @return uint16 of the lastGmTimeBaseIndicator
- */
- uint16_t getLastGmTimeBaseIndicator(void) {
- return lastGmTimeBaseIndicator;
- }
-
- /**
- * @brief Sets the lastGmTimeBaseIndicator
- * @param gmTimeBaseIndicator from last Follow up message
- * @return void
- */
- void setLastGmTimeBaseIndicator(uint16_t gmTimeBaseIndicator) {
- lastGmTimeBaseIndicator = gmTimeBaseIndicator;
- }
-
- /**
- * @brief Gets the testMode
- * @return bool of the test mode value
- */
- bool getTestMode(void) {
- return testMode;
- }
-
- /**
- * @brief Sets the linkUp status
- * @param bool of the linkUp status
- * @return void
- */
- void setLinkUpState(bool state) {
- linkUp = state;
- }
-
- /**
- * @brief Gets the linkUp status
- * @return bool of the linkUp status
- */
- bool getLinkUpState(void) {
- return linkUp;
- }
-
- /**
- * @brief Increment IEEE Port counter:
- * ieee8021AsPortStatRxSyncCount
- * @return void
- */
- void incCounter_ieee8021AsPortStatRxSyncCount(void) {
- counters.ieee8021AsPortStatRxSyncCount++;
- }
-
- /**
- * @brief Increment IEEE Port counter:
- * ieee8021AsPortStatRxFollowUpCount
- * @return void
- */
- void incCounter_ieee8021AsPortStatRxFollowUpCount(void) {
- counters.ieee8021AsPortStatRxFollowUpCount++;
- }
-
- /**
- * @brief Increment IEEE Port counter:
- * ieee8021AsPortStatRxPdelayRequest
- * @return void
- */
- void incCounter_ieee8021AsPortStatRxPdelayRequest(void) {
- counters.ieee8021AsPortStatRxPdelayRequest++;
- }
-
- /**
- * @brief Increment IEEE Port counter:
- * ieee8021AsPortStatRxPdelayResponse
- * @return void
- */
- void incCounter_ieee8021AsPortStatRxPdelayResponse(void) {
- counters.ieee8021AsPortStatRxPdelayResponse++;
- }
-
- /**
- * @brief Increment IEEE Port counter:
- * ieee8021AsPortStatRxPdelayResponseFollowUp
- * @return void
- */
- void incCounter_ieee8021AsPortStatRxPdelayResponseFollowUp(void) {
- counters.ieee8021AsPortStatRxPdelayResponseFollowUp++;
- }
-
- /**
- * @brief Increment IEEE Port counter:
- * ieee8021AsPortStatRxAnnounce
- * @return void
- */
- void incCounter_ieee8021AsPortStatRxAnnounce(void) {
- counters.ieee8021AsPortStatRxAnnounce++;
- }
-
- /**
- * @brief Increment IEEE Port counter:
- * ieee8021AsPortStatRxPTPPacketDiscard
- * @return void
- */
- void incCounter_ieee8021AsPortStatRxPTPPacketDiscard(void) {
- counters.ieee8021AsPortStatRxPTPPacketDiscard++;
- }
-
- /**
- * @brief Increment IEEE Port counter:
- * ieee8021AsPortStatRxSyncReceiptTimeouts
- * @return void
- */
- void incCounter_ieee8021AsPortStatRxSyncReceiptTimeouts(void) {
- counters.ieee8021AsPortStatRxSyncReceiptTimeouts++;
- }
-
- /**
- * @brief Increment IEEE Port counter:
- * ieee8021AsPortStatAnnounceReceiptTimeouts
- * @return void
- */
- void incCounter_ieee8021AsPortStatAnnounceReceiptTimeouts(void) {
- counters.ieee8021AsPortStatAnnounceReceiptTimeouts++;
- }
-
-
- /**
- * @brief Increment IEEE Port counter:
- * ieee8021AsPortStatPdelayAllowedLostResponsesExceeded
- * @return void
- */
- // TODO: Not called
- void incCounter_ieee8021AsPortStatPdelayAllowedLostResponsesExceeded(void) {
- counters.ieee8021AsPortStatPdelayAllowedLostResponsesExceeded++;
- }
-
- /**
- * @brief Increment IEEE Port counter:
- * ieee8021AsPortStatTxSyncCount
- * @return void
- */
- void incCounter_ieee8021AsPortStatTxSyncCount(void) {
- counters.ieee8021AsPortStatTxSyncCount++;
- }
-
- /**
- * @brief Increment IEEE Port counter:
- * ieee8021AsPortStatTxFollowUpCount
- * @return void
- */
- void incCounter_ieee8021AsPortStatTxFollowUpCount(void) {
- counters.ieee8021AsPortStatTxFollowUpCount++;
- }
-
- /**
- * @brief Increment IEEE Port counter:
- * ieee8021AsPortStatTxPdelayRequest
- * @return void
- */
- void incCounter_ieee8021AsPortStatTxPdelayRequest(void) {
- counters.ieee8021AsPortStatTxPdelayRequest++;
- }
-
- /**
- * @brief Increment IEEE Port counter:
- * ieee8021AsPortStatTxPdelayResponse
- * @return void
- */
- void incCounter_ieee8021AsPortStatTxPdelayResponse(void) {
- counters.ieee8021AsPortStatTxPdelayResponse++;
- }
-
- /**
- * @brief Increment IEEE Port counter:
- * ieee8021AsPortStatTxPdelayResponseFollowUp
- * @return void
- */
- void incCounter_ieee8021AsPortStatTxPdelayResponseFollowUp(void) {
- counters.ieee8021AsPortStatTxPdelayResponseFollowUp++;
- }
-
- /**
- * @brief Increment IEEE Port counter:
- * ieee8021AsPortStatTxAnnounce
- * @return void
- */
- void incCounter_ieee8021AsPortStatTxAnnounce(void) {
- counters.ieee8021AsPortStatTxAnnounce++;
- }
-
- /**
- * @brief Logs port counters
- * @return void
- */
- void logIEEEPortCounters(void) {
- GPTP_LOG_STATUS("IEEE Port Counter ieee8021AsPortStatRxSyncCount : %u", counters.ieee8021AsPortStatRxSyncCount);
- GPTP_LOG_STATUS("IEEE Port Counter ieee8021AsPortStatRxFollowUpCount : %u", counters.ieee8021AsPortStatRxFollowUpCount);
- GPTP_LOG_STATUS("IEEE Port Counter ieee8021AsPortStatRxPdelayRequest : %u", counters.ieee8021AsPortStatRxPdelayRequest);
- GPTP_LOG_STATUS("IEEE Port Counter ieee8021AsPortStatRxPdelayResponse : %u", counters.ieee8021AsPortStatRxPdelayResponse);
- GPTP_LOG_STATUS("IEEE Port Counter ieee8021AsPortStatRxPdelayResponseFollowUp : %u", counters.ieee8021AsPortStatRxPdelayResponseFollowUp);
- GPTP_LOG_STATUS("IEEE Port Counter ieee8021AsPortStatRxAnnounce : %u", counters.ieee8021AsPortStatRxAnnounce);
- GPTP_LOG_STATUS("IEEE Port Counter ieee8021AsPortStatRxPTPPacketDiscard : %u", counters.ieee8021AsPortStatRxPTPPacketDiscard);
- GPTP_LOG_STATUS("IEEE Port Counter ieee8021AsPortStatRxSyncReceiptTimeouts : %u", counters.ieee8021AsPortStatRxSyncReceiptTimeouts);
- GPTP_LOG_STATUS("IEEE Port Counter ieee8021AsPortStatAnnounceReceiptTimeouts : %u", counters.ieee8021AsPortStatAnnounceReceiptTimeouts);
- GPTP_LOG_STATUS("IEEE Port Counter ieee8021AsPortStatPdelayAllowedLostResponsesExceeded : %u", counters.ieee8021AsPortStatPdelayAllowedLostResponsesExceeded);
- GPTP_LOG_STATUS("IEEE Port Counter ieee8021AsPortStatTxSyncCount : %u", counters.ieee8021AsPortStatTxSyncCount);
- GPTP_LOG_STATUS("IEEE Port Counter ieee8021AsPortStatTxFollowUpCount : %u", counters.ieee8021AsPortStatTxFollowUpCount);
- GPTP_LOG_STATUS("IEEE Port Counter ieee8021AsPortStatTxPdelayRequest : %u", counters.ieee8021AsPortStatTxPdelayRequest);
- GPTP_LOG_STATUS("IEEE Port Counter ieee8021AsPortStatTxPdelayResponse : %u", counters.ieee8021AsPortStatTxPdelayResponse);
- GPTP_LOG_STATUS("IEEE Port Counter ieee8021AsPortStatTxPdelayResponseFollowUp : %u", counters.ieee8021AsPortStatTxPdelayResponseFollowUp);
- GPTP_LOG_STATUS("IEEE Port Counter ieee8021AsPortStatTxAnnounce : %u", counters.ieee8021AsPortStatTxAnnounce);
- }
-};
-
-#endif
diff --git a/daemons/gptp/common/common_port.cpp b/daemons/gptp/common/common_port.cpp
new file mode 100644
index 00000000..a5116083
--- /dev/null
+++ b/daemons/gptp/common/common_port.cpp
@@ -0,0 +1,709 @@
+/******************************************************************************
+
+ Copyright (c) 2009-2012, Intel Corporation
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+******************************************************************************/
+
+
+#include <common_port.hpp>
+#include <avbts_clock.hpp>
+
+CommonPort::CommonPort( PortInit_t *portInit ) :
+ thread_factory( portInit->thread_factory ),
+ timer_factory( portInit->timer_factory ),
+ lock_factory( portInit->lock_factory ),
+ condition_factory( portInit->condition_factory ),
+ _hw_timestamper( portInit->timestamper ),
+ clock( portInit->clock ),
+ isGM( portInit->isGM )
+{
+ one_way_delay = ONE_WAY_DELAY_DEFAULT;
+ neighbor_prop_delay_thresh = NEIGHBOR_PROP_DELAY_THRESH;
+ net_label = portInit->net_label;
+ link_thread = thread_factory->createThread();
+ listening_thread = thread_factory->createThread();
+ sync_receipt_thresh = DEFAULT_SYNC_RECEIPT_THRESH;
+ wrongSeqIDCounter = 0;
+ memset(phy_delay, 0, sizeof(phy_delay));
+ _peer_rate_offset = 1.0;
+ _peer_offset_init = false;
+ ifindex = portInit->index;
+ testMode = false;
+ port_state = PTP_INITIALIZING;
+ clock->registerPort(this, ifindex);
+ qualified_announce = NULL;
+ announce_sequence_id = 0;
+ signal_sequence_id = 0;
+ sync_sequence_id = 0;
+ initialLogSyncInterval = portInit->initialLogSyncInterval;
+ log_mean_announce_interval = 0;
+ pdelay_count = 0;
+ asCapable = false;
+}
+
+CommonPort::~CommonPort()
+{
+ delete qualified_announce;
+}
+
+bool CommonPort::init_port( int phy_delay[4] )
+{
+ log_mean_sync_interval = initialLogSyncInterval;
+
+ if (!OSNetworkInterfaceFactory::buildInterface
+ ( &net_iface, factory_name_t("default"), net_label,
+ _hw_timestamper))
+ return false;
+
+ this->net_iface->getLinkLayerAddress(&local_addr);
+ clock->setClockIdentity(&local_addr);
+ memcpy(this->phy_delay, phy_delay, sizeof(this->phy_delay));
+
+ this->timestamper_init();
+
+ port_identity.setClockIdentity(clock->getClockIdentity());
+ port_identity.setPortNumber(&ifindex);
+
+ syncReceiptTimerLock = lock_factory->createLock(oslock_recursive);
+ syncIntervalTimerLock = lock_factory->createLock(oslock_recursive);
+ announceIntervalTimerLock = lock_factory->createLock(oslock_recursive);
+
+ return _init_port();
+}
+
+void CommonPort::timestamper_init( void )
+{
+ if( _hw_timestamper != NULL )
+ {
+ _hw_timestamper->init_phy_delay(this->phy_delay);
+ if( !_hw_timestamper->HWTimestamper_init
+ ( net_label, net_iface ))
+ {
+ GPTP_LOG_ERROR
+ ( "Failed to initialize hardware timestamper, "
+ "falling back to software timestamping" );
+ return;
+ }
+ }
+}
+
+void CommonPort::timestamper_reset( void )
+{
+ if( _hw_timestamper != NULL )
+ {
+ _hw_timestamper->init_phy_delay(this->phy_delay);
+ _hw_timestamper->HWTimestamper_reset();
+ }
+}
+
+PTPMessageAnnounce *CommonPort::calculateERBest( void )
+{
+ return qualified_announce;
+}
+
+void CommonPort::recommendState
+( PortState state, bool changed_external_master )
+{
+ bool reset_sync = false;
+ switch (state) {
+ case PTP_MASTER:
+ if ( getPortState() != PTP_MASTER )
+ {
+ setPortState( PTP_MASTER );
+ // Start announce receipt timeout timer
+ // Start sync receipt timeout timer
+ becomeMaster( true );
+ reset_sync = true;
+ }
+ break;
+ case PTP_SLAVE:
+ if ( getPortState() != PTP_SLAVE )
+ {
+ becomeSlave( true );
+ reset_sync = true;
+ } else {
+ if( changed_external_master ) {
+ GPTP_LOG_STATUS("Changed master!" );
+ clock->newSyntonizationSetPoint();
+ clock->updateFUPInfo();
+ reset_sync = true;
+ }
+ }
+ break;
+ default:
+ GPTP_LOG_ERROR
+ ("Invalid state change requested by call to "
+ "1588Port::recommendState()");
+ break;
+ }
+ if( reset_sync ) sync_count = 0;
+ return;
+}
+
+bool CommonPort::serializeState( void *buf, off_t *count )
+{
+ bool ret = true;
+
+ if( buf == NULL ) {
+ *count = sizeof(port_state)+sizeof(_peer_rate_offset)+
+ sizeof(asCapable)+sizeof(one_way_delay);
+ return true;
+ }
+
+ if( port_state != PTP_MASTER && port_state != PTP_SLAVE ) {
+ *count = 0;
+ ret = false;
+ goto bail;
+ }
+
+ /* asCapable */
+ if( ret && *count >= (off_t) sizeof( asCapable )) {
+ memcpy( buf, &asCapable, sizeof( asCapable ));
+ *count -= sizeof( asCapable );
+ buf = ((char *)buf) + sizeof( asCapable );
+ } else if( ret == false ) {
+ *count += sizeof( asCapable );
+ } else {
+ *count = sizeof( asCapable )-*count;
+ ret = false;
+ }
+
+ /* Port State */
+ if( ret && *count >= (off_t) sizeof( port_state )) {
+ memcpy( buf, &port_state, sizeof( port_state ));
+ *count -= sizeof( port_state );
+ buf = ((char *)buf) + sizeof( port_state );
+ } else if( ret == false ) {
+ *count += sizeof( port_state );
+ } else {
+ *count = sizeof( port_state )-*count;
+ ret = false;
+ }
+
+ /* Link Delay */
+ if( ret && *count >= (off_t) sizeof( one_way_delay )) {
+ memcpy( buf, &one_way_delay, sizeof( one_way_delay ));
+ *count -= sizeof( one_way_delay );
+ buf = ((char *)buf) + sizeof( one_way_delay );
+ } else if( ret == false ) {
+ *count += sizeof( one_way_delay );
+ } else {
+ *count = sizeof( one_way_delay )-*count;
+ ret = false;
+ }
+
+ /* Neighbor Rate Ratio */
+ if( ret && *count >= (off_t) sizeof( _peer_rate_offset )) {
+ memcpy( buf, &_peer_rate_offset, sizeof( _peer_rate_offset ));
+ *count -= sizeof( _peer_rate_offset );
+ buf = ((char *)buf) + sizeof( _peer_rate_offset );
+ } else if( ret == false ) {
+ *count += sizeof( _peer_rate_offset );
+ } else {
+ *count = sizeof( _peer_rate_offset )-*count;
+ ret = false;
+ }
+
+ bail:
+ return ret;
+}
+
+bool CommonPort::restoreSerializedState
+( void *buf, off_t *count )
+{
+ bool ret = true;
+
+ /* asCapable */
+ if( ret && *count >= (off_t) sizeof( asCapable )) {
+ memcpy( &asCapable, buf, sizeof( asCapable ));
+ *count -= sizeof( asCapable );
+ buf = ((char *)buf) + sizeof( asCapable );
+ } else if( ret == false ) {
+ *count += sizeof( asCapable );
+ } else {
+ *count = sizeof( asCapable )-*count;
+ ret = false;
+ }
+
+ /* Port State */
+ if( ret && *count >= (off_t) sizeof( port_state )) {
+ memcpy( &port_state, buf, sizeof( port_state ));
+ *count -= sizeof( port_state );
+ buf = ((char *)buf) + sizeof( port_state );
+ } else if( ret == false ) {
+ *count += sizeof( port_state );
+ } else {
+ *count = sizeof( port_state )-*count;
+ ret = false;
+ }
+
+ /* Link Delay */
+ if( ret && *count >= (off_t) sizeof( one_way_delay )) {
+ memcpy( &one_way_delay, buf, sizeof( one_way_delay ));
+ *count -= sizeof( one_way_delay );
+ buf = ((char *)buf) + sizeof( one_way_delay );
+ } else if( ret == false ) {
+ *count += sizeof( one_way_delay );
+ } else {
+ *count = sizeof( one_way_delay )-*count;
+ ret = false;
+ }
+
+ /* Neighbor Rate Ratio */
+ if( ret && *count >= (off_t) sizeof( _peer_rate_offset )) {
+ memcpy( &_peer_rate_offset, buf, sizeof( _peer_rate_offset ));
+ *count -= sizeof( _peer_rate_offset );
+ buf = ((char *)buf) + sizeof( _peer_rate_offset );
+ } else if( ret == false ) {
+ *count += sizeof( _peer_rate_offset );
+ } else {
+ *count = sizeof( _peer_rate_offset )-*count;
+ ret = false;
+ }
+
+ return ret;
+}
+
+void CommonPort::startSyncReceiptTimer
+( long long unsigned int waitTime )
+{
+ syncReceiptTimerLock->lock();
+ clock->deleteEventTimerLocked( this, SYNC_RECEIPT_TIMEOUT_EXPIRES );
+ clock->addEventTimerLocked
+ ( this, SYNC_RECEIPT_TIMEOUT_EXPIRES, waitTime );
+ syncReceiptTimerLock->unlock();
+}
+
+void CommonPort::stopSyncReceiptTimer( void )
+{
+ syncReceiptTimerLock->lock();
+ clock->deleteEventTimerLocked( this, SYNC_RECEIPT_TIMEOUT_EXPIRES );
+ syncReceiptTimerLock->unlock();
+}
+
+void CommonPort::startSyncIntervalTimer
+( long long unsigned int waitTime )
+{
+ syncIntervalTimerLock->lock();
+ clock->deleteEventTimerLocked(this, SYNC_INTERVAL_TIMEOUT_EXPIRES);
+ clock->addEventTimerLocked
+ (this, SYNC_INTERVAL_TIMEOUT_EXPIRES, waitTime);
+ syncIntervalTimerLock->unlock();
+}
+
+void CommonPort::startAnnounceIntervalTimer
+( long long unsigned int waitTime )
+{
+ announceIntervalTimerLock->lock();
+ clock->deleteEventTimerLocked
+ ( this, ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES );
+ clock->addEventTimerLocked
+ ( this, ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES, waitTime );
+ announceIntervalTimerLock->unlock();
+}
+
+bool CommonPort::processStateChange( Event e )
+{
+ bool changed_external_master;
+ uint8_t LastEBestClockIdentity[PTP_CLOCK_IDENTITY_LENGTH];
+ int number_ports, j;
+ PTPMessageAnnounce *EBest = NULL;
+ char EBestClockIdentity[PTP_CLOCK_IDENTITY_LENGTH];
+ CommonPort **ports;
+
+ // Nothing to do if we are slave only
+ if ( clock->getPriority1() == 255 )
+ return true;
+
+ clock->getPortList(number_ports, ports);
+
+ /* Find EBest for all ports */
+ j = 0;
+ for (int i = 0; i < number_ports; ++i) {
+ while (ports[j] == NULL)
+ ++j;
+ if ( ports[j]->getPortState() == PTP_DISABLED ||
+ ports[j]->getPortState() == PTP_FAULTY )
+ {
+ continue;
+ }
+ if( EBest == NULL )
+ {
+ EBest = ports[j]->calculateERBest();
+ }
+ else if( ports[j]->calculateERBest() )
+ {
+ if( ports[j]->
+ calculateERBest()->isBetterThan(EBest))
+ {
+ EBest = ports[j]->calculateERBest();
+ }
+ }
+ }
+
+ if (EBest == NULL)
+ {
+ return true;
+ }
+
+ /* Check if we've changed */
+ clock->getLastEBestIdentity().
+ getIdentityString( LastEBestClockIdentity );
+ EBest->getGrandmasterIdentity( EBestClockIdentity );
+ if( memcmp( EBestClockIdentity, LastEBestClockIdentity,
+ PTP_CLOCK_IDENTITY_LENGTH ) != 0 )
+ {
+ ClockIdentity newGM;
+ changed_external_master = true;
+ newGM.set((uint8_t *) EBestClockIdentity );
+ clock->setLastEBestIdentity( newGM );
+ }
+ else
+ {
+ changed_external_master = false;
+ }
+
+ if( clock->isBetterThan( EBest ))
+ {
+ // We're Grandmaster, set grandmaster info to me
+ ClockIdentity clock_identity;
+ unsigned char priority1;
+ unsigned char priority2;
+ ClockQuality clock_quality;
+
+ clock_identity = getClock()->getClockIdentity();
+ getClock()->setGrandmasterClockIdentity( clock_identity );
+ priority1 = getClock()->getPriority1();
+ getClock()->setGrandmasterPriority1( priority1 );
+ priority2 = getClock()->getPriority2();
+ getClock()->setGrandmasterPriority2( priority2 );
+ clock_quality = getClock()->getClockQuality();
+ getClock()->setGrandmasterClockQuality( clock_quality );
+ }
+
+ j = 0;
+ for( int i = 0; i < number_ports; ++i )
+ {
+ while (ports[j] == NULL)
+ ++j;
+ if ( ports[j]->getPortState() ==
+ PTP_DISABLED ||
+ ports[j]->getPortState() ==
+ PTP_FAULTY)
+ {
+ continue;
+ }
+ if (clock->isBetterThan(EBest))
+ {
+ // We are the GrandMaster, all ports are master
+ EBest = NULL; // EBest == NULL : we were grandmaster
+ ports[j]->recommendState( PTP_MASTER,
+ changed_external_master );
+ } else {
+ if( EBest == ports[j]->calculateERBest() ) {
+ // The "best" Announce was received on this
+ // port
+ ClockIdentity clock_identity;
+ unsigned char priority1;
+ unsigned char priority2;
+ ClockQuality *clock_quality;
+
+ ports[j]->recommendState
+ ( PTP_SLAVE, changed_external_master );
+ clock_identity =
+ EBest->getGrandmasterClockIdentity();
+ getClock()->setGrandmasterClockIdentity
+ ( clock_identity );
+ priority1 = EBest->getGrandmasterPriority1();
+ getClock()->setGrandmasterPriority1
+ ( priority1 );
+ priority2 =
+ EBest->getGrandmasterPriority2();
+ getClock()->setGrandmasterPriority2
+ ( priority2 );
+ clock_quality =
+ EBest->getGrandmasterClockQuality();
+ getClock()->setGrandmasterClockQuality
+ (*clock_quality);
+ } else {
+ /* Otherwise we are the master because we have
+ sync'd to a better clock */
+ ports[j]->recommendState
+ (PTP_MASTER, changed_external_master);
+ }
+ }
+ }
+
+ return true;
+}
+
+
+bool CommonPort::processSyncAnnounceTimeout( Event e )
+{
+ // Nothing to do
+ if( clock->getPriority1() != 255 )
+ return true;
+
+ // Restart timer
+ if( e == ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES ) {
+ clock->addEventTimerLocked
+ (this, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES,
+ (ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER*
+ (unsigned long long)
+ (pow((double)2,getAnnounceInterval())*
+ 1000000000.0)));
+ } else {
+ startSyncReceiptTimer
+ ((unsigned long long)
+ (SYNC_RECEIPT_TIMEOUT_MULTIPLIER *
+ ((double) pow((double)2, getSyncInterval()) *
+ 1000000000.0)));
+ }
+
+ if ( getPortState() == PTP_INITIALIZING ||
+ getPortState() == PTP_UNCALIBRATED ||
+ getPortState() == PTP_SLAVE ||
+ getPortState() == PTP_PRE_MASTER )
+ {
+ GPTP_LOG_STATUS(
+ "*** %s Timeout Expired - Becoming Master",
+ e == ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES ? "Announce" :
+ "Sync" );
+ {
+ // We're Grandmaster, set grandmaster info to me
+ ClockIdentity clock_identity;
+ unsigned char priority1;
+ unsigned char priority2;
+ ClockQuality clock_quality;
+
+ clock_identity = getClock()->getClockIdentity();
+ getClock()->setGrandmasterClockIdentity
+ ( clock_identity );
+ priority1 = getClock()->getPriority1();
+ getClock()->setGrandmasterPriority1( priority1 );
+ priority2 = getClock()->getPriority2();
+ getClock()->setGrandmasterPriority2( priority2 );
+ clock_quality = getClock()->getClockQuality();
+ getClock()->setGrandmasterClockQuality
+ ( clock_quality );
+ }
+ setPortState( PTP_MASTER );
+ Timestamp system_time;
+ Timestamp device_time;
+
+ uint32_t local_clock, nominal_clock_rate;
+
+ getDeviceTime(system_time, device_time,
+ local_clock, nominal_clock_rate);
+
+ (void) clock->calcLocalSystemClockRateDifference
+ ( device_time, system_time );
+
+ setQualifiedAnnounce( NULL );
+
+ // Add timers for Announce and Sync, this is as close to
+ // immediately as we get
+ if( clock->getPriority1() != 255)
+ {
+ clock->addEventTimerLocked
+ ( this, SYNC_INTERVAL_TIMEOUT_EXPIRES,
+ 16000000 );
+ }
+ startAnnounce();
+ }
+
+ return true;
+}
+
+bool CommonPort::processEvent( Event e )
+{
+ bool ret;
+
+ switch( e )
+ {
+ default:
+ // Unhandled event
+ ret = _processEvent( e );
+ break;
+
+ case POWERUP:
+ case INITIALIZE:
+ GPTP_LOG_DEBUG("Received POWERUP/INITIALIZE event");
+
+ // If port has been configured as master or slave, run media
+ // specific configuration. If it hasn't been configured
+ // start announce message time
+ if( clock->getPriority1() == 255 ||
+ port_state == PTP_SLAVE )
+ {
+ becomeSlave( true );
+ }
+ else if( port_state == PTP_MASTER )
+ {
+ becomeMaster( true );
+ }
+ else
+ {
+ startAnnounce();
+ }
+
+ // Do any media specific initialization
+ ret = _processEvent( e );
+ break;
+
+ case STATE_CHANGE_EVENT:
+ ret = _processEvent( e );
+
+ // If this event wasn't handled in a media specific way, call
+ // the default action
+ if( !ret )
+ ret = processStateChange( e );
+ break;
+
+ case ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES:
+ case SYNC_RECEIPT_TIMEOUT_EXPIRES:
+ if (e == ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES) {
+ incCounter_ieee8021AsPortStatAnnounceReceiptTimeouts();
+ }
+ else if (e == SYNC_RECEIPT_TIMEOUT_EXPIRES) {
+ incCounter_ieee8021AsPortStatRxSyncReceiptTimeouts();
+ }
+
+ ret = _processEvent( e );
+
+ // If this event wasn't handled in a media specific way, call
+ // the default action
+ if( !ret )
+ ret = processSyncAnnounceTimeout( e );
+ break;
+
+ case ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES:
+ GPTP_LOG_DEBUG("ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES occured");
+ if( !asCapable )
+ {
+ ret = true;
+ break;
+ }
+
+ // Send an announce message
+ {
+ PTPMessageAnnounce *annc =
+ new PTPMessageAnnounce(this);
+ PortIdentity dest_id;
+ PortIdentity gmId;
+ ClockIdentity clock_id = clock->getClockIdentity();
+ gmId.setClockIdentity(clock_id);
+ getPortIdentity( dest_id );
+ annc->setPortIdentity( &dest_id );
+ annc->sendPort( this, NULL );
+ delete annc;
+ }
+
+ startAnnounceIntervalTimer
+ ((uint64_t)( pow((double)2, getAnnounceInterval()) *
+ 1000000000.0 ));
+ ret = true;
+ break;
+
+ case SYNC_INTERVAL_TIMEOUT_EXPIRES:
+ GPTP_LOG_DEBUG("SYNC_INTERVAL_TIMEOUT_EXPIRES occured");
+ // If asCapable is true attempt some media specific action
+ ret = true;
+ if( asCapable )
+ ret = _processEvent( e );
+
+ /* Do getDeviceTime() after transmitting sync frame
+ causing an update to local/system timestamp */
+ {
+ Timestamp system_time;
+ Timestamp device_time;
+ uint32_t local_clock, nominal_clock_rate;
+ FrequencyRatio local_system_freq_offset;
+ int64_t local_system_offset;
+
+ getDeviceTime
+ ( system_time, device_time,
+ local_clock, nominal_clock_rate );
+
+ GPTP_LOG_VERBOSE
+ ( "port::processEvent(): System time: %u,%u "
+ "Device Time: %u,%u",
+ system_time.seconds_ls,
+ system_time.nanoseconds,
+ device_time.seconds_ls,
+ device_time.nanoseconds );
+
+ local_system_offset =
+ TIMESTAMP_TO_NS(system_time) -
+ TIMESTAMP_TO_NS(device_time);
+ local_system_freq_offset =
+ clock->calcLocalSystemClockRateDifference
+ ( device_time, system_time );
+ clock->setMasterOffset
+ ( this, 0, device_time, 1.0,
+ local_system_offset, system_time,
+ local_system_freq_offset, getSyncCount(),
+ pdelay_count, port_state, asCapable );
+ }
+
+ // Call media specific action for completed sync
+ syncDone();
+
+ // Restart the timer
+ startSyncIntervalTimer
+ ((uint64_t)( pow((double)2, getSyncInterval()) *
+ 1000000000.0 ));
+
+ break;
+ }
+
+ return ret;
+}
+
+void CommonPort::getDeviceTime
+( Timestamp &system_time, Timestamp &device_time,
+ uint32_t &local_clock, uint32_t &nominal_clock_rate )
+{
+ if (_hw_timestamper) {
+ _hw_timestamper->HWTimestamper_gettime
+ ( &system_time, &device_time,
+ &local_clock, &nominal_clock_rate );
+ } else {
+ device_time = system_time = clock->getSystemTime();
+ local_clock = nominal_clock_rate = 0;
+ }
+
+ return;
+}
+
+void CommonPort::startAnnounce()
+{
+ startAnnounceIntervalTimer(16000000);
+}
diff --git a/daemons/gptp/common/common_port.hpp b/daemons/gptp/common/common_port.hpp
new file mode 100644
index 00000000..da333a74
--- /dev/null
+++ b/daemons/gptp/common/common_port.hpp
@@ -0,0 +1,1344 @@
+/******************************************************************************
+
+ Copyright (c) 2009-2012, Intel Corporation
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+******************************************************************************/
+
+
+#ifndef COMMON_PORT_HPP
+#define COMMON_PORT_HPP
+
+#include <avbts_message.hpp>
+#include <avbts_osthread.hpp>
+#include <avbts_oscondition.hpp>
+#include <avbts_ostimer.hpp>
+#include <avbts_oslock.hpp>
+#include <avbts_osnet.hpp>
+
+#include <math.h>
+
+class IEEE1588Clock;
+
+/**
+ * @brief PortIdentity interface
+ * Defined at IEEE 802.1AS Clause 8.5.2
+ */
+class PortIdentity {
+private:
+ ClockIdentity clock_id;
+ uint16_t portNumber;
+public:
+ /**
+ * @brief Default Constructor
+ */
+ PortIdentity() { };
+
+ /**
+ * @brief Constructs PortIdentity interface.
+ * @param clock_id Clock ID value as defined at IEEE 802.1AS Clause
+ * 8.5.2.2
+ * @param portNumber Port Number
+ */
+ PortIdentity(uint8_t * clock_id, uint16_t * portNumber)
+ {
+ this->portNumber = *portNumber;
+ this->portNumber = PLAT_ntohs(this->portNumber);
+ this->clock_id.set(clock_id);
+ }
+
+ /**
+ * @brief Implements the operator '!=' overloading method. Compares
+ * clock_id and portNumber.
+ * @param cmp Constant PortIdentity value to be compared against.
+ * @return TRUE if the comparison value differs from the object's
+ * PortIdentity value. FALSE otherwise.
+ */
+ bool operator!=(const PortIdentity & cmp) const
+ {
+ return
+ !(this->clock_id == cmp.clock_id) ||
+ this->portNumber != cmp.portNumber ? true : false;
+ }
+
+ /**
+ * @brief Implements the operator '==' overloading method. Compares
+ * clock_id and portNumber.
+ * @param cmp Constant PortIdentity value to be compared against.
+ * @return TRUE if the comparison value equals to the object's
+ * PortIdentity value. FALSE otherwise.
+ */
+ bool operator==(const PortIdentity & cmp)const
+ {
+ return
+ this->clock_id == cmp.clock_id &&
+ this->portNumber == cmp.portNumber ? true : false;
+ }
+
+ /**
+ * @brief Implements the operator '<' overloading method. Compares
+ * clock_id and portNumber.
+ * @param cmp Constant PortIdentity value to be compared against.
+ * @return TRUE if the comparison value is lower than the object's
+ * PortIdentity value. FALSE otherwise.
+ */
+ bool operator<(const PortIdentity & cmp)const
+ {
+ return
+ this->clock_id < cmp.clock_id ?
+ true : this->clock_id == cmp.clock_id &&
+ this->portNumber < cmp.portNumber ? true : false;
+ }
+
+ /**
+ * @brief Implements the operator '>' overloading method. Compares
+ * clock_id and portNumber.
+ * @param cmp Constant PortIdentity value to be compared against.
+ * @return TRUE if the comparison value is greater than the object's
+ * PortIdentity value. FALSE otherwise.
+ */
+ bool operator>(const PortIdentity & cmp)const
+ {
+ return
+ this->clock_id > cmp.clock_id ?
+ true : this->clock_id == cmp.clock_id &&
+ this->portNumber > cmp.portNumber ? true : false;
+ }
+
+ /**
+ * @brief Gets the ClockIdentity string
+ * @param id [out] Pointer to an array of octets.
+ * @return void
+ */
+ void getClockIdentityString(uint8_t *id)
+ {
+ clock_id.getIdentityString(id);
+ }
+
+ /**
+ * @brief Sets the ClockIdentity.
+ * @param clock_id Clock Identity to be set.
+ * @return void
+ */
+ void setClockIdentity(ClockIdentity clock_id)
+ {
+ this->clock_id = clock_id;
+ }
+
+ /**
+ * @brief Gets the clockIdentity value
+ * @return A copy of Clock identity value.
+ */
+ ClockIdentity getClockIdentity( void ) {
+ return this->clock_id;
+ }
+
+ /**
+ * @brief Gets the port number following the network byte order, i.e.
+ * Big-Endian.
+ * @param id [out] Port number
+ * @return void
+ */
+ void getPortNumberNO(uint16_t * id) // Network byte order
+ {
+ uint16_t portNumberNO = PLAT_htons(portNumber);
+ *id = portNumberNO;
+ }
+
+ /**
+ * @brief Gets the port number in the host byte order, which can be
+ * either Big-Endian
+ * or Little-Endian, depending on the processor where it is running.
+ * @param id Port number
+ * @return void
+ */
+ void getPortNumber(uint16_t * id) // Host byte order
+ {
+ *id = portNumber;
+ }
+
+ /**
+ * @brief Sets the Port number
+ * @param id [in] Port number
+ * @return void
+ */
+ void setPortNumber(uint16_t * id)
+ {
+ portNumber = *id;
+ }
+};
+
+/**
+ * @brief Structure for initializing the port class
+ */
+typedef struct {
+ /* clock IEEE1588Clock instance */
+ IEEE1588Clock * clock;
+
+ /* index Interface index */
+ uint16_t index;
+
+ /* timestamper Hardware timestamper instance */
+ HWTimestamper * timestamper;
+
+ /* net_label Network label */
+ InterfaceLabel *net_label;
+
+ /* automotive_profile set the AVnu automotive profile */
+ bool automotive_profile;
+
+ /* Set to true if the port is the grandmaster. Used for fixed GM in
+ * the the AVnu automotive profile */
+ bool isGM;
+
+ /* Set to true if the port is the grandmaster. Used for fixed GM in
+ * the the AVnu automotive profile */
+ bool testMode;
+
+ /* Set to true if the port's network interface is up. Used to filter
+ * false LINKUP/LINKDOWN events */
+ bool linkUp;
+
+ /* gPTP 10.2.4.4 */
+ char initialLogSyncInterval;
+
+ /* gPTP 11.5.2.2 */
+ char initialLogPdelayReqInterval;
+
+ /* CDS 6.2.1.5 */
+ char operLogPdelayReqInterval;
+
+ /* CDS 6.2.1.6 */
+ char operLogSyncInterval;
+
+ /* condition_factory OSConditionFactory instance */
+ OSConditionFactory * condition_factory;
+
+ /* thread_factory OSThreadFactory instance */
+ OSThreadFactory * thread_factory;
+
+ /* timer_factory OSTimerFactory instance */
+ OSTimerFactory * timer_factory;
+
+ /* lock_factory OSLockFactory instance */
+ OSLockFactory * lock_factory;
+} PortInit_t;
+
+
+/**
+ * @brief Structure for Port Counters
+ */
+typedef struct {
+ int32_t ieee8021AsPortStatRxSyncCount;
+ int32_t ieee8021AsPortStatRxFollowUpCount;
+ int32_t ieee8021AsPortStatRxPdelayRequest;
+ int32_t ieee8021AsPortStatRxPdelayResponse;
+ int32_t ieee8021AsPortStatRxPdelayResponseFollowUp;
+ int32_t ieee8021AsPortStatRxAnnounce;
+ int32_t ieee8021AsPortStatRxPTPPacketDiscard;
+ int32_t ieee8021AsPortStatRxSyncReceiptTimeouts;
+ int32_t ieee8021AsPortStatAnnounceReceiptTimeouts;
+ int32_t ieee8021AsPortStatPdelayAllowedLostResponsesExceeded;
+ int32_t ieee8021AsPortStatTxSyncCount;
+ int32_t ieee8021AsPortStatTxFollowUpCount;
+ int32_t ieee8021AsPortStatTxPdelayRequest;
+ int32_t ieee8021AsPortStatTxPdelayResponse;
+ int32_t ieee8021AsPortStatTxPdelayResponseFollowUp;
+ int32_t ieee8021AsPortStatTxAnnounce;
+} PortCounters_t;
+
+
+/**
+ * @brief Port functionality common to all network media
+ */
+class CommonPort
+{
+private:
+ LinkLayerAddress local_addr;
+ PortIdentity port_identity;
+
+ /* Network socket description
+ physical interface number that object represents */
+ uint16_t ifindex;
+
+
+ /* Signed value allows this to be negative result because of inaccurate
+ timestamp */
+ int64_t one_way_delay;
+ int64_t neighbor_prop_delay_thresh;
+
+ InterfaceLabel *net_label;
+
+ OSNetworkInterface *net_iface;
+ int phy_delay[4];
+
+ PortState port_state;
+ bool testMode;
+
+ char log_mean_sync_interval;
+ char log_mean_announce_interval;
+ char initialLogSyncInterval;
+
+ /*Sync threshold*/
+ unsigned int sync_receipt_thresh;
+ unsigned int wrongSeqIDCounter;
+
+ PortCounters_t counters;
+
+ OSThread *listening_thread;
+ OSThread *link_thread;
+
+ FrequencyRatio _peer_rate_offset;
+ Timestamp _peer_offset_ts_theirs;
+ Timestamp _peer_offset_ts_mine;
+ bool _peer_offset_init;
+ bool asCapable;
+ unsigned sync_count; /* 0 for master, increment for each sync
+ * received as slave */
+ unsigned pdelay_count;
+
+ PTPMessageAnnounce *qualified_announce;
+
+ uint16_t announce_sequence_id;
+ uint16_t signal_sequence_id;
+ uint16_t sync_sequence_id;
+
+ uint16_t lastGmTimeBaseIndicator;
+
+ OSLock *syncReceiptTimerLock;
+ OSLock *syncIntervalTimerLock;
+ OSLock *announceIntervalTimerLock;
+
+protected:
+ static const unsigned int DEFAULT_SYNC_RECEIPT_THRESH = 5;
+ static const int64_t INVALID_LINKDELAY = 3600000000000;
+ static const int64_t ONE_WAY_DELAY_DEFAULT = INVALID_LINKDELAY;
+ static const int64_t NEIGHBOR_PROP_DELAY_THRESH = 800;
+
+ OSThreadFactory const * const thread_factory;
+ OSTimerFactory const * const timer_factory;
+ OSLockFactory const * const lock_factory;
+ OSConditionFactory const * const condition_factory;
+ HWTimestamper * const _hw_timestamper;
+ IEEE1588Clock * const clock;
+ const bool isGM;
+
+public:
+ CommonPort( PortInit_t *portInit );
+ virtual ~CommonPort();
+
+ /**
+ * @brief Global media dependent port initialization
+ * @param [in] phy_delay array representing delays introduced by the
+ * device PHY
+ * @return true on success
+ */
+ bool init_port( int phy_delay[4] );
+
+ /**
+ * @brief Media specific port initialization
+ * @return true on success
+ */
+ virtual bool _init_port( void ) = 0;
+
+ /**
+ * @brief Initializes the hwtimestamper
+ */
+ void timestamper_init( void );
+
+ /**
+ * @brief Resets the hwtimestamper
+ */
+ void timestamper_reset( void );
+
+ /**
+ * @brief Gets the link delay information.
+ * @return one way delay if delay > 0, or zero otherwise.
+ */
+ uint64_t getLinkDelay( void )
+ {
+ return one_way_delay > 0LL ? one_way_delay : 0LL;
+ }
+
+ /**
+ * @brief Gets the link delay information.
+ * @param [in] delay Pointer to the delay information
+ * @return True if valid, false if invalid
+ */
+ bool getLinkDelay( uint64_t *delay )
+ {
+ if(delay == NULL) {
+ return false;
+ }
+ *delay = getLinkDelay();
+ return *delay < INVALID_LINKDELAY;
+ }
+
+ /**
+ * @brief Sets link delay information.
+ * Signed value allows this to be negative result because
+ * of inaccurate timestamps.
+ * @param delay Link delay
+ * @return True if one_way_delay is lower or equal than neighbor
+ * propagation delay threshold False otherwise
+ */
+ bool setLinkDelay( int64_t delay )
+ {
+ one_way_delay = delay;
+ int64_t abs_delay = (one_way_delay < 0 ?
+ -one_way_delay : one_way_delay);
+
+ if (testMode) {
+ GPTP_LOG_STATUS("Link delay: %d", delay);
+ }
+
+ return (abs_delay <= neighbor_prop_delay_thresh);
+ }
+
+ /**
+ * @brief Gets a pointer to IEEE1588Clock
+ * @return Pointer to clock
+ */
+ IEEE1588Clock *getClock( void )
+ {
+ return clock;
+ }
+
+ /**
+ * @brief Gets the local_addr
+ * @return LinkLayerAddress
+ */
+ LinkLayerAddress *getLocalAddr( void )
+ {
+ return &local_addr;
+ }
+
+ /**
+ * @brief Gets the testMode
+ * @return bool of the test mode value
+ */
+ bool getTestMode( void )
+ {
+ return testMode;
+ }
+
+ /**
+ * @brief Sets the testMode
+ * @param testMode changes testMode to this value
+ */
+ void setTestMode( bool testMode )
+ {
+ this->testMode = testMode;
+ }
+
+ /**
+ * @brief Serializes (i.e. copy over buf pointer) the information from
+ * the variables (in that order):
+ * - asCapable;
+ * - Port Sate;
+ * - Link Delay;
+ * - Neighbor Rate Ratio
+ * @param buf [out] Buffer where to put the results.
+ * @param count [inout] Length of buffer. It contains maximum length
+ * to be written
+ * when the function is called, and the value is decremented by the
+ * same amount the
+ * buf size increases.
+ * @return TRUE if it has successfully written to buf all the values
+ * or if buf is NULL.
+ * FALSE if count should be updated with the right size.
+ */
+ bool serializeState( void *buf, long *count );
+
+ /**
+ * @brief Restores the serialized state from the buffer. Copies the
+ * information from buffer
+ * to the variables (in that order):
+ * - asCapable;
+ * - Port State;
+ * - Link Delay;
+ * - Neighbor Rate Ratio
+ * @param buf Buffer containing the serialized state.
+ * @param count Buffer lenght. It is decremented by the same size of
+ * the variables that are
+ * being copied.
+ * @return TRUE if everything was copied successfully, FALSE otherwise.
+ */
+ bool restoreSerializedState( void *buf, long *count );
+
+ /**
+ * @brief Sets the internal variabl sync_receipt_thresh, which is the
+ * flag that monitors the amount of wrong syncs enabled before
+ * switching
+ * the ptp to master.
+ * @param th Threshold to be set
+ * @return void
+ */
+ void setSyncReceiptThresh(unsigned int th)
+ {
+ sync_receipt_thresh = th;
+ }
+
+ /**
+ * @brief Gets the internal variabl sync_receipt_thresh, which is the
+ * flag that monitors the amount of wrong syncs enabled before
+ * switching
+ * the ptp to master.
+ * @return sync_receipt_thresh value
+ */
+ unsigned int getSyncReceiptThresh( void )
+ {
+ return sync_receipt_thresh;
+ }
+
+ /**
+ * @brief Sets the wrongSeqIDCounter variable
+ * @param cnt Value to be set
+ * @return void
+ */
+ void setWrongSeqIDCounter(unsigned int cnt)
+ {
+ wrongSeqIDCounter = cnt;
+ }
+
+ /**
+ * @brief Gets the wrongSeqIDCounter value
+ * @param [out] cnt Pointer to the counter value. It must be valid
+ * @return TRUE if ok and lower than the syncReceiptThreshold value.
+ * FALSE otherwise
+ */
+ bool getWrongSeqIDCounter(unsigned int *cnt)
+ {
+ if( cnt == NULL )
+ {
+ return false;
+ }
+ *cnt = wrongSeqIDCounter;
+
+ return( *cnt < getSyncReceiptThresh() );
+ }
+
+ /**
+ * @brief Increments the wrongSeqIDCounter value
+ * @param [out] cnt Pointer to the counter value. Must be valid
+ * @return TRUE if incremented value is lower than the
+ * syncReceiptThreshold. FALSE otherwise.
+ */
+ bool incWrongSeqIDCounter(unsigned int *cnt)
+ {
+ if( getAsCapable() )
+ {
+ wrongSeqIDCounter++;
+ }
+ bool ret = wrongSeqIDCounter < getSyncReceiptThresh();
+
+ if( cnt != NULL)
+ {
+ *cnt = wrongSeqIDCounter;
+ }
+
+ return ret;
+ }
+
+ /**
+ * @brief Gets the hardware timestamper version
+ * @return HW timestamper version
+ */
+ int getTimestampVersion() {
+ return _hw_timestamper->getVersion();
+ }
+
+ /**
+ * @brief Adjusts the clock frequency.
+ * @param freq_offset Frequency offset
+ * @return TRUE if adjusted. FALSE otherwise.
+ */
+ bool _adjustClockRate( FrequencyRatio freq_offset ) {
+ if( _hw_timestamper ) {
+ return _hw_timestamper->HWTimestamper_adjclockrate
+ ((float) freq_offset );
+ }
+ return false;
+ }
+
+ /**
+ * @brief Adjusts the clock frequency.
+ * @param freq_offset Frequency offset
+ * @return TRUE if adjusted. FALSE otherwise.
+ */
+ bool adjustClockRate( FrequencyRatio freq_offset ) {
+ return _adjustClockRate( freq_offset );
+ }
+
+ /**
+ * @brief Gets extended error message from hardware timestamper
+ * @param msg [out] Extended error message
+ * @return void
+ */
+ void getExtendedError(char *msg) {
+ if (_hw_timestamper) {
+ _hw_timestamper->HWTimestamper_get_extderror(msg);
+ } else {
+ *msg = '\0';
+ }
+ }
+
+ /**
+ * @brief Increment IEEE Port counter:
+ * ieee8021AsPortStatRxSyncCount
+ * @return void
+ */
+ void incCounter_ieee8021AsPortStatRxSyncCount( void )
+ {
+ counters.ieee8021AsPortStatRxSyncCount++;
+ }
+
+ /**
+ * @brief Increment IEEE Port counter:
+ * ieee8021AsPortStatRxFollowUpCount
+ * @return void
+ */
+ void incCounter_ieee8021AsPortStatRxFollowUpCount( void )
+ {
+ counters.ieee8021AsPortStatRxFollowUpCount++;
+ }
+
+ /**
+ * @brief Increment IEEE Port counter:
+ * ieee8021AsPortStatRxPdelayRequest
+ * @return void
+ */
+ void incCounter_ieee8021AsPortStatRxPdelayRequest( void )
+ {
+ counters.ieee8021AsPortStatRxPdelayRequest++;
+ }
+
+ /**
+ * @brief Increment IEEE Port counter:
+ * ieee8021AsPortStatRxPdelayResponse
+ * @return void
+ */
+ void incCounter_ieee8021AsPortStatRxPdelayResponse( void )
+ {
+ counters.ieee8021AsPortStatRxPdelayResponse++;
+ }
+
+ /**
+ * @brief Increment IEEE Port counter:
+ * ieee8021AsPortStatRxPdelayResponseFollowUp
+ * @return void
+ */
+ void incCounter_ieee8021AsPortStatRxPdelayResponseFollowUp( void )
+ {
+ counters.ieee8021AsPortStatRxPdelayResponseFollowUp++;
+ }
+
+ /**
+ * @brief Increment IEEE Port counter:
+ * ieee8021AsPortStatRxAnnounce
+ * @return void
+ */
+ void incCounter_ieee8021AsPortStatRxAnnounce( void )
+ {
+ counters.ieee8021AsPortStatRxAnnounce++;
+ }
+
+ /**
+ * @brief Increment IEEE Port counter:
+ * ieee8021AsPortStatRxPTPPacketDiscard
+ * @return void
+ */
+ void incCounter_ieee8021AsPortStatRxPTPPacketDiscard( void )
+ {
+ counters.ieee8021AsPortStatRxPTPPacketDiscard++;
+ }
+
+ /**
+ * @brief Increment IEEE Port counter:
+ * ieee8021AsPortStatRxSyncReceiptTimeouts
+ * @return void
+ */
+ void incCounter_ieee8021AsPortStatRxSyncReceiptTimeouts( void )
+ {
+ counters.ieee8021AsPortStatRxSyncReceiptTimeouts++;
+ }
+
+ /**
+ * @brief Increment IEEE Port counter:
+ * ieee8021AsPortStatAnnounceReceiptTimeouts
+ * @return void
+ */
+ void incCounter_ieee8021AsPortStatAnnounceReceiptTimeouts( void )
+ {
+ counters.ieee8021AsPortStatAnnounceReceiptTimeouts++;
+ }
+
+
+ /**
+ * @brief Increment IEEE Port counter:
+ * ieee8021AsPortStatPdelayAllowedLostResponsesExceeded
+ * @return void
+ */
+ // TODO: Not called
+ void incCounter_ieee8021AsPortStatPdelayAllowedLostResponsesExceeded
+ ( void )
+ {
+ counters.
+ ieee8021AsPortStatPdelayAllowedLostResponsesExceeded++;
+ }
+
+ /**
+ * @brief Increment IEEE Port counter:
+ * ieee8021AsPortStatTxSyncCount
+ * @return void
+ */
+ void incCounter_ieee8021AsPortStatTxSyncCount( void )
+ {
+ counters.ieee8021AsPortStatTxSyncCount++;
+ }
+
+ /**
+ * @brief Increment IEEE Port counter:
+ * ieee8021AsPortStatTxFollowUpCount
+ * @return void
+ */
+ void incCounter_ieee8021AsPortStatTxFollowUpCount( void )
+ {
+ counters.ieee8021AsPortStatTxFollowUpCount++;
+ }
+
+ /**
+ * @brief Increment IEEE Port counter:
+ * ieee8021AsPortStatTxPdelayRequest
+ * @return void
+ */
+ void incCounter_ieee8021AsPortStatTxPdelayRequest( void )
+ {
+ counters.ieee8021AsPortStatTxPdelayRequest++;
+ }
+
+ /**
+ * @brief Increment IEEE Port counter:
+ * ieee8021AsPortStatTxPdelayResponse
+ * @return void
+ */
+ void incCounter_ieee8021AsPortStatTxPdelayResponse( void )
+ {
+ counters.ieee8021AsPortStatTxPdelayResponse++;
+ }
+
+ /**
+ * @brief Increment IEEE Port counter:
+ * ieee8021AsPortStatTxPdelayResponseFollowUp
+ * @return void
+ */
+ void incCounter_ieee8021AsPortStatTxPdelayResponseFollowUp( void )
+ {
+ counters.ieee8021AsPortStatTxPdelayResponseFollowUp++;
+ }
+
+ /**
+ * @brief Increment IEEE Port counter:
+ * ieee8021AsPortStatTxAnnounce
+ * @return void
+ */
+ void incCounter_ieee8021AsPortStatTxAnnounce( void )
+ {
+ counters.ieee8021AsPortStatTxAnnounce++;
+ }
+
+ /**
+ * @brief Logs port counters
+ * @return void
+ */
+ void logIEEEPortCounters( void )
+ {
+ GPTP_LOG_STATUS
+ ( "IEEE Port Counter "
+ "ieee8021AsPortStatRxSyncCount : %u",
+ counters.ieee8021AsPortStatRxSyncCount );
+ GPTP_LOG_STATUS
+ ( "IEEE Port Counter "
+ "ieee8021AsPortStatRxFollowUpCount : %u",
+ counters.ieee8021AsPortStatRxFollowUpCount );
+ GPTP_LOG_STATUS
+ ( "IEEE Port Counter "
+ "ieee8021AsPortStatRxPdelayRequest : %u",
+ counters.ieee8021AsPortStatRxPdelayRequest );
+ GPTP_LOG_STATUS
+ ( "IEEE Port Counter "
+ "ieee8021AsPortStatRxPdelayResponse : %u",
+ counters.ieee8021AsPortStatRxPdelayResponse );
+ GPTP_LOG_STATUS
+ ( "IEEE Port Counter "
+ "ieee8021AsPortStatRxPdelayResponseFollowUp "
+ ": %u", counters.
+ ieee8021AsPortStatRxPdelayResponseFollowUp );
+ GPTP_LOG_STATUS
+ ( "IEEE Port Counter "
+ "ieee8021AsPortStatRxAnnounce : %u",
+ counters.ieee8021AsPortStatRxAnnounce );
+ GPTP_LOG_STATUS
+ ( "IEEE Port Counter "
+ "ieee8021AsPortStatRxPTPPacketDiscard : %u",
+ counters.
+ ieee8021AsPortStatRxPTPPacketDiscard );
+ GPTP_LOG_STATUS
+ ( "IEEE Port Counter "
+ "ieee8021AsPortStatRxSyncReceiptTimeouts "
+ ": %u", counters.
+ ieee8021AsPortStatRxSyncReceiptTimeouts );
+ GPTP_LOG_STATUS
+ ( "IEEE Port Counter "
+ "ieee8021AsPortStatAnnounceReceiptTimeouts "
+ ": %u", counters.
+ ieee8021AsPortStatAnnounceReceiptTimeouts );
+ GPTP_LOG_STATUS
+ ( "IEEE Port Counter "
+ "ieee8021AsPortStatPdelayAllowed"
+ "LostResponsesExceeded : %u", counters.
+ ieee8021AsPortStatPdelayAllowedLostResponsesExceeded
+ );
+ GPTP_LOG_STATUS
+ ( "IEEE Port Counter "
+ "ieee8021AsPortStatTxSyncCount : %u",
+ counters.ieee8021AsPortStatTxSyncCount );
+ GPTP_LOG_STATUS
+ ( "IEEE Port Counter "
+ "ieee8021AsPortStatTxFollowUpCount : %u", counters.
+ ieee8021AsPortStatTxFollowUpCount);
+ GPTP_LOG_STATUS
+ ( "IEEE Port Counter "
+ "ieee8021AsPortStatTxPdelayRequest : %u",
+ counters.ieee8021AsPortStatTxPdelayRequest);
+ GPTP_LOG_STATUS
+ ( "IEEE Port Counter "
+ "ieee8021AsPortStatTxPdelayResponse : %u", counters.
+ ieee8021AsPortStatTxPdelayResponse);
+ GPTP_LOG_STATUS
+ ( "IEEE Port Counter "
+ "ieee8021AsPortStatTxPdelayResponseFollowUp : %u",
+ counters.ieee8021AsPortStatTxPdelayResponseFollowUp
+ );
+ GPTP_LOG_STATUS
+ ( "IEEE Port Counter "
+ "ieee8021AsPortStatTxAnnounce : %u",
+ counters.ieee8021AsPortStatTxAnnounce);
+ }
+
+ /**
+ * @brief Get the cross timestamping information.
+ * The gPTP subsystem uses these samples to calculate
+ * ratios which can be used to translate or extrapolate
+ * one clock into another clock reference. The gPTP service
+ * uses these supplied cross timestamps to perform internal
+ * rate estimation and conversion functions.
+ * @param system_time [out] System time
+ * @param device_time [out] Device time
+ * @param local_clock [out] Local clock
+ * @param nominal_clock_rate [out] Nominal clock rate
+ * @return True in case of success. FALSE in case of error
+ */
+ void getDeviceTime
+ ( Timestamp &system_time, Timestamp &device_time,
+ uint32_t &local_clock, uint32_t & nominal_clock_rate );
+
+ /**
+ * @brief Sets asCapable flag
+ * @param ascap flag to be set. If FALSE, marks peer_offset_init as
+ * false.
+ * @return void
+ */
+ void setAsCapable(bool ascap)
+ {
+ if ( ascap != asCapable ) {
+ GPTP_LOG_STATUS
+ ("AsCapable: %s", ascap == true
+ ? "Enabled" : "Disabled");
+ }
+ if( !ascap )
+ {
+ _peer_offset_init = false;
+ }
+ asCapable = ascap;
+ }
+
+ /**
+ * @brief Gets the asCapable flag
+ * @return asCapable flag.
+ */
+ bool getAsCapable()
+ {
+ return( asCapable );
+ }
+
+ /**
+ * @brief Gets the Peer rate offset. Used to calculate neighbor
+ * rate ratio.
+ * @return FrequencyRatio peer rate offset
+ */
+ FrequencyRatio getPeerRateOffset( void )
+ {
+ return _peer_rate_offset;
+ }
+
+ /**
+ * @brief Sets the peer rate offset. Used to calculate neighbor rate
+ * ratio.
+ * @param offset Offset to be set
+ * @return void
+ */
+ void setPeerRateOffset( FrequencyRatio offset ) {
+ _peer_rate_offset = offset;
+ }
+
+ /**
+ * @brief Sets peer offset timestamps
+ * @param mine Local timestamps
+ * @param theirs Remote timestamps
+ * @return void
+ */
+ void setPeerOffset(Timestamp mine, Timestamp theirs) {
+ _peer_offset_ts_mine = mine;
+ _peer_offset_ts_theirs = theirs;
+ _peer_offset_init = true;
+ }
+
+ /**
+ * @brief Gets peer offset timestamps
+ * @param mine [out] Reference to local timestamps
+ * @param theirs [out] Reference to remote timestamps
+ * @return TRUE if peer offset has already been initialized. FALSE
+ * otherwise.
+ */
+ bool getPeerOffset(Timestamp & mine, Timestamp & theirs) {
+ mine = _peer_offset_ts_mine;
+ theirs = _peer_offset_ts_theirs;
+ return _peer_offset_init;
+ }
+
+ /**
+ * @brief Sets the neighbor propagation delay threshold
+ * @param delay Delay in nanoseconds
+ * @return void
+ */
+ void setNeighPropDelayThresh(int64_t delay) {
+ neighbor_prop_delay_thresh = delay;
+ }
+
+ /**
+ * @brief Restart PDelay
+ * @return void
+ */
+ void restartPDelay() {
+ _peer_offset_init = false;
+ }
+
+ /**
+ * @brief Gets a pointer to timer_factory object
+ * @return timer_factory pointer
+ */
+ const OSTimerFactory *getTimerFactory() {
+ return timer_factory;
+ }
+
+ /**
+ * @brief Watch for link up and down events.
+ * @return Its an infinite loop. Returns NULL in case of error.
+ */
+ void *watchNetLink( void )
+ {
+ // Should never return
+ net_iface->watchNetLink(this);
+
+ return NULL;
+ }
+
+ /**
+ * @brief Receive frame
+ */
+ net_result recv( LinkLayerAddress *addr, uint8_t *payload,
+ size_t &length, struct phy_delay *delay )
+ {
+ return net_iface->nrecv( addr, payload, length, delay );
+ }
+
+ /**
+ * @brief Send frame
+ */
+ net_result send( LinkLayerAddress *addr, uint16_t etherType,
+ uint8_t *payload, size_t length, bool timestamp )
+ {
+ return net_iface->send
+ ( addr, etherType, payload, length, timestamp );
+ }
+
+ /**
+ * @brief Get the payload offset inside a packet
+ * @return 0
+ */
+ unsigned getPayloadOffset()
+ {
+ return net_iface->getPayloadOffset();
+ }
+
+ bool linkWatch( OSThreadFunction func, OSThreadFunctionArg arg )
+ {
+ return link_thread->start( func, arg );
+ }
+
+ bool linkOpen( OSThreadFunction func, OSThreadFunctionArg arg )
+ {
+ return listening_thread->start( func, arg );
+ }
+
+ /**
+ * @brief Gets the portState information
+ * @return PortState
+ */
+ PortState getPortState( void ) {
+ return port_state;
+ }
+
+ /**
+ * @brief Sets the PortState
+ * @param state value to be set
+ * @return void
+ */
+ void setPortState( PortState state ) {
+ port_state = state;
+ }
+
+ /**
+ * @brief Gets port identity
+ * @param identity [out] Reference to PortIdentity
+ * @return void
+ */
+ void getPortIdentity(PortIdentity & identity) {
+ identity = this->port_identity;
+ }
+
+ /**
+ * @brief Gets the "best" announce
+ * @return Pointer to PTPMessageAnnounce
+ */
+ PTPMessageAnnounce *calculateERBest( void );
+
+ /**
+ * @brief Changes the port state
+ * @param state Current state
+ * @param changed_external_master TRUE if external master has
+ * changed, FALSE otherwise
+ * @return void
+ */
+ void recommendState(PortState state, bool changed_external_master);
+
+ /**
+ * @brief Locks the TX port
+ * @return TRUE if success. FALSE otherwise.
+ */
+ virtual bool getTxLock()
+ {
+ return true;
+ }
+
+ /**
+ * @brief Unlocks the port TX.
+ * @return TRUE if success. FALSE otherwise.
+ */
+ virtual bool putTxLock()
+ {
+ return false;
+ }
+
+ /**
+ * @brief Adds a new qualified announce the port. IEEE 802.1AS
+ * Clause 10.3.10.2
+ * @param annc PTP announce message
+ * @return void
+ */
+ void setQualifiedAnnounce( PTPMessageAnnounce *annc )
+ {
+ delete qualified_announce;
+ qualified_announce = annc;
+ }
+
+ /**
+ * @brief Switches port to a gPTP master
+ * @param annc If TRUE, starts announce event timer.
+ * @return void
+ */
+ virtual void becomeMaster( bool annc ) = 0;
+
+ /**
+ * @brief Switches port to a gPTP slave.
+ * @param restart_syntonization if TRUE, restarts the syntonization
+ * @return void
+ */
+ virtual void becomeSlave( bool restart_syntonization ) = 0;
+
+ /**
+ * @brief Sets current sync count value.
+ * @param cnt [in] sync count value
+ * @return void
+ */
+ void setSyncCount(unsigned int cnt)
+ {
+ sync_count = cnt;
+ }
+
+ /**
+ * @brief Increments sync count
+ * @return void
+ */
+ void incSyncCount() {
+ ++sync_count;
+ }
+
+ /**
+ * @brief Gets current sync count value. It is set to zero
+ * when master and incremented at each sync received for slave.
+ * @return sync count
+ */
+ unsigned getSyncCount()
+ {
+ return sync_count;
+ }
+
+ /**
+ * @brief Sets current pdelay count value.
+ * @param cnt [in] pdelay count value
+ * @return void
+ */
+ void setPdelayCount(unsigned int cnt) {
+ pdelay_count = cnt;
+ }
+
+ /**
+ * @brief Increments Pdelay count
+ * @return void
+ */
+ void incPdelayCount()
+ {
+ ++pdelay_count;
+ }
+
+ /**
+ * @brief Gets current pdelay count value. It is set to zero
+ * when asCapable is false.
+ * @return pdelay count
+ */
+ unsigned getPdelayCount()
+ {
+ return pdelay_count;
+ }
+
+ /**
+ * @brief Increments announce sequence id and returns
+ * @return Next announce sequence id.
+ */
+ uint16_t getNextAnnounceSequenceId( void )
+ {
+ return announce_sequence_id++;
+ }
+
+ /**
+ * @brief Increments signal sequence id and returns
+ * @return Next signal sequence id.
+ */
+ uint16_t getNextSignalSequenceId( void )
+ {
+ return signal_sequence_id++;
+ }
+
+ /**
+ * @brief Increments sync sequence ID and returns
+ * @return Next synce sequence id.
+ */
+ uint16_t getNextSyncSequenceId( void )
+ {
+ return sync_sequence_id++;
+ }
+
+ /**
+ * @brief Gets the lastGmTimeBaseIndicator
+ * @return uint16 of the lastGmTimeBaseIndicator
+ */
+ uint16_t getLastGmTimeBaseIndicator( void ) {
+ return lastGmTimeBaseIndicator;
+ }
+
+ /**
+ * @brief Sets the lastGmTimeBaseIndicator
+ * @param gmTimeBaseIndicator from last Follow up message
+ * @return void
+ */
+ void setLastGmTimeBaseIndicator(uint16_t gmTimeBaseIndicator)
+ {
+ lastGmTimeBaseIndicator = gmTimeBaseIndicator;
+ }
+
+ /**
+ * @brief Gets the sync interval value
+ * @return Sync Interval
+ */
+ char getSyncInterval( void )
+ {
+ return log_mean_sync_interval;
+ }
+
+ /**
+ * @brief Sets the sync interval value
+ * @param val time interval
+ * @return none
+ */
+ void setSyncInterval( char val )
+ {
+ log_mean_sync_interval = val;
+ }
+
+ /**
+ * @brief Sets the sync interval back to initial value
+ * @return none
+ */
+ void resetInitSyncInterval( void )
+ {
+ log_mean_sync_interval = initialLogSyncInterval;;
+ }
+
+ /**
+ * @brief Sets the sync interval
+ * @return none
+ */
+ void setInitSyncInterval( char interval )
+ {
+ initialLogSyncInterval = interval;
+ }
+
+ /**
+ * @brief Gets the sync interval
+ * @return sync interval
+ */
+ char getInitSyncInterval( void )
+ {
+ return initialLogSyncInterval;
+ }
+
+ /**
+ * @brief Gets the announce interval
+ * @return Announce interval
+ */
+ char getAnnounceInterval( void ) {
+ return log_mean_announce_interval;
+ }
+
+ /**
+ * @brief Sets the announce interval
+ * @param val time interval
+ * @return none
+ */
+ void setAnnounceInterval(char val) {
+ log_mean_announce_interval = val;
+ }
+ /**
+ * @brief Start sync receipt timer
+ * @param waitTime time interval
+ * @return none
+ */
+ void startSyncReceiptTimer(long long unsigned int waitTime);
+
+ /**
+ * @brief Stop sync receipt timer
+ * @return none
+ */
+ void stopSyncReceiptTimer( void );
+
+ /**
+ * @brief Start sync interval timer
+ * @param waitTime time interval in nanoseconds
+ * @return none
+ */
+ void startSyncIntervalTimer(long long unsigned int waitTime);
+
+ /**
+ * @brief Start announce interval timer
+ * @param waitTime time interval
+ * @return none
+ */
+ void startAnnounceIntervalTimer(long long unsigned int waitTime);
+
+ /**
+ * @brief Starts announce event timer
+ * @return void
+ */
+ void startAnnounce();
+
+ /**
+ * @brief Process default state change event
+ * @return true if event is handled without errors
+ */
+ bool processStateChange( Event e );
+
+ /**
+ * @brief Default sync/announce timeout handler
+ * @return true if event is handled without errors
+ */
+ bool processSyncAnnounceTimeout( Event e );
+
+
+ /**
+ * @brief Perform default event action, can be overridden by media
+ * specific actions in _processEvent
+ * @return true if event is handled without errors
+ */
+ bool processEvent( Event e );
+
+ /**
+ * @brief Perform media specific event handling action
+ * @return true if event is handled without errors
+ */
+ virtual bool _processEvent( Event e ) = 0;
+
+ virtual void syncDone() = 0;
+
+ /**
+ * @brief Sends a general message to a port. No timestamps
+ * @param buf [in] Pointer to the data buffer
+ * @param len Size of the message
+ * @param mcast_type Enumeration
+ * MulticastType (pdelay, none or other). Depracated.
+ * @param destIdentity Destination port identity
+ * @return void
+ */
+ virtual void sendGeneralPort
+ (uint16_t etherType, uint8_t * buf, int len, MulticastType mcast_type,
+ PortIdentity * destIdentity) = 0;
+};
+
+#endif/*COMMON_PORT_HPP*/
diff --git a/daemons/gptp/common/ether_port.cpp b/daemons/gptp/common/ether_port.cpp
new file mode 100644
index 00000000..83400285
--- /dev/null
+++ b/daemons/gptp/common/ether_port.cpp
@@ -0,0 +1,908 @@
+/******************************************************************************
+
+ Copyright (c) 2009-2012, Intel Corporation
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+******************************************************************************/
+
+#include <ieee1588.hpp>
+
+#include <ether_port.hpp>
+#include <avbts_message.hpp>
+#include <avbts_clock.hpp>
+
+#include <avbts_oslock.hpp>
+#include <avbts_osnet.hpp>
+#include <avbts_oscondition.hpp>
+
+#include <gptp_log.hpp>
+
+#include <stdio.h>
+
+#include <math.h>
+
+#include <stdlib.h>
+
+LinkLayerAddress EtherPort::other_multicast(OTHER_MULTICAST);
+LinkLayerAddress EtherPort::pdelay_multicast(PDELAY_MULTICAST);
+LinkLayerAddress EtherPort::test_status_multicast
+( TEST_STATUS_MULTICAST );
+
+OSThreadExitCode watchNetLinkWrapper(void *arg)
+{
+ EtherPort *port;
+
+ port = (EtherPort *) arg;
+ if (port->watchNetLink() == NULL)
+ return osthread_ok;
+ else
+ return osthread_error;
+}
+
+OSThreadExitCode openPortWrapper(void *arg)
+{
+ EtherPort *port;
+
+ port = (EtherPort *) arg;
+ if (port->openPort(port) == NULL)
+ return osthread_ok;
+ else
+ return osthread_error;
+}
+
+EtherPort::~EtherPort()
+{
+ delete port_ready_condition;
+}
+
+EtherPort::EtherPort( PortInit_t *portInit ) :
+ CommonPort( portInit )
+{
+ automotive_profile = portInit->automotive_profile;
+ linkUp = portInit->linkUp;
+ setTestMode( portInit->testMode );
+
+ pdelay_sequence_id = 0;
+
+ pdelay_started = false;
+ pdelay_halted = false;
+ sync_rate_interval_timer_started = false;
+
+ duplicate_resp_counter = 0;
+ last_invalid_seqid = 0;
+
+ initialLogPdelayReqInterval = portInit->initialLogPdelayReqInterval;
+ operLogPdelayReqInterval = portInit->operLogPdelayReqInterval;
+ operLogSyncInterval = portInit->operLogSyncInterval;
+
+ if (automotive_profile) {
+ setAsCapable( true );
+
+ if (getInitSyncInterval() == LOG2_INTERVAL_INVALID)
+ setInitSyncInterval( -5 ); // 31.25 ms
+ if (initialLogPdelayReqInterval == LOG2_INTERVAL_INVALID)
+ initialLogPdelayReqInterval = 0; // 1 second
+ if (operLogPdelayReqInterval == LOG2_INTERVAL_INVALID)
+ operLogPdelayReqInterval = 0; // 1 second
+ if (operLogSyncInterval == LOG2_INTERVAL_INVALID)
+ operLogSyncInterval = 0; // 1 second
+ }
+ else {
+ setAsCapable( false );
+
+ if ( getInitSyncInterval() == LOG2_INTERVAL_INVALID )
+ setInitSyncInterval( -3 ); // 125 ms
+ if (initialLogPdelayReqInterval == LOG2_INTERVAL_INVALID)
+ initialLogPdelayReqInterval = 0; // 1 second
+ if (operLogPdelayReqInterval == LOG2_INTERVAL_INVALID)
+ operLogPdelayReqInterval = 0; // 1 second
+ if (operLogSyncInterval == LOG2_INTERVAL_INVALID)
+ operLogSyncInterval = 0; // 1 second
+ }
+
+ /*TODO: Add intervals below to a config interface*/
+ log_min_mean_pdelay_req_interval = initialLogPdelayReqInterval;
+
+ last_sync = NULL;
+ last_pdelay_req = NULL;
+ last_pdelay_resp = NULL;
+ last_pdelay_resp_fwup = NULL;
+
+ setPdelayCount(0);
+ setSyncCount(0);
+
+ if (automotive_profile) {
+ if (isGM) {
+ avbSyncState = 1;
+ }
+ else {
+ avbSyncState = 2;
+ }
+ if (getTestMode())
+ {
+ linkUpCount = 1; // TODO : really should check the current linkup status http://stackoverflow.com/questions/15723061/how-to-check-if-interface-is-up
+ linkDownCount = 0;
+ }
+ setStationState(STATION_STATE_RESERVED);
+ }
+}
+
+bool EtherPort::_init_port( void )
+{
+ pdelay_rx_lock = lock_factory->createLock(oslock_recursive);
+ port_tx_lock = lock_factory->createLock(oslock_recursive);
+
+ pDelayIntervalTimerLock = lock_factory->createLock(oslock_recursive);
+
+ port_ready_condition = condition_factory->createCondition();
+
+ return true;
+}
+
+void EtherPort::startPDelay()
+{
+ if(!pdelayHalted()) {
+ if (automotive_profile) {
+ if (log_min_mean_pdelay_req_interval != PTPMessageSignalling::sigMsgInterval_NoSend) {
+ long long unsigned int waitTime;
+ waitTime = ((long long) (pow((double)2, log_min_mean_pdelay_req_interval) * 1000000000.0));
+ waitTime = waitTime > EVENT_TIMER_GRANULARITY ? waitTime : EVENT_TIMER_GRANULARITY;
+ pdelay_started = true;
+ startPDelayIntervalTimer(waitTime);
+ }
+ }
+ else {
+ pdelay_started = true;
+ startPDelayIntervalTimer(32000000);
+ }
+ }
+}
+
+void EtherPort::stopPDelay()
+{
+ haltPdelay(true);
+ pdelay_started = false;
+ clock->deleteEventTimerLocked( this, PDELAY_INTERVAL_TIMEOUT_EXPIRES);
+}
+
+void EtherPort::startSyncRateIntervalTimer()
+{
+ if (automotive_profile) {
+ sync_rate_interval_timer_started = true;
+ if (isGM) {
+ // GM will wait up to 8 seconds for signaling rate
+ // TODO: This isn't according to spec but set because it is believed that some slave devices aren't signalling
+ // to reduce the rate
+ clock->addEventTimerLocked( this, SYNC_RATE_INTERVAL_TIMEOUT_EXPIRED, 8000000000 );
+ }
+ else {
+ // Slave will time out after 4 seconds
+ clock->addEventTimerLocked( this, SYNC_RATE_INTERVAL_TIMEOUT_EXPIRED, 4000000000 );
+ }
+ }
+}
+
+void *EtherPort::openPort( EtherPort *port )
+{
+ port_ready_condition->signal();
+ struct phy_delay get_delay = { 0, 0, 0, 0 };
+ if(port->_hw_timestamper)
+ port->_hw_timestamper->get_phy_delay(&get_delay);
+
+ while (1) {
+ PTPMessageCommon *msg;
+ uint8_t buf[128];
+ LinkLayerAddress remote;
+ net_result rrecv;
+ size_t length = sizeof(buf);
+
+ if ((rrecv = recv(&remote, buf, length,&get_delay))
+ == net_succeed)
+ {
+ GPTP_LOG_VERBOSE("Processing network buffer");
+ msg = buildPTPMessage((char *)buf, (int)length, &remote,
+ this);
+ if (msg != NULL) {
+ GPTP_LOG_VERBOSE("Processing message");
+ msg->processMessage(this);
+ if (msg->garbage()) {
+ delete msg;
+ }
+ } else {
+ GPTP_LOG_ERROR("Discarding invalid message");
+ }
+ } else if (rrecv == net_fatal) {
+ GPTP_LOG_ERROR("read from network interface failed");
+ this->processEvent(FAULT_DETECTED);
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+net_result EtherPort::port_send
+( uint16_t etherType, uint8_t *buf, int size, MulticastType mcast_type,
+ PortIdentity *destIdentity, bool timestamp )
+{
+ LinkLayerAddress dest;
+
+ if (mcast_type != MCAST_NONE) {
+ if (mcast_type == MCAST_PDELAY) {
+ dest = pdelay_multicast;
+ }
+ else if (mcast_type == MCAST_TEST_STATUS) {
+ dest = test_status_multicast;
+ }
+ else {
+ dest = other_multicast;
+ }
+ } else {
+ mapSocketAddr(destIdentity, &dest);
+ }
+
+ return send(&dest, etherType, (uint8_t *) buf, size, timestamp);
+}
+
+void EtherPort::sendEventPort
+( uint16_t etherType, uint8_t * buf, int size, MulticastType mcast_type,
+ PortIdentity * destIdentity)
+{
+ net_result rtx = port_send(etherType, buf, size, mcast_type, destIdentity, true);
+ if (rtx != net_succeed) {
+ GPTP_LOG_ERROR("sendEventPort(): failure");
+ }
+
+ return;
+}
+
+void EtherPort::sendGeneralPort
+( uint16_t etherType, uint8_t *buf, int size, MulticastType mcast_type,
+ PortIdentity * destIdentity )
+{
+ net_result rtx = port_send(etherType, buf, size, mcast_type, destIdentity, false);
+ if (rtx != net_succeed) {
+ GPTP_LOG_ERROR("sendGeneralPort(): failure");
+ }
+
+ return;
+}
+
+bool EtherPort::_processEvent( Event e )
+{
+ bool ret;
+
+ switch (e) {
+ case POWERUP:
+ case INITIALIZE:
+ if (!automotive_profile) {
+ if ( getPortState() != PTP_SLAVE &&
+ getPortState() != PTP_MASTER )
+ {
+ GPTP_LOG_STATUS("Starting PDelay");
+ startPDelay();
+ }
+ }
+ else {
+ startPDelay();
+ }
+
+ port_ready_condition->wait_prelock();
+
+ if( !linkWatch(watchNetLinkWrapper, (void *)this) )
+ {
+ GPTP_LOG_ERROR("Error creating port link thread");
+ ret = false;
+ break;
+ }
+
+ if( !linkOpen(openPortWrapper, (void *)this) )
+ {
+ GPTP_LOG_ERROR("Error creating port thread");
+ ret = false;
+ break;
+ }
+
+ port_ready_condition->wait();
+
+ if (automotive_profile) {
+ setStationState(STATION_STATE_ETHERNET_READY);
+ if (getTestMode())
+ {
+ APMessageTestStatus *testStatusMsg = new APMessageTestStatus(this);
+ if (testStatusMsg) {
+ testStatusMsg->sendPort(this);
+ delete testStatusMsg;
+ }
+ }
+ if (!isGM) {
+ // Send an initial signalling message
+ PTPMessageSignalling *sigMsg = new PTPMessageSignalling(this);
+ if (sigMsg) {
+ sigMsg->setintervals(PTPMessageSignalling::sigMsgInterval_NoSend, getSyncInterval(), PTPMessageSignalling::sigMsgInterval_NoSend);
+ sigMsg->sendPort(this, NULL);
+ delete sigMsg;
+ }
+
+ startSyncReceiptTimer((unsigned long long)
+ (SYNC_RECEIPT_TIMEOUT_MULTIPLIER *
+ ((double) pow((double)2, getSyncInterval()) *
+ 1000000000.0)));
+ }
+ }
+
+ ret = true;
+ break;
+ case STATE_CHANGE_EVENT:
+ // If the automotive profile is enabled, handle the event by
+ // doing nothing and returning true, preventing the default
+ // action from executing
+ if( automotive_profile )
+ ret = true;
+ else
+ ret = false;
+
+ break;
+ case LINKUP:
+ haltPdelay(false);
+ startPDelay();
+ if (automotive_profile) {
+ GPTP_LOG_EXCEPTION("LINKUP");
+ }
+ else {
+ GPTP_LOG_STATUS("LINKUP");
+ }
+
+ if (automotive_profile) {
+ setAsCapable( true );
+
+ setStationState(STATION_STATE_ETHERNET_READY);
+ if (getTestMode())
+ {
+ APMessageTestStatus *testStatusMsg = new APMessageTestStatus(this);
+ if (testStatusMsg) {
+ testStatusMsg->sendPort(this);
+ delete testStatusMsg;
+ }
+ }
+
+ resetInitSyncInterval();
+ setAnnounceInterval( 0 );
+ log_min_mean_pdelay_req_interval = initialLogPdelayReqInterval;
+
+ if (!isGM) {
+ // Send an initial signaling message
+ PTPMessageSignalling *sigMsg = new PTPMessageSignalling(this);
+ if (sigMsg) {
+ sigMsg->setintervals(PTPMessageSignalling::sigMsgInterval_NoSend, getSyncInterval(), PTPMessageSignalling::sigMsgInterval_NoSend);
+ sigMsg->sendPort(this, NULL);
+ delete sigMsg;
+ }
+
+ startSyncReceiptTimer((unsigned long long)
+ (SYNC_RECEIPT_TIMEOUT_MULTIPLIER *
+ ((double) pow((double)2, getSyncInterval()) *
+ 1000000000.0)));
+ }
+
+ // Reset Sync count and pdelay count
+ setPdelayCount(0);
+ setSyncCount(0);
+
+ // Start AVB SYNC at 2. It will decrement after each sync. When it reaches 0 the Test Status message
+ // can be sent
+ if (isGM) {
+ avbSyncState = 1;
+ }
+ else {
+ avbSyncState = 2;
+ }
+
+ if (getTestMode())
+ {
+ linkUpCount++;
+ }
+ }
+ this->timestamper_reset();
+
+ ret = true;
+ break;
+ case LINKDOWN:
+ stopPDelay();
+ if (automotive_profile) {
+ GPTP_LOG_EXCEPTION("LINK DOWN");
+ }
+ else {
+ setAsCapable(false);
+ GPTP_LOG_STATUS("LINK DOWN");
+ }
+ if (getTestMode())
+ {
+ linkDownCount++;
+ }
+
+ ret = true;
+ break;
+ case ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES:
+ case SYNC_RECEIPT_TIMEOUT_EXPIRES:
+ if( !automotive_profile )
+ {
+ ret = false;
+ break;
+ }
+
+ // Automotive Profile specific action
+ if (e == SYNC_RECEIPT_TIMEOUT_EXPIRES) {
+ GPTP_LOG_EXCEPTION("SYNC receipt timeout");
+
+ startSyncReceiptTimer((unsigned long long)
+ (SYNC_RECEIPT_TIMEOUT_MULTIPLIER *
+ ((double) pow((double)2, getSyncInterval()) *
+ 1000000000.0)));
+ }
+ ret = true;
+ break;
+ case PDELAY_INTERVAL_TIMEOUT_EXPIRES:
+ GPTP_LOG_DEBUG("PDELAY_INTERVAL_TIMEOUT_EXPIRES occured");
+ {
+ int ts_good;
+ Timestamp req_timestamp;
+ int iter = TX_TIMEOUT_ITER;
+ long req = TX_TIMEOUT_BASE;
+ unsigned req_timestamp_counter_value;
+ long long wait_time = 0;
+
+ PTPMessagePathDelayReq *pdelay_req =
+ new PTPMessagePathDelayReq(this);
+ PortIdentity dest_id;
+ getPortIdentity(dest_id);
+ pdelay_req->setPortIdentity(&dest_id);
+
+ {
+ Timestamp pending =
+ PDELAY_PENDING_TIMESTAMP;
+ pdelay_req->setTimestamp(pending);
+ }
+
+ if (last_pdelay_req != NULL) {
+ delete last_pdelay_req;
+ }
+ setLastPDelayReq(pdelay_req);
+
+ getTxLock();
+ pdelay_req->sendPort(this, NULL);
+ GPTP_LOG_DEBUG("*** Sent PDelay Request message");
+
+ OSTimer *timer = timer_factory->createTimer();
+
+ ts_good = getTxTimestamp
+ (pdelay_req, req_timestamp, req_timestamp_counter_value, false);
+ while (ts_good != GPTP_EC_SUCCESS && iter-- != 0) {
+ timer->sleep(req);
+ wait_time += req;
+ if (ts_good != GPTP_EC_EAGAIN && iter < 1)
+ GPTP_LOG_ERROR(
+ "Error (TX) timestamping PDelay request "
+ "(Retrying-%d), error=%d", iter, ts_good);
+ ts_good =
+ getTxTimestamp
+ (pdelay_req, req_timestamp,
+ req_timestamp_counter_value, iter == 0);
+ req *= 2;
+ }
+ delete timer;
+ putTxLock();
+
+ if (ts_good == GPTP_EC_SUCCESS) {
+ pdelay_req->setTimestamp(req_timestamp);
+ GPTP_LOG_DEBUG(
+ "PDelay Request message, Timestamp %u (sec) %u (ns), seqID %u",
+ req_timestamp.seconds_ls, req_timestamp.nanoseconds,
+ pdelay_req->getSequenceId());
+ } else {
+ Timestamp failed = INVALID_TIMESTAMP;
+ pdelay_req->setTimestamp(failed);
+ GPTP_LOG_ERROR( "Invalid TX" );
+ }
+
+ if (ts_good != GPTP_EC_SUCCESS) {
+ char msg
+ [HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE];
+ getExtendedError(msg);
+ GPTP_LOG_ERROR(
+ "Error (TX) timestamping PDelay request, error=%d\t%s",
+ ts_good, msg);
+ }
+
+ {
+ long long timeout;
+ long long interval;
+
+ timeout = PDELAY_RESP_RECEIPT_TIMEOUT_MULTIPLIER *
+ ((long long)
+ (pow((double)2,getPDelayInterval())*1000000000.0)) -
+ wait_time*1000;
+ timeout = timeout > EVENT_TIMER_GRANULARITY ?
+ timeout : EVENT_TIMER_GRANULARITY;
+ clock->addEventTimerLocked
+ (this, PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES, timeout );
+ GPTP_LOG_DEBUG("Schedule PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES, "
+ "PDelay interval %d, wait_time %lld, timeout %lld",
+ getPDelayInterval(), wait_time, timeout);
+
+ interval =
+ ((long long)
+ (pow((double)2,getPDelayInterval())*1000000000.0)) -
+ wait_time*1000;
+ interval = interval > EVENT_TIMER_GRANULARITY ?
+ interval : EVENT_TIMER_GRANULARITY;
+ startPDelayIntervalTimer(interval);
+ }
+ }
+ break;
+ case SYNC_INTERVAL_TIMEOUT_EXPIRES:
+ {
+ /* Set offset from master to zero, update device vs
+ system time offset */
+
+ // Send a sync message and then a followup to broadcast
+ PTPMessageSync *sync = new PTPMessageSync(this);
+ PortIdentity dest_id;
+ getPortIdentity(dest_id);
+ sync->setPortIdentity(&dest_id);
+ getTxLock();
+ sync->sendPort(this, NULL);
+ GPTP_LOG_DEBUG("Sent SYNC message");
+
+ if ( automotive_profile &&
+ getPortState() == PTP_MASTER )
+ {
+ if (avbSyncState > 0) {
+ avbSyncState--;
+ if (avbSyncState == 0) {
+ // Send Avnu Automotive Profile status message
+ setStationState(STATION_STATE_AVB_SYNC);
+ if (getTestMode()) {
+ APMessageTestStatus *testStatusMsg = new APMessageTestStatus(this);
+ if (testStatusMsg) {
+ testStatusMsg->sendPort(this);
+ delete testStatusMsg;
+ }
+ }
+ }
+ }
+ }
+
+ int ts_good;
+ Timestamp sync_timestamp;
+ unsigned sync_timestamp_counter_value;
+ int iter = TX_TIMEOUT_ITER;
+ long req = TX_TIMEOUT_BASE;
+
+ OSTimer *timer = timer_factory->createTimer();
+
+ ts_good = getTxTimestamp( sync, sync_timestamp,
+ sync_timestamp_counter_value,
+ false );
+ while (ts_good != GPTP_EC_SUCCESS && iter-- != 0) {
+ timer->sleep(req);
+
+ if (ts_good != GPTP_EC_EAGAIN && iter < 1)
+ GPTP_LOG_ERROR(
+ "Error (TX) timestamping Sync (Retrying), "
+ "error=%d", ts_good);
+ ts_good =
+ getTxTimestamp
+ (sync, sync_timestamp,
+ sync_timestamp_counter_value, iter == 0);
+ req *= 2;
+ }
+ delete timer;
+ putTxLock();
+
+ if (ts_good != GPTP_EC_SUCCESS) {
+ char msg [HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE];
+ getExtendedError(msg);
+ GPTP_LOG_ERROR(
+ "Error (TX) timestamping Sync, error="
+ "%d\n%s",
+ ts_good, msg );
+ }
+
+ if (ts_good == GPTP_EC_SUCCESS) {
+ GPTP_LOG_VERBOSE("Successful Sync timestamp");
+ GPTP_LOG_VERBOSE("Seconds: %u",
+ sync_timestamp.seconds_ls);
+ GPTP_LOG_VERBOSE("Nanoseconds: %u",
+ sync_timestamp.nanoseconds);
+ } else {
+ GPTP_LOG_ERROR
+ ("*** Unsuccessful Sync timestamp");
+ }
+
+ PTPMessageFollowUp *follow_up;
+ if (ts_good == GPTP_EC_SUCCESS) {
+
+ follow_up =
+ new PTPMessageFollowUp(this);
+ PortIdentity dest_id;
+ getPortIdentity(dest_id);
+
+ follow_up->setClockSourceTime(getClock()->getFUPInfo());
+ follow_up->setPortIdentity(&dest_id);
+ follow_up->setSequenceId(sync->getSequenceId());
+ follow_up->setPreciseOriginTimestamp(sync_timestamp);
+ follow_up->sendPort(this, NULL);
+ delete follow_up;
+ } else {
+ }
+ delete sync;
+
+ }
+ break;
+ case FAULT_DETECTED:
+ GPTP_LOG_ERROR("Received FAULT_DETECTED event");
+ if (!automotive_profile) {
+ setAsCapable(false);
+ }
+ break;
+ case PDELAY_DEFERRED_PROCESSING:
+ GPTP_LOG_DEBUG("PDELAY_DEFERRED_PROCESSING occured");
+ pdelay_rx_lock->lock();
+ if (last_pdelay_resp_fwup == NULL) {
+ GPTP_LOG_ERROR("PDelay Response Followup is NULL!");
+ abort();
+ }
+ last_pdelay_resp_fwup->processMessage(this);
+ if (last_pdelay_resp_fwup->garbage()) {
+ delete last_pdelay_resp_fwup;
+ this->setLastPDelayRespFollowUp(NULL);
+ }
+ pdelay_rx_lock->unlock();
+ break;
+ case PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES:
+ if (!automotive_profile) {
+ GPTP_LOG_EXCEPTION("PDelay Response Receipt Timeout");
+ setAsCapable(false);
+ }
+ setPdelayCount( 0 );
+ break;
+
+ case PDELAY_RESP_PEER_MISBEHAVING_TIMEOUT_EXPIRES:
+ GPTP_LOG_EXCEPTION("PDelay Resp Peer Misbehaving timeout expired! Restarting PDelay");
+
+ haltPdelay(false);
+ if( getPortState() != PTP_SLAVE &&
+ getPortState() != PTP_MASTER )
+ {
+ GPTP_LOG_STATUS("Starting PDelay" );
+ startPDelay();
+ }
+ break;
+ case SYNC_RATE_INTERVAL_TIMEOUT_EXPIRED:
+ {
+ GPTP_LOG_INFO("SYNC_RATE_INTERVAL_TIMEOUT_EXPIRED occured");
+
+ sync_rate_interval_timer_started = false;
+
+ bool sendSignalMessage = false;
+ if ( getSyncInterval() != operLogSyncInterval )
+ {
+ setSyncInterval( operLogSyncInterval );
+ sendSignalMessage = true;
+ }
+
+ if (log_min_mean_pdelay_req_interval != operLogPdelayReqInterval) {
+ log_min_mean_pdelay_req_interval = operLogPdelayReqInterval;
+ sendSignalMessage = true;
+ }
+
+ if (sendSignalMessage) {
+ if (!isGM) {
+ // Send operational signalling message
+ PTPMessageSignalling *sigMsg = new PTPMessageSignalling(this);
+ if (sigMsg) {
+ if (automotive_profile)
+ sigMsg->setintervals(PTPMessageSignalling::sigMsgInterval_NoChange, getSyncInterval(), PTPMessageSignalling::sigMsgInterval_NoChange);
+ else
+ sigMsg->setintervals(log_min_mean_pdelay_req_interval, getSyncInterval(), PTPMessageSignalling::sigMsgInterval_NoChange);
+ sigMsg->sendPort(this, NULL);
+ delete sigMsg;
+ }
+
+ startSyncReceiptTimer((unsigned long long)
+ (SYNC_RECEIPT_TIMEOUT_MULTIPLIER *
+ ((double) pow((double)2, getSyncInterval()) *
+ 1000000000.0)));
+ }
+ }
+ }
+
+ break;
+ default:
+ GPTP_LOG_ERROR
+ ( "Unhandled event type in "
+ "EtherPort::processEvent(), %d", e );
+ ret = false;
+ break;
+ }
+
+ return ret;
+}
+
+void EtherPort::recoverPort( void )
+{
+ return;
+}
+
+void EtherPort::becomeMaster( bool annc ) {
+ setPortState( PTP_MASTER );
+ // Stop announce receipt timeout timer
+ clock->deleteEventTimerLocked( this, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES );
+
+ // Stop sync receipt timeout timer
+ stopSyncReceiptTimer();
+
+ if( annc ) {
+ if (!automotive_profile) {
+ startAnnounce();
+ }
+ }
+ startSyncIntervalTimer(16000000);
+ GPTP_LOG_STATUS("Switching to Master" );
+
+ clock->updateFUPInfo();
+
+ return;
+}
+
+void EtherPort::becomeSlave( bool restart_syntonization ) {
+ clock->deleteEventTimerLocked( this, ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES );
+ clock->deleteEventTimerLocked( this, SYNC_INTERVAL_TIMEOUT_EXPIRES );
+
+ setPortState( PTP_SLAVE );
+
+ if (!automotive_profile) {
+ clock->addEventTimerLocked
+ (this, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES,
+ (ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER*
+ (unsigned long long)
+ (pow((double)2,getAnnounceInterval())*1000000000.0)));
+ }
+
+ GPTP_LOG_STATUS("Switching to Slave" );
+ if( restart_syntonization ) clock->newSyntonizationSetPoint();
+
+ getClock()->updateFUPInfo();
+
+ return;
+}
+
+void EtherPort::mapSocketAddr
+( PortIdentity *destIdentity, LinkLayerAddress *remote )
+{
+ *remote = identity_map[*destIdentity];
+ return;
+}
+
+void EtherPort::addSockAddrMap
+( PortIdentity *destIdentity, LinkLayerAddress *remote )
+{
+ identity_map[*destIdentity] = *remote;
+ return;
+}
+
+int EtherPort::getTxTimestamp
+( PTPMessageCommon *msg, Timestamp &timestamp, unsigned &counter_value,
+ bool last )
+{
+ PortIdentity identity;
+ msg->getPortIdentity(&identity);
+ return getTxTimestamp
+ (&identity, msg->getMessageId(), timestamp, counter_value, last);
+}
+
+int EtherPort::getRxTimestamp
+( PTPMessageCommon * msg, Timestamp & timestamp, unsigned &counter_value,
+ bool last )
+{
+ PortIdentity identity;
+ msg->getPortIdentity(&identity);
+ return getRxTimestamp
+ (&identity, msg->getMessageId(), timestamp, counter_value, last);
+}
+
+int EtherPort::getTxTimestamp
+(PortIdentity *sourcePortIdentity, PTPMessageId messageId,
+ Timestamp &timestamp, unsigned &counter_value, bool last )
+{
+ if (_hw_timestamper) {
+ return _hw_timestamper->HWTimestamper_txtimestamp
+ (sourcePortIdentity, messageId, timestamp, counter_value,
+ last);
+ }
+ timestamp = clock->getSystemTime();
+ return 0;
+}
+
+int EtherPort::getRxTimestamp
+( PortIdentity * sourcePortIdentity, PTPMessageId messageId,
+ Timestamp &timestamp, unsigned &counter_value, bool last )
+{
+ if (_hw_timestamper) {
+ return _hw_timestamper->HWTimestamper_rxtimestamp
+ (sourcePortIdentity, messageId, timestamp, counter_value,
+ last);
+ }
+ timestamp = clock->getSystemTime();
+ return 0;
+}
+
+void EtherPort::startPDelayIntervalTimer
+( long long unsigned int waitTime )
+{
+ pDelayIntervalTimerLock->lock();
+ clock->deleteEventTimerLocked(this, PDELAY_INTERVAL_TIMEOUT_EXPIRES);
+ clock->addEventTimerLocked(this, PDELAY_INTERVAL_TIMEOUT_EXPIRES, waitTime);
+ pDelayIntervalTimerLock->unlock();
+}
+
+void EtherPort::syncDone() {
+ GPTP_LOG_VERBOSE("Sync complete");
+
+ if (automotive_profile && getPortState() == PTP_SLAVE) {
+ if (avbSyncState > 0) {
+ avbSyncState--;
+ if (avbSyncState == 0) {
+ setStationState(STATION_STATE_AVB_SYNC);
+ if (getTestMode()) {
+ APMessageTestStatus *testStatusMsg =
+ new APMessageTestStatus(this);
+ if (testStatusMsg) {
+ testStatusMsg->sendPort(this);
+ delete testStatusMsg;
+ }
+ }
+ }
+ }
+ }
+
+ if (automotive_profile) {
+ if (!sync_rate_interval_timer_started) {
+ if ( getSyncInterval() != operLogSyncInterval )
+ {
+ startSyncRateIntervalTimer();
+ }
+ }
+ }
+
+ if( !pdelay_started ) {
+ startPDelay();
+ }
+}
diff --git a/daemons/gptp/common/ether_port.hpp b/daemons/gptp/common/ether_port.hpp
new file mode 100644
index 00000000..6028ca75
--- /dev/null
+++ b/daemons/gptp/common/ether_port.hpp
@@ -0,0 +1,624 @@
+/******************************************************************************
+
+ Copyright (c) 2009-2012, Intel Corporation
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+******************************************************************************/
+
+#ifndef ETHER_PORT_HPP
+#define ETHER_PORT_HPP
+
+#include <ieee1588.hpp>
+#include <avbap_message.hpp>
+
+#include <avbts_ostimer.hpp>
+#include <avbts_oslock.hpp>
+#include <avbts_osnet.hpp>
+#include <avbts_osthread.hpp>
+#include <avbts_oscondition.hpp>
+#include <ipcdef.hpp>
+#include <gptp_log.hpp>
+
+#include <stdint.h>
+
+#include <map>
+#include <list>
+
+#include <common_port.hpp>
+
+/**@file*/
+
+#define GPTP_MULTICAST 0x0180C200000EULL /*!< GPTP multicast adddress */
+#define PDELAY_MULTICAST GPTP_MULTICAST /*!< PDELAY Multicast value */
+#define OTHER_MULTICAST GPTP_MULTICAST /*!< OTHER multicast value */
+#define TEST_STATUS_MULTICAST 0x011BC50AC000ULL /*!< AVnu Automotive profile test status msg Multicast value */
+
+#define PDELAY_RESP_RECEIPT_TIMEOUT_MULTIPLIER 3 /*!< PDelay timeout multiplier*/
+#define SYNC_RECEIPT_TIMEOUT_MULTIPLIER 3 /*!< Sync receipt timeout multiplier*/
+#define ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER 3 /*!< Announce receipt timeout multiplier*/
+
+#define LOG2_INTERVAL_INVALID -127 /* Simple out of range Log base 2 value used for Sync and PDelay msg internvals */
+
+/**
+ * @brief PortType enumeration. Selects between delay request-response (E2E) mechanism
+ * or PTPV1 or PTPV2 P2P (peer delay) mechanism.
+ */
+typedef enum {
+ V1,
+ V2_E2E,
+ V2_P2P
+} PortType;
+
+/**
+ * @brief Provides a map for the identityMap member of EtherPort
+ * class
+ */
+typedef std::map < PortIdentity, LinkLayerAddress > IdentityMap_t;
+
+
+/**
+ * @brief Ethernet specific port functions
+ */
+class EtherPort : public CommonPort
+{
+ static LinkLayerAddress other_multicast;
+ static LinkLayerAddress pdelay_multicast;
+ static LinkLayerAddress test_status_multicast;
+
+ /* Port Status */
+ // set to 0 when asCapable is false, increment for each pdelay recvd
+ bool linkUp;
+
+ /* Port Configuration */
+ char log_mean_unicast_sync_interval;
+ char log_min_mean_delay_req_interval;
+ char log_min_mean_pdelay_req_interval;
+
+ unsigned int duplicate_resp_counter;
+ uint16_t last_invalid_seqid;
+
+ /* Automotive Profile : Static variables */
+ // port_state : already defined as port_state
+ bool isGM;
+ // asCapable : already defined as asCapable
+ char operLogPdelayReqInterval;
+ char operLogSyncInterval;
+ char initialLogPdelayReqInterval;
+ bool automotive_profile;
+
+ // Test Status variables
+ uint32_t linkUpCount;
+ uint32_t linkDownCount;
+ StationState_t stationState;
+
+
+ /* Automotive Profile : Persistant variables */
+ // neighborPropDelay : defined as one_way_delay ??
+ // rateRatio : Optional and didn't fine this variable. Will proceed without writing it.
+ // neighborRateRatio : defined as _peer_rate_offset ??
+
+ // Automotive Profile AVB SYNC state indicator. > 0 will inditate valid AVB SYNC state
+ uint32_t avbSyncState;
+
+ uint16_t pdelay_sequence_id;
+ PTPMessagePathDelayReq *last_pdelay_req;
+ PTPMessagePathDelayResp *last_pdelay_resp;
+ PTPMessagePathDelayRespFollowUp *last_pdelay_resp_fwup;
+
+ IdentityMap_t identity_map;
+
+ PTPMessageSync *last_sync;
+
+ OSCondition *port_ready_condition;
+
+ OSLock *pdelay_rx_lock;
+ OSLock *port_tx_lock;
+
+ OSLock *pDelayIntervalTimerLock;
+
+ net_result port_send
+ (uint16_t etherType, uint8_t * buf, int size, MulticastType mcast_type,
+ PortIdentity * destIdentity, bool timestamp);
+
+ bool pdelay_started;
+ bool pdelay_halted;
+ bool sync_rate_interval_timer_started;
+
+protected:
+ static const unsigned int DUPLICATE_RESP_THRESH = 3;
+
+ public:
+ void becomeMaster( bool annc );
+ void becomeSlave( bool restart_syntonization );
+
+ /**
+ * @brief Starts pDelay event timer.
+ * @return void
+ */
+ void startPDelay();
+
+ /**
+ * @brief Stops PDelay event timer
+ * @return void
+ */
+ void stopPDelay();
+
+ /**
+ * @brief Enable/Disable PDelay Request messages
+ * @param hlt True to HALT (stop sending), False to resume (start sending).
+ */
+ void haltPdelay(bool hlt)
+ {
+ pdelay_halted = hlt;
+ }
+
+ /**
+ * @brief Get the status of pdelayHalted condition.
+ * @return True PdelayRequest halted. False when PDelay Request is running
+ */
+ bool pdelayHalted(void)
+ {
+ return pdelay_halted;
+ }
+
+ /**
+ * @brief Starts Sync Rate Interval event timer. Used for the
+ * Automotive Profile.
+ * @return void
+ */
+ void startSyncRateIntervalTimer();
+
+ /**
+ * @brief Starts pDelay event timer if not yet started.
+ * @return void
+ */
+ void syncDone();
+
+ /**
+ * @brief Gets the AVnu automotive profile flag
+ * @return automotive_profile flag
+ */
+ bool getAutomotiveProfile() { return( automotive_profile ); }
+
+ /**
+ * @brief Destroys a EtherPort
+ */
+ ~EtherPort();
+
+ /**
+ * @brief Creates the EtherPort interface.
+ * @param init PortInit initialization parameters
+ */
+ EtherPort( PortInit_t *portInit );
+
+ /**
+ * @brief Initializes the port. Creates network interface, initializes
+ * hardware timestamper and create OS locks conditions
+ * @return FALSE if error during building the interface. TRUE if success
+ */
+ bool _init_port( void );
+
+ /**
+ * @brief Currently doesnt do anything. Just returns.
+ * @return void
+ */
+ void recoverPort(void);
+
+ /**
+ * @brief Receives messages from the network interface
+ * @return Its an infinite loop. Returns NULL in case of error.
+ */
+ void *openPort( EtherPort *port );
+
+ /**
+ * @brief Sends and event to a IEEE1588 port. It includes timestamp
+ * @param buf [in] Pointer to the data buffer
+ * @param len Size of the message
+ * @param mcast_type Enumeration MulticastType (pdlay, none or other). Depracated.
+ * @param destIdentity Destination port identity
+ * @return void
+ */
+ void sendEventPort
+ (uint16_t etherType, uint8_t * buf, int len, MulticastType mcast_type,
+ PortIdentity * destIdentity);
+
+ /**
+ * @brief Sends a general message to a port. No timestamps
+ * @param buf [in] Pointer to the data buffer
+ * @param len Size of the message
+ * @param mcast_type Enumeration MulticastType (pdelay, none or other). Depracated.
+ * @param destIdentity Destination port identity
+ * @return void
+ */
+ void sendGeneralPort
+ (uint16_t etherType, uint8_t * buf, int len, MulticastType mcast_type,
+ PortIdentity * destIdentity);
+
+ /**
+ * @brief Process all events for a EtherPort
+ * @param e Event to be processed
+ * @return true if event is handled, false otherwise
+ */
+ bool _processEvent(Event e);
+
+ /**
+ * @brief Adds a foreign master.
+ * @param msg [in] PTP announce message
+ * @return void
+ * @todo Currently not implemented
+ */
+ void addForeignMaster(PTPMessageAnnounce * msg);
+
+ /**
+ * @brief Remove a foreign master.
+ * @param msg [in] PTP announce message
+ * @return void
+ * @todo Currently not implemented
+ */
+ void removeForeignMaster(PTPMessageAnnounce * msg);
+
+ /**
+ * @brief Remove all foreign masters.
+ * @return void
+ * @todo Currently not implemented
+ */
+ void removeForeignMasterAll(void);
+
+ /**
+ * @brief Gets the pDelay minimum interval
+ * @return PDelay interval
+ */
+ char getPDelayInterval(void) {
+ return log_min_mean_pdelay_req_interval;
+ }
+
+ /**
+ * @brief Sets the pDelay minimum interval
+ * @param val time interval
+ * @return none
+ */
+ void setPDelayInterval(char val) {
+ log_min_mean_pdelay_req_interval = val;
+ }
+
+ /**
+ * @brief Sets the pDelay minimum interval back to initial
+ * value
+ * @return none */
+ void setInitPDelayInterval(void) {
+ log_min_mean_pdelay_req_interval = initialLogPdelayReqInterval;
+ }
+
+ /**
+ * @brief Start pDelay interval timer
+ * @param waitTime time interval
+ * @return none
+ */
+ void startPDelayIntervalTimer(long long unsigned int waitTime);
+
+ /**
+ * @brief Increments PDelay sequence ID and returns.
+ * @return Next PDelay sequence id.
+ */
+ uint16_t getNextPDelaySequenceId(void) {
+ return pdelay_sequence_id++;
+ }
+
+ /**
+ * @brief Gets last sync sequence number from parent
+ * @return Parent last sync sequence number
+ * @todo Not currently implemented.
+ */
+ uint16_t getParentLastSyncSequenceNumber(void);
+
+ /**
+ * @brief Sets last sync sequence number from parent
+ * @param num Sequence number
+ * @return void
+ * @todo Currently not implemented.
+ */
+ void setParentLastSyncSequenceNumber(uint16_t num);
+
+ /**
+ * @brief Sets last sync ptp message
+ * @param msg [in] PTP sync message
+ * @return void
+ */
+ void setLastSync(PTPMessageSync * msg) {
+ last_sync = msg;
+ }
+
+ /**
+ * @brief Gets last sync message
+ * @return PTPMessageSync last sync
+ */
+ PTPMessageSync *getLastSync(void) {
+ return last_sync;
+ }
+
+ /**
+ * @brief Locks PDelay RX
+ * @return TRUE if acquired the lock. FALSE otherwise
+ */
+ bool getPDelayRxLock() {
+ return pdelay_rx_lock->lock() == oslock_ok ? true : false;
+ }
+
+ /**
+ * @brief Do a trylock on the PDelay RX
+ * @return TRUE if acquired the lock. FALSE otherwise.
+ */
+ bool tryPDelayRxLock() {
+ return pdelay_rx_lock->trylock() == oslock_ok ? true : false;
+ }
+
+ /**
+ * @brief Unlocks PDelay RX.
+ * @return TRUE if success. FALSE otherwise
+ */
+ bool putPDelayRxLock() {
+ return pdelay_rx_lock->unlock() == oslock_ok ? true : false;
+ }
+
+ bool getTxLock() {
+ return port_tx_lock->lock() == oslock_ok ? true : false;
+ }
+
+ bool putTxLock() {
+ return port_tx_lock->unlock() == oslock_ok ? true : false;
+ }
+
+ /**
+ * @brief Sets the last_pdelay_req message
+ * @param msg [in] PTPMessagePathDelayReq message to set
+ * @return void
+ */
+ void setLastPDelayReq(PTPMessagePathDelayReq * msg) {
+ last_pdelay_req = msg;
+ }
+
+ /**
+ * @brief Gets the last PTPMessagePathDelayReq message
+ * @return Last pdelay request
+ */
+ PTPMessagePathDelayReq *getLastPDelayReq(void) {
+ return last_pdelay_req;
+ }
+
+ /**
+ * @brief Sets the last PTPMessagePathDelayResp message
+ * @param msg [in] Last pdelay response
+ * @return void
+ */
+ void setLastPDelayResp(PTPMessagePathDelayResp * msg) {
+ last_pdelay_resp = msg;
+ }
+
+ /**
+ * @brief Gets the last PTPMessagePathDelayResp message
+ * @return Last pdelay response
+ */
+ PTPMessagePathDelayResp *getLastPDelayResp(void) {
+ return last_pdelay_resp;
+ }
+
+ /**
+ * @brief Sets the last PTPMessagePathDelayRespFollowUp message
+ * @param msg [in] last pdelay response follow up
+ * @return void
+ */
+ void setLastPDelayRespFollowUp(PTPMessagePathDelayRespFollowUp * msg) {
+ last_pdelay_resp_fwup = msg;
+ }
+
+ /**
+ * @brief Gets the last PTPMessagePathDelayRespFollowUp message
+ * @return last pdelay response follow up
+ */
+ PTPMessagePathDelayRespFollowUp *getLastPDelayRespFollowUp(void) {
+ return last_pdelay_resp_fwup;
+ }
+
+ /**
+ * @brief Gets RX timestamp based on port identity
+ * @param sourcePortIdentity [in] Source port identity
+ * @param sequenceId Sequence ID
+ * @param timestamp [out] RX timestamp
+ * @param counter_value [out] timestamp count value
+ * @param last If true, removes the rx lock.
+ * @return GPTP_EC_SUCCESS if no error, GPTP_EC_FAILURE if error and GPTP_EC_EAGAIN to try again.
+ */
+ int getRxTimestamp
+ (PortIdentity * sourcePortIdentity, PTPMessageId messageId,
+ Timestamp & timestamp, unsigned &counter_value, bool last);
+
+ /**
+ * @brief Gets TX timestamp based on port identity
+ * @param sourcePortIdentity [in] Source port identity
+ * @param sequenceId Sequence ID
+ * @param timestamp [out] TX timestamp
+ * @param counter_value [out] timestamp count value
+ * @param last If true, removes the TX lock
+ * @return GPTP_EC_SUCCESS if no error, GPTP_EC_FAILURE if error and GPTP_EC_EAGAIN to try again.
+ */
+ int getTxTimestamp
+ (PortIdentity * sourcePortIdentity, PTPMessageId messageId,
+ Timestamp & timestamp, unsigned &counter_value, bool last);
+
+ /**
+ * @brief Gets TX timestamp based on PTP message
+ * @param msg PTPMessageCommon message
+ * @param timestamp [out] TX timestamp
+ * @param counter_value [out] timestamp count value
+ * @param last If true, removes the TX lock
+ * @return GPTP_EC_SUCCESS if no error, GPTP_EC_FAILURE if error and GPTP_EC_EAGAIN to try again.
+ */
+ int getTxTimestamp
+ (PTPMessageCommon * msg, Timestamp & timestamp, unsigned &counter_value,
+ bool last);
+
+ /**
+ * @brief Gets RX timestamp based on PTP message
+ * @param msg PTPMessageCommon message
+ * @param timestamp [out] RX timestamp
+ * @param counter_value [out] timestamp count value
+ * @param last If true, removes the RX lock
+ * @return GPTP_EC_SUCCESS if no error, GPTP_EC_FAILURE if error and GPTP_EC_EAGAIN to try again.
+ */
+ int getRxTimestamp
+ (PTPMessageCommon * msg, Timestamp & timestamp, unsigned &counter_value,
+ bool last);
+
+ /**
+ * @brief Sets the value of last duplicated SeqID
+ * @param seqid Value to set
+ * @return void
+ */
+ void setLastInvalidSeqID(uint16_t seqid)
+ {
+ last_invalid_seqid = seqid;
+ }
+
+ /**
+ * @brief Get the value of last invalid seqID
+ * @return Last invalid seq id
+ */
+ uint16_t getLastInvalidSeqID(void)
+ {
+ return last_invalid_seqid;
+ }
+
+ /**
+ * @brief Sets the duplicate pdelay_resp counter.
+ * @param cnt Value to be set
+ */
+ void setDuplicateRespCounter(unsigned int cnt)
+ {
+ duplicate_resp_counter = cnt;
+ }
+
+ /**
+ * @brief Gets the current value of pdelay_resp duplicate messages counter
+ * @return Counter value
+ */
+ unsigned int getDuplicateRespCounter(void)
+ {
+ return duplicate_resp_counter;
+ }
+
+ /**
+ * @brief Increment the duplicate PDelayResp message counter
+ * @return True if it equals the threshold, False otherwise
+ */
+ bool incrementDuplicateRespCounter(void)
+ {
+ return ++duplicate_resp_counter == DUPLICATE_RESP_THRESH;
+ }
+
+ /**
+ * @brief Maps socket addr to the remote link layer address
+ * @param destIdentity [in] PortIdentity remote
+ * @param remote [in] remote link layer address
+ * @return void
+ */
+ void mapSocketAddr
+ (PortIdentity * destIdentity, LinkLayerAddress * remote);
+
+ /**
+ * @brief Adds New sock addr map
+ * @param destIdentity [in] PortIdentity remote
+ * @param remote [in] remote link layer address
+ * @return void
+ */
+ void addSockAddrMap
+ (PortIdentity * destIdentity, LinkLayerAddress * remote);
+
+ /**
+ * @brief Gets link up count
+ * @return Link up count
+ */
+ uint32_t getLinkUpCount() {
+ return linkUpCount;
+ }
+
+ /**
+ * @brief Gets link down count
+ * @return Link down count
+ */
+ uint32_t getLinkDownCount() {
+ return linkDownCount;
+ }
+
+ /**
+ * @brief Sets the Station State for the Test Status message
+ * @param StationState_t [in] The station state
+ * @return none
+ */
+ void setStationState(StationState_t _stationState) {
+ stationState = _stationState;
+ if (stationState == STATION_STATE_ETHERNET_READY) {
+ GPTP_LOG_STATUS("AVnu AP Status : STATION_STATE_ETHERNET_READY");
+ }
+ else if (stationState == STATION_STATE_AVB_SYNC) {
+ GPTP_LOG_STATUS("AVnu AP Status : STATION_STATE_AVB_SYNC");
+ }
+ else if (stationState == STATION_STATE_AVB_MEDIA_READY) {
+ GPTP_LOG_STATUS("AVnu AP Status : STATION_STATE_AVB_MEDIA_READY");
+ }
+ }
+
+ /**
+ * @brief Gets the Station State for the Test Status
+ * message
+ * @return station state
+ */
+ StationState_t getStationState() {
+ return stationState;
+ }
+
+
+ /**
+ * @brief Sets the linkUp status
+ * @param bool of the linkUp status
+ * @return void
+ */
+ void setLinkUpState(bool state) {
+ linkUp = state;
+ }
+
+ /**
+ * @brief Gets the linkUp status
+ * @return bool of the linkUp status
+ */
+ bool getLinkUpState(void) {
+ return linkUp;
+ }
+};
+
+#endif/*ETHER_PORT_HPP*/
diff --git a/daemons/gptp/common/ieee1588.hpp b/daemons/gptp/common/ieee1588.hpp
index 3d89a158..80242f6b 100644
--- a/daemons/gptp/common/ieee1588.hpp
+++ b/daemons/gptp/common/ieee1588.hpp
@@ -49,7 +49,8 @@
#include <gptp_log.hpp>
-#define MAX_PORTS 32 /*!< Maximum number of IEEE1588Port instances */
+#define MAX_PORTS 32 /*!< Maximum number of EtherPort
+ * instances */
#define PTP_CLOCK_IDENTITY_LENGTH 8 /*!< Size of a clock identifier stored in the ClockIndentity class, described at IEEE 802.1AS Clause 8.5.2.4*/
@@ -72,7 +73,8 @@ class PTPMessageAnnounce;
class PTPMessagePathDelayReq;
class PTPMessagePathDelayResp;
class PTPMessagePathDelayRespFollowUp;
-class IEEE1588Port;
+class EtherPort;
+class CommonPort;
class IEEE1588Clock;
class OSNetworkInterface;
@@ -105,7 +107,7 @@ typedef enum {
* @brief Defines an event descriptor type
*/
typedef struct {
- IEEE1588Port *port; //!< IEEE 1588 Port
+ CommonPort *port; //!< Media Dependent Ether Port
Event event; //!< Event enumeration
} event_descriptor_t;
@@ -499,7 +501,8 @@ public:
* @param frequency_offset Frequency offset
* @return false
*/
- virtual bool HWTimestamper_adjclockrate( float frequency_offset )
+ virtual bool HWTimestamper_adjclockrate
+ ( float frequency_offset ) const
{ return false; }
/**
@@ -526,7 +529,7 @@ public:
virtual bool HWTimestamper_gettime(Timestamp * system_time,
Timestamp * device_time,
uint32_t * local_clock,
- uint32_t * nominal_clock_rate) = 0;
+ uint32_t * nominal_clock_rate) const = 0;
/**
* @brief Gets the tx timestamp from hardware
@@ -580,7 +583,8 @@ public:
* @return void
* @todo There is no current implementation for this method.
*/
- virtual void HWTimestamper_get_extderror(char *msg) {
+ virtual void HWTimestamper_get_extderror(char *msg) const
+ {
*msg = '\0';
}
@@ -600,7 +604,8 @@ public:
* @brief Gets the HWTimestamper version
* @return version (signed integer)
*/
- int getVersion() {
+ int getVersion() const
+ {
return version;
}
/**
@@ -626,7 +631,7 @@ public:
* @return 0
**/
- int get_phy_delay (struct phy_delay *get_delay)
+ int get_phy_delay (struct phy_delay *get_delay) const
{
get_delay->mb_tx_phy_delay = delay.mb_tx_phy_delay;
get_delay->mb_rx_phy_delay = delay.mb_rx_phy_delay;
@@ -671,8 +676,8 @@ public:
* @param port [in] IEEE1588 port
* @return PTP message instance of PTPMessageCommon
*/
-PTPMessageCommon *buildPTPMessage(char *buf, int size,
- LinkLayerAddress * remote,
- IEEE1588Port * port);
+PTPMessageCommon *buildPTPMessage
+( char *buf, int size, LinkLayerAddress *remote,
+ EtherPort *port );
#endif
diff --git a/daemons/gptp/common/ieee1588clock.cpp b/daemons/gptp/common/ieee1588clock.cpp
index ac9b1aea..aae42dd1 100644
--- a/daemons/gptp/common/ieee1588clock.cpp
+++ b/daemons/gptp/common/ieee1588clock.cpp
@@ -233,7 +233,7 @@ void timerq_handler(void *arg)
}
void IEEE1588Clock::addEventTimer
-( IEEE1588Port * target, Event e, unsigned long long time_ns )
+( CommonPort *target, Event e, unsigned long long time_ns )
{
event_descriptor_t *event_descriptor = new event_descriptor_t();
event_descriptor->event = e;
@@ -244,7 +244,7 @@ void IEEE1588Clock::addEventTimer
}
void IEEE1588Clock::addEventTimerLocked
-( IEEE1588Port * target, Event e, unsigned long long time_ns )
+( CommonPort *target, Event e, unsigned long long time_ns )
{
if( getTimerQLock() == oslock_fail ) return;
addEventTimer( target, e, time_ns );
@@ -253,12 +253,14 @@ void IEEE1588Clock::addEventTimerLocked
-void IEEE1588Clock::deleteEventTimer(IEEE1588Port * target, Event event)
+void IEEE1588Clock::deleteEventTimer
+( CommonPort *target, Event event )
{
timerq->cancelEvent((int)event, NULL);
}
-void IEEE1588Clock::deleteEventTimerLocked(IEEE1588Port * target, Event event)
+void IEEE1588Clock::deleteEventTimerLocked
+( CommonPort *target, Event event )
{
if( getTimerQLock() == oslock_fail ) return;
@@ -336,10 +338,11 @@ FrequencyRatio IEEE1588Clock::calcMasterLocalClockRateDifference( Timestamp mast
}
void IEEE1588Clock::setMasterOffset
-( IEEE1588Port * port, int64_t master_local_offset, Timestamp local_time,
- FrequencyRatio master_local_freq_offset, int64_t local_system_offset,
- Timestamp system_time, FrequencyRatio local_system_freq_offset,
- unsigned sync_count, unsigned pdelay_count, PortState port_state, bool asCapable )
+( CommonPort *port, int64_t master_local_offset,
+ Timestamp local_time, FrequencyRatio master_local_freq_offset,
+ int64_t local_system_offset, Timestamp system_time,
+ FrequencyRatio local_system_freq_offset, unsigned sync_count,
+ unsigned pdelay_count, PortState port_state, bool asCapable )
{
_master_local_freq_offset = master_local_freq_offset;
_local_system_freq_offset = local_system_freq_offset;
diff --git a/daemons/gptp/common/ieee1588port.cpp b/daemons/gptp/common/ieee1588port.cpp
deleted file mode 100644
index 441ebbd6..00000000
--- a/daemons/gptp/common/ieee1588port.cpp
+++ /dev/null
@@ -1,1422 +0,0 @@
-/******************************************************************************
-
- Copyright (c) 2009-2012, Intel Corporation
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
-******************************************************************************/
-
-#include <ieee1588.hpp>
-
-#include <avbts_port.hpp>
-#include <avbts_message.hpp>
-#include <avbts_clock.hpp>
-
-#include <avbts_oslock.hpp>
-#include <avbts_osnet.hpp>
-#include <avbts_oscondition.hpp>
-
-#include <gptp_log.hpp>
-
-#include <stdio.h>
-
-#include <math.h>
-
-#include <stdlib.h>
-
-LinkLayerAddress IEEE1588Port::other_multicast(OTHER_MULTICAST);
-LinkLayerAddress IEEE1588Port::pdelay_multicast(PDELAY_MULTICAST);
-LinkLayerAddress IEEE1588Port::test_status_multicast(TEST_STATUS_MULTICAST);
-
-OSThreadExitCode watchNetLinkWrapper(void *arg)
-{
- IEEE1588Port *port;
-
- port = (IEEE1588Port *) arg;
- if (port->watchNetLink() == NULL)
- return osthread_ok;
- else
- return osthread_error;
-}
-
-OSThreadExitCode openPortWrapper(void *arg)
-{
- IEEE1588Port *port;
-
- port = (IEEE1588Port *) arg;
- if (port->openPort(port) == NULL)
- return osthread_ok;
- else
- return osthread_error;
-}
-
-IEEE1588Port::~IEEE1588Port()
-{
- delete port_ready_condition;
- delete [] rate_offset_array;
- if( qualified_announce != NULL ) delete qualified_announce;
-}
-
-IEEE1588Port::IEEE1588Port(IEEE1588PortInit_t *portInit)
-{
- sync_sequence_id = 0;
-
- clock = portInit->clock;
- ifindex = portInit->index;
- clock->registerPort(this, ifindex);
-
- forceSlave = portInit->forceSlave;
- port_state = PTP_INITIALIZING;
-
- automotive_profile = portInit->automotive_profile;
- isGM = portInit->isGM;
- testMode = portInit->testMode;
- linkUp = portInit->linkUp;
- initialLogSyncInterval = portInit->initialLogSyncInterval;
- initialLogPdelayReqInterval = portInit->initialLogPdelayReqInterval;
- operLogPdelayReqInterval = portInit->operLogPdelayReqInterval;
- operLogSyncInterval = portInit->operLogSyncInterval;
-
- if (automotive_profile) {
- asCapable = true;
-
- if (initialLogSyncInterval == LOG2_INTERVAL_INVALID)
- initialLogSyncInterval = -5; // 31.25 ms
- if (initialLogPdelayReqInterval == LOG2_INTERVAL_INVALID)
- initialLogPdelayReqInterval = 0; // 1 second
- if (operLogPdelayReqInterval == LOG2_INTERVAL_INVALID)
- operLogPdelayReqInterval = 0; // 1 second
- if (operLogSyncInterval == LOG2_INTERVAL_INVALID)
- operLogSyncInterval = 0; // 1 second
- }
- else {
- asCapable = false;
-
- if (initialLogSyncInterval == LOG2_INTERVAL_INVALID)
- initialLogSyncInterval = -3; // 125 ms
- if (initialLogPdelayReqInterval == LOG2_INTERVAL_INVALID)
- initialLogPdelayReqInterval = 0; // 1 second
- if (operLogPdelayReqInterval == LOG2_INTERVAL_INVALID)
- operLogPdelayReqInterval = 0; // 1 second
- if (operLogSyncInterval == LOG2_INTERVAL_INVALID)
- operLogSyncInterval = 0; // 1 second
- }
-
- announce_sequence_id = 0;
- signal_sequence_id = 0;
- sync_sequence_id = 0;
- pdelay_sequence_id = 0;
-
- pdelay_started = false;
- pdelay_halted = false;
- sync_rate_interval_timer_started = false;
-
- duplicate_resp_counter = 0;
- last_invalid_seqid = 0;
-
- /*TODO: Add intervals below to a config interface*/
- log_mean_sync_interval = initialLogSyncInterval;
- log_mean_announce_interval = 0;
- log_min_mean_pdelay_req_interval = initialLogPdelayReqInterval;
-
- _current_clock_offset = _initial_clock_offset = portInit->offset;
-
- rate_offset_array = NULL;
-
- _hw_timestamper = portInit->timestamper;
-
- one_way_delay = ONE_WAY_DELAY_DEFAULT;
- neighbor_prop_delay_thresh = NEIGHBOR_PROP_DELAY_THRESH;
- sync_receipt_thresh = DEFAULT_SYNC_RECEIPT_THRESH;
- wrongSeqIDCounter = 0;
-
- _peer_rate_offset = 1.0;
-
- last_sync = NULL;
- last_pdelay_req = NULL;
- last_pdelay_resp = NULL;
- last_pdelay_resp_fwup = NULL;
-
- qualified_announce = NULL;
-
- this->net_label = portInit->net_label;
-
- this->timer_factory = portInit->timer_factory;
- this->thread_factory = portInit->thread_factory;
-
- this->condition_factory = portInit->condition_factory;
- this->lock_factory = portInit->lock_factory;
-
- setPdelayCount(0);
- setSyncCount(0);
- memset(link_delay, 0, sizeof(link_delay));
-
- _peer_offset_init = false;
-
- if (automotive_profile) {
- if (isGM) {
- avbSyncState = 1;
- }
- else {
- avbSyncState = 2;
- }
- if (testMode) {
- linkUpCount = 1; // TODO : really should check the current linkup status http://stackoverflow.com/questions/15723061/how-to-check-if-interface-is-up
- linkDownCount = 0;
- }
- setStationState(STATION_STATE_RESERVED);
- }
-}
-
-void IEEE1588Port::timestamper_init(void)
-{
- if( _hw_timestamper != NULL ) {
- _hw_timestamper->init_phy_delay(this->link_delay);
- if( !_hw_timestamper->HWTimestamper_init( net_label, net_iface )) {
- GPTP_LOG_ERROR
- ( "Failed to initialize hardware timestamper, "
- "falling back to software timestamping" );
- _hw_timestamper = NULL;
- return;
- }
- }
-}
-
-void IEEE1588Port::timestamper_reset(void)
-{
- if( _hw_timestamper != NULL ) {
- _hw_timestamper->init_phy_delay(this->link_delay);
- _hw_timestamper->HWTimestamper_reset();
- }
-}
-
-bool IEEE1588Port::init_port(int delay[4])
-{
- if (!OSNetworkInterfaceFactory::buildInterface
- (&net_iface, factory_name_t("default"), net_label, _hw_timestamper))
- return false;
-
- this->net_iface = net_iface;
- this->net_iface->getLinkLayerAddress(&local_addr);
- clock->setClockIdentity(&local_addr);
- memcpy(this->link_delay, delay, sizeof(this->link_delay));
-
- this->timestamper_init();
-
- pdelay_rx_lock = lock_factory->createLock(oslock_recursive);
- port_tx_lock = lock_factory->createLock(oslock_recursive);
-
- syncReceiptTimerLock = lock_factory->createLock(oslock_recursive);
- syncIntervalTimerLock = lock_factory->createLock(oslock_recursive);
- announceIntervalTimerLock = lock_factory->createLock(oslock_recursive);
- pDelayIntervalTimerLock = lock_factory->createLock(oslock_recursive);
-
- port_identity.setClockIdentity(clock->getClockIdentity());
- port_identity.setPortNumber(&ifindex);
-
- port_ready_condition = condition_factory->createCondition();
-
- return true;
-}
-
-void IEEE1588Port::startPDelay() {
- if(!pdelayHalted()) {
- if (automotive_profile) {
- if (log_min_mean_pdelay_req_interval != PTPMessageSignalling::sigMsgInterval_NoSend) {
- long long unsigned int waitTime;
- waitTime = ((long long) (pow((double)2, log_min_mean_pdelay_req_interval) * 1000000000.0));
- waitTime = waitTime > EVENT_TIMER_GRANULARITY ? waitTime : EVENT_TIMER_GRANULARITY;
- pdelay_started = true;
- startPDelayIntervalTimer(waitTime);
- }
- }
- else {
- pdelay_started = true;
- startPDelayIntervalTimer(32000000);
- }
- }
-}
-
-void IEEE1588Port::stopPDelay() {
- haltPdelay(true);
- pdelay_started = false;
- clock->deleteEventTimerLocked( this, PDELAY_INTERVAL_TIMEOUT_EXPIRES);
-}
-
-void IEEE1588Port::startSyncRateIntervalTimer() {
- if (automotive_profile) {
- sync_rate_interval_timer_started = true;
- if (isGM) {
- // GM will wait up to 8 seconds for signaling rate
- // TODO: This isn't according to spec but set because it is believed that some slave devices aren't signalling
- // to reduce the rate
- clock->addEventTimerLocked( this, SYNC_RATE_INTERVAL_TIMEOUT_EXPIRED, 8000000000 );
- }
- else {
- // Slave will time out after 4 seconds
- clock->addEventTimerLocked( this, SYNC_RATE_INTERVAL_TIMEOUT_EXPIRED, 4000000000 );
- }
- }
-}
-
-void IEEE1588Port::startAnnounce() {
- if (!automotive_profile) {
- startAnnounceIntervalTimer(16000000);
- }
-}
-
-bool IEEE1588Port::serializeState( void *buf, off_t *count ) {
- bool ret = true;
-
- if( buf == NULL ) {
- *count = sizeof(port_state)+sizeof(_peer_rate_offset)+
- sizeof(asCapable)+sizeof(one_way_delay);
- return true;
- }
-
- if( port_state != PTP_MASTER && port_state != PTP_SLAVE ) {
- *count = 0;
- ret = false;
- goto bail;
- }
-
- /* asCapable */
- if( ret && *count >= (off_t) sizeof( asCapable )) {
- memcpy( buf, &asCapable, sizeof( asCapable ));
- *count -= sizeof( asCapable );
- buf = ((char *)buf) + sizeof( asCapable );
- } else if( ret == false ) {
- *count += sizeof( asCapable );
- } else {
- *count = sizeof( asCapable )-*count;
- ret = false;
- }
-
- /* Port State */
- if( ret && *count >= (off_t) sizeof( port_state )) {
- memcpy( buf, &port_state, sizeof( port_state ));
- *count -= sizeof( port_state );
- buf = ((char *)buf) + sizeof( port_state );
- } else if( ret == false ) {
- *count += sizeof( port_state );
- } else {
- *count = sizeof( port_state )-*count;
- ret = false;
- }
-
- /* Link Delay */
- if( ret && *count >= (off_t) sizeof( one_way_delay )) {
- memcpy( buf, &one_way_delay, sizeof( one_way_delay ));
- *count -= sizeof( one_way_delay );
- buf = ((char *)buf) + sizeof( one_way_delay );
- } else if( ret == false ) {
- *count += sizeof( one_way_delay );
- } else {
- *count = sizeof( one_way_delay )-*count;
- ret = false;
- }
-
- /* Neighbor Rate Ratio */
- if( ret && *count >= (off_t) sizeof( _peer_rate_offset )) {
- memcpy( buf, &_peer_rate_offset, sizeof( _peer_rate_offset ));
- *count -= sizeof( _peer_rate_offset );
- buf = ((char *)buf) + sizeof( _peer_rate_offset );
- } else if( ret == false ) {
- *count += sizeof( _peer_rate_offset );
- } else {
- *count = sizeof( _peer_rate_offset )-*count;
- ret = false;
- }
-
- bail:
- return ret;
-}
-
-bool IEEE1588Port::restoreSerializedState( void *buf, off_t *count ) {
- bool ret = true;
-
- /* asCapable */
- if( ret && *count >= (off_t) sizeof( asCapable )) {
- memcpy( &asCapable, buf, sizeof( asCapable ));
- *count -= sizeof( asCapable );
- buf = ((char *)buf) + sizeof( asCapable );
- } else if( ret == false ) {
- *count += sizeof( asCapable );
- } else {
- *count = sizeof( asCapable )-*count;
- ret = false;
- }
-
- /* Port State */
- if( ret && *count >= (off_t) sizeof( port_state )) {
- memcpy( &port_state, buf, sizeof( port_state ));
- *count -= sizeof( port_state );
- buf = ((char *)buf) + sizeof( port_state );
- } else if( ret == false ) {
- *count += sizeof( port_state );
- } else {
- *count = sizeof( port_state )-*count;
- ret = false;
- }
-
- /* Link Delay */
- if( ret && *count >= (off_t) sizeof( one_way_delay )) {
- memcpy( &one_way_delay, buf, sizeof( one_way_delay ));
- *count -= sizeof( one_way_delay );
- buf = ((char *)buf) + sizeof( one_way_delay );
- } else if( ret == false ) {
- *count += sizeof( one_way_delay );
- } else {
- *count = sizeof( one_way_delay )-*count;
- ret = false;
- }
-
- /* Neighbor Rate Ratio */
- if( ret && *count >= (off_t) sizeof( _peer_rate_offset )) {
- memcpy( &_peer_rate_offset, buf, sizeof( _peer_rate_offset ));
- *count -= sizeof( _peer_rate_offset );
- buf = ((char *)buf) + sizeof( _peer_rate_offset );
- } else if( ret == false ) {
- *count += sizeof( _peer_rate_offset );
- } else {
- *count = sizeof( _peer_rate_offset )-*count;
- ret = false;
- }
-
- return ret;
-}
-
-void *IEEE1588Port::watchNetLink(void)
-{
- // Should never return
- net_iface->watchNetLink(this);
-
- return NULL;
-}
-
-void *IEEE1588Port::openPort(IEEE1588Port *port)
-{
- port_ready_condition->signal();
- struct phy_delay get_delay = { 0, 0, 0, 0 };
- if(port->_hw_timestamper)
- port->_hw_timestamper->get_phy_delay(&get_delay);
-
- while (1) {
- PTPMessageCommon *msg;
- uint8_t buf[128];
- LinkLayerAddress remote;
- net_result rrecv;
- size_t length = sizeof(buf);
-
- if ((rrecv = net_iface->nrecv(&remote, buf, length,&get_delay)) == net_succeed) {
- GPTP_LOG_VERBOSE("Processing network buffer");
- msg = buildPTPMessage((char *)buf, (int)length, &remote,
- this);
- if (msg != NULL) {
- GPTP_LOG_VERBOSE("Processing message");
- msg->processMessage(this);
- if (msg->garbage()) {
- delete msg;
- }
- } else {
- GPTP_LOG_ERROR("Discarding invalid message");
- }
- } else if (rrecv == net_fatal) {
- GPTP_LOG_ERROR("read from network interface failed");
- this->processEvent(FAULT_DETECTED);
- break;
- }
- }
-
- return NULL;
-}
-
-net_result IEEE1588Port::port_send(uint16_t etherType, uint8_t * buf, int size,
- MulticastType mcast_type,
- PortIdentity * destIdentity, bool timestamp)
-{
- LinkLayerAddress dest;
-
- if (mcast_type != MCAST_NONE) {
- if (mcast_type == MCAST_PDELAY) {
- dest = pdelay_multicast;
- }
- else if (mcast_type == MCAST_TEST_STATUS) {
- dest = test_status_multicast;
- }
- else {
- dest = other_multicast;
- }
- } else {
- mapSocketAddr(destIdentity, &dest);
- }
-
- return net_iface->send(&dest, etherType, (uint8_t *) buf, size, timestamp);
-}
-
-unsigned IEEE1588Port::getPayloadOffset()
-{
- return net_iface->getPayloadOffset();
-}
-
-void IEEE1588Port::sendEventPort(uint16_t etherType, uint8_t * buf, int size,
- MulticastType mcast_type,
- PortIdentity * destIdentity)
-{
- net_result rtx = port_send(etherType, buf, size, mcast_type, destIdentity, true);
- if (rtx != net_succeed) {
- GPTP_LOG_ERROR("sendEventPort(): failure");
- }
-
- return;
-}
-
-void IEEE1588Port::sendGeneralPort(uint16_t etherType, uint8_t * buf, int size,
- MulticastType mcast_type,
- PortIdentity * destIdentity)
-{
- net_result rtx = port_send(etherType, buf, size, mcast_type, destIdentity, false);
- if (rtx != net_succeed) {
- GPTP_LOG_ERROR("sendGeneralPort(): failure");
- }
-
- return;
-}
-
-void IEEE1588Port::processEvent(Event e)
-{
- bool changed_external_master;
-
- switch (e) {
- case POWERUP:
- case INITIALIZE:
- GPTP_LOG_DEBUG("Received POWERUP/INITIALIZE event");
-
- {
- unsigned long long interval3;
- unsigned long long interval4;
- Event e3 = NULL_EVENT;
- Event e4 = NULL_EVENT;
-
- if (!automotive_profile) {
- if (port_state != PTP_SLAVE && port_state != PTP_MASTER) {
- GPTP_LOG_STATUS("Starting PDelay");
- startPDelay();
- }
- }
- else {
- startPDelay();
- }
-
- if( clock->getPriority1() == 255 || port_state == PTP_SLAVE ) {
- becomeSlave( true );
- } else if( port_state == PTP_MASTER ) {
- becomeMaster( true );
- } else {
- /*TODO: Should I remove the commented code below ?*/
- //e3 = SYNC_RECEIPT_TIMEOUT_EXPIRES;
- e4 = ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES;
- interval3 = (unsigned long long)
- (SYNC_RECEIPT_TIMEOUT_MULTIPLIER*
- pow((double)2,getSyncInterval())*1000000000.0);
- interval4 = (unsigned long long)
- (ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER*
- pow((double)2,getAnnounceInterval())*1000000000.0);
- }
-
- port_ready_condition->wait_prelock();
-
- link_thread = thread_factory->createThread();
- if(!link_thread->start(watchNetLinkWrapper, (void *)this))
- {
- GPTP_LOG_ERROR("Error creating port link thread");
- return;
- }
-
- listening_thread = thread_factory->createThread();
- if (!listening_thread->
- start (openPortWrapper, (void *)this))
- {
- GPTP_LOG_ERROR("Error creating port thread");
- return;
- }
- port_ready_condition->wait();
-
- if (e3 != NULL_EVENT)
- clock->addEventTimerLocked(this, e3, interval3);
- if (e4 != NULL_EVENT)
- clock->addEventTimerLocked(this, e4, interval4);
- }
-
- if (automotive_profile) {
- setStationState(STATION_STATE_ETHERNET_READY);
- if (testMode) {
- APMessageTestStatus *testStatusMsg = new APMessageTestStatus(this);
- if (testStatusMsg) {
- testStatusMsg->sendPort(this);
- delete testStatusMsg;
- }
- }
- if (!isGM) {
- // Send an initial signalling message
- PTPMessageSignalling *sigMsg = new PTPMessageSignalling(this);
- if (sigMsg) {
- sigMsg->setintervals(PTPMessageSignalling::sigMsgInterval_NoSend, log_mean_sync_interval, PTPMessageSignalling::sigMsgInterval_NoSend);
- sigMsg->sendPort(this, NULL);
- delete sigMsg;
- }
-
- startSyncReceiptTimer((unsigned long long)
- (SYNC_RECEIPT_TIMEOUT_MULTIPLIER *
- ((double) pow((double)2, getSyncInterval()) *
- 1000000000.0)));
- }
- }
-
- break;
-
- case STATE_CHANGE_EVENT:
- if (!automotive_profile) { // BMCA is not active with Automotive Profile
- if ( clock->getPriority1() != 255 ) {
- int number_ports, j;
- PTPMessageAnnounce *EBest = NULL;
- char EBestClockIdentity[PTP_CLOCK_IDENTITY_LENGTH];
-
- IEEE1588Port **ports;
- clock->getPortList(number_ports, ports);
-
- /* Find EBest for all ports */
- j = 0;
- for (int i = 0; i < number_ports; ++i) {
- while (ports[j] == NULL)
- ++j;
- if (ports[j]->port_state == PTP_DISABLED
- || ports[j]->port_state == PTP_FAULTY) {
- continue;
- }
- if (EBest == NULL) {
- EBest = ports[j]->calculateERBest();
- } else if (ports[j]->calculateERBest()) {
- if (ports[j]->calculateERBest()->isBetterThan(EBest)) {
- EBest = ports[j]->calculateERBest();
- }
- }
- }
-
- if (EBest == NULL) {
- break;
- }
-
- /* Check if we've changed */
- {
-
- uint8_t LastEBestClockIdentity[PTP_CLOCK_IDENTITY_LENGTH];
- clock->getLastEBestIdentity().
- getIdentityString( LastEBestClockIdentity );
- EBest->getGrandmasterIdentity( EBestClockIdentity );
- if( memcmp( EBestClockIdentity, LastEBestClockIdentity,
- PTP_CLOCK_IDENTITY_LENGTH ) != 0 )
- {
- ClockIdentity newGM;
- changed_external_master = true;
- newGM.set((uint8_t *) EBestClockIdentity );
- clock->setLastEBestIdentity( newGM );
- } else {
- changed_external_master = false;
- }
- }
-
- if( clock->isBetterThan( EBest )) {
- // We're Grandmaster, set grandmaster info to me
- ClockIdentity clock_identity;
- unsigned char priority1;
- unsigned char priority2;
- ClockQuality clock_quality;
-
- clock_identity = getClock()->getClockIdentity();
- getClock()->setGrandmasterClockIdentity( clock_identity );
- priority1 = getClock()->getPriority1();
- getClock()->setGrandmasterPriority1( priority1 );
- priority2 = getClock()->getPriority2();
- getClock()->setGrandmasterPriority2( priority2 );
- clock_quality = getClock()->getClockQuality();
- getClock()->setGrandmasterClockQuality( clock_quality );
- }
-
- j = 0;
- for (int i = 0; i < number_ports; ++i) {
- while (ports[j] == NULL)
- ++j;
- if (ports[j]->port_state == PTP_DISABLED
- || ports[j]->port_state == PTP_FAULTY) {
- continue;
- }
- if (clock->isBetterThan(EBest)) {
- // We are the GrandMaster, all ports are master
- EBest = NULL; // EBest == NULL : we were grandmaster
- ports[j]->recommendState(PTP_MASTER,
- changed_external_master);
- } else {
- if( EBest == ports[j]->calculateERBest() ) {
- // The "best" Announce was recieved on this port
- ClockIdentity clock_identity;
- unsigned char priority1;
- unsigned char priority2;
- ClockQuality *clock_quality;
-
- ports[j]->recommendState
- ( PTP_SLAVE, changed_external_master );
-
- clock_identity = EBest->getGrandmasterClockIdentity();
- getClock()->setGrandmasterClockIdentity(clock_identity);
- priority1 = EBest->getGrandmasterPriority1();
- getClock()->setGrandmasterPriority1( priority1 );
- priority2 = EBest->getGrandmasterPriority2();
- getClock()->setGrandmasterPriority2( priority2 );
- clock_quality = EBest->getGrandmasterClockQuality();
- getClock()->setGrandmasterClockQuality(*clock_quality);
- } else {
- /* Otherwise we are the master because we have
- sync'd to a better clock */
- ports[j]->recommendState
- (PTP_MASTER, changed_external_master);
- }
- }
- }
- }
- }
- break;
-
- case LINKUP:
- haltPdelay(false);
- startPDelay();
- if (automotive_profile) {
- GPTP_LOG_EXCEPTION("LINKUP");
- }
- else {
- GPTP_LOG_STATUS("LINKUP");
- }
-
- if (automotive_profile) {
- asCapable = true;
-
- setStationState(STATION_STATE_ETHERNET_READY);
- if (testMode) {
- APMessageTestStatus *testStatusMsg = new APMessageTestStatus(this);
- if (testStatusMsg) {
- testStatusMsg->sendPort(this);
- delete testStatusMsg;
- }
- }
-
- log_mean_sync_interval = initialLogSyncInterval;
- log_mean_announce_interval = 0;
- log_min_mean_pdelay_req_interval = initialLogPdelayReqInterval;
-
- if (!isGM) {
- // Send an initial signaling message
- PTPMessageSignalling *sigMsg = new PTPMessageSignalling(this);
- if (sigMsg) {
- sigMsg->setintervals(PTPMessageSignalling::sigMsgInterval_NoSend, log_mean_sync_interval, PTPMessageSignalling::sigMsgInterval_NoSend);
- sigMsg->sendPort(this, NULL);
- delete sigMsg;
- }
-
- startSyncReceiptTimer((unsigned long long)
- (SYNC_RECEIPT_TIMEOUT_MULTIPLIER *
- ((double) pow((double)2, getSyncInterval()) *
- 1000000000.0)));
- }
-
- // Reset Sync count and pdelay count
- setPdelayCount(0);
- setSyncCount(0);
-
- // Start AVB SYNC at 2. It will decrement after each sync. When it reaches 0 the Test Status message
- // can be sent
- if (isGM) {
- avbSyncState = 1;
- }
- else {
- avbSyncState = 2;
- }
-
- if (testMode) {
- linkUpCount++;
- }
- }
- this->timestamper_reset();
- break;
-
- case LINKDOWN:
- stopPDelay();
- if (automotive_profile) {
- GPTP_LOG_EXCEPTION("LINK DOWN");
- }
- else {
- setAsCapable(false);
- GPTP_LOG_STATUS("LINK DOWN");
- }
- if (testMode) {
- linkDownCount++;
- }
- break;
-
- case ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES:
- case SYNC_RECEIPT_TIMEOUT_EXPIRES:
- {
- if (e == ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES) {
- incCounter_ieee8021AsPortStatAnnounceReceiptTimeouts();
- }
- else if (e == SYNC_RECEIPT_TIMEOUT_EXPIRES) {
- incCounter_ieee8021AsPortStatRxSyncReceiptTimeouts();
- }
- if (!automotive_profile) {
-
- if( clock->getPriority1() == 255 ) {
- // Restart timer
- if( e == ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES ) {
- clock->addEventTimerLocked
- (this, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES,
- (ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER*
- (unsigned long long)
- (pow((double)2,getAnnounceInterval())*
- 1000000000.0)));
- } else {
- startSyncReceiptTimer((unsigned long long)
- (SYNC_RECEIPT_TIMEOUT_MULTIPLIER *
- ((double) pow((double)2, getSyncInterval()) *
- 1000000000.0)));
- }
- }
-
- if (port_state == PTP_INITIALIZING
- || port_state == PTP_UNCALIBRATED
- || port_state == PTP_SLAVE
- || port_state == PTP_PRE_MASTER) {
- GPTP_LOG_STATUS(
- "*** %s Timeout Expired - Becoming Master",
- e == ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES ? "Announce" :
- "Sync" );
- {
- // We're Grandmaster, set grandmaster info to me
- ClockIdentity clock_identity;
- unsigned char priority1;
- unsigned char priority2;
- ClockQuality clock_quality;
-
- clock_identity = getClock()->getClockIdentity();
- getClock()->setGrandmasterClockIdentity( clock_identity );
- priority1 = getClock()->getPriority1();
- getClock()->setGrandmasterPriority1( priority1 );
- priority2 = getClock()->getPriority2();
- getClock()->setGrandmasterPriority2( priority2 );
- clock_quality = getClock()->getClockQuality();
- getClock()->setGrandmasterClockQuality( clock_quality );
- }
- port_state = PTP_MASTER;
- Timestamp system_time;
- Timestamp device_time;
-
- uint32_t local_clock, nominal_clock_rate;
-
- getDeviceTime(system_time, device_time,
- local_clock, nominal_clock_rate);
-
- (void) clock->calcLocalSystemClockRateDifference
- ( device_time, system_time );
-
- delete qualified_announce;
- qualified_announce = NULL;
-
- // Add timers for Announce and Sync, this is as close to immediately as we get
- if( clock->getPriority1() != 255) {
- clock->addEventTimerLocked
- ( this, SYNC_INTERVAL_TIMEOUT_EXPIRES, 16000000 );
- }
- startAnnounce();
- }
-
- }
- else {
- // Automotive Profile
- if (e == SYNC_RECEIPT_TIMEOUT_EXPIRES) {
- GPTP_LOG_EXCEPTION("SYNC receipt timeout");
-
- startSyncReceiptTimer((unsigned long long)
- (SYNC_RECEIPT_TIMEOUT_MULTIPLIER *
- ((double) pow((double)2, getSyncInterval()) *
- 1000000000.0)));
- }
- }
-
- }
-
- break;
- case PDELAY_INTERVAL_TIMEOUT_EXPIRES:
- GPTP_LOG_DEBUG("PDELAY_INTERVAL_TIMEOUT_EXPIRES occured");
- {
- int ts_good;
- Timestamp req_timestamp;
- int iter = TX_TIMEOUT_ITER;
- long req = TX_TIMEOUT_BASE;
- unsigned req_timestamp_counter_value;
- long long wait_time = 0;
-
- PTPMessagePathDelayReq *pdelay_req =
- new PTPMessagePathDelayReq(this);
- PortIdentity dest_id;
- getPortIdentity(dest_id);
- pdelay_req->setPortIdentity(&dest_id);
-
- {
- Timestamp pending =
- PDELAY_PENDING_TIMESTAMP;
- pdelay_req->setTimestamp(pending);
- }
-
- if (last_pdelay_req != NULL) {
- delete last_pdelay_req;
- }
- setLastPDelayReq(pdelay_req);
-
- getTxLock();
- pdelay_req->sendPort(this, NULL);
- GPTP_LOG_DEBUG("*** Sent PDelay Request message");
-
- OSTimer *timer = timer_factory->createTimer();
-
- ts_good = getTxTimestamp
- (pdelay_req, req_timestamp, req_timestamp_counter_value, false);
- while (ts_good != GPTP_EC_SUCCESS && iter-- != 0) {
- timer->sleep(req);
- wait_time += req;
- if (ts_good != GPTP_EC_EAGAIN && iter < 1)
- GPTP_LOG_ERROR(
- "Error (TX) timestamping PDelay request "
- "(Retrying-%d), error=%d", iter, ts_good);
- ts_good =
- getTxTimestamp
- (pdelay_req, req_timestamp,
- req_timestamp_counter_value, iter == 0);
- req *= 2;
- }
- delete timer;
- putTxLock();
-
- if (ts_good == GPTP_EC_SUCCESS) {
- pdelay_req->setTimestamp(req_timestamp);
- GPTP_LOG_DEBUG(
- "PDelay Request message, Timestamp %u (sec) %u (ns), seqID %u",
- req_timestamp.seconds_ls, req_timestamp.nanoseconds,
- pdelay_req->getSequenceId());
- } else {
- Timestamp failed = INVALID_TIMESTAMP;
- pdelay_req->setTimestamp(failed);
- GPTP_LOG_ERROR( "Invalid TX" );
- }
-
- if (ts_good != GPTP_EC_SUCCESS) {
- char msg
- [HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE];
- getExtendedError(msg);
- GPTP_LOG_ERROR(
- "Error (TX) timestamping PDelay request, error=%d\t%s",
- ts_good, msg);
- }
-
- {
- long long timeout;
- long long interval;
-
- timeout = PDELAY_RESP_RECEIPT_TIMEOUT_MULTIPLIER *
- ((long long)
- (pow((double)2,getPDelayInterval())*1000000000.0)) -
- wait_time*1000;
- timeout = timeout > EVENT_TIMER_GRANULARITY ?
- timeout : EVENT_TIMER_GRANULARITY;
- clock->addEventTimerLocked
- (this, PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES, timeout );
- GPTP_LOG_DEBUG("Schedule PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES, "
- "PDelay interval %d, wait_time %lld, timeout %lld",
- getPDelayInterval(), wait_time, timeout);
-
- interval =
- ((long long)
- (pow((double)2,getPDelayInterval())*1000000000.0)) -
- wait_time*1000;
- interval = interval > EVENT_TIMER_GRANULARITY ?
- interval : EVENT_TIMER_GRANULARITY;
- startPDelayIntervalTimer(interval);
- }
- }
- break;
- case SYNC_INTERVAL_TIMEOUT_EXPIRES:
- GPTP_LOG_DEBUG("SYNC_INTERVAL_TIMEOUT_EXPIRES occured");
- {
- /* Set offset from master to zero, update device vs
- system time offset */
- Timestamp system_time;
- Timestamp device_time;
- FrequencyRatio local_system_freq_offset;
- int64_t local_system_offset;
- long long wait_time = 0;
-
- uint32_t local_clock, nominal_clock_rate;
-
- // Send a sync message and then a followup to broadcast
- if (asCapable) {
- PTPMessageSync *sync = new PTPMessageSync(this);
- PortIdentity dest_id;
- getPortIdentity(dest_id);
- sync->setPortIdentity(&dest_id);
- getTxLock();
- sync->sendPort(this, NULL);
- GPTP_LOG_DEBUG("Sent SYNC message");
-
- if (automotive_profile && port_state == PTP_MASTER) {
- if (avbSyncState > 0) {
- avbSyncState--;
- if (avbSyncState == 0) {
- // Send Avnu Automotive Profile status message
- setStationState(STATION_STATE_AVB_SYNC);
- if (testMode) {
- APMessageTestStatus *testStatusMsg = new APMessageTestStatus(this);
- if (testStatusMsg) {
- testStatusMsg->sendPort(this);
- delete testStatusMsg;
- }
- }
- }
- }
- }
-
- int ts_good;
- Timestamp sync_timestamp;
- unsigned sync_timestamp_counter_value;
- int iter = TX_TIMEOUT_ITER;
- long req = TX_TIMEOUT_BASE;
-
- OSTimer *timer = timer_factory->createTimer();
-
- ts_good =
- getTxTimestamp(sync, sync_timestamp,
- sync_timestamp_counter_value,
- false);
- while (ts_good != GPTP_EC_SUCCESS && iter-- != 0) {
- timer->sleep(req);
- wait_time += req;
-
- if (ts_good != GPTP_EC_EAGAIN && iter < 1)
- GPTP_LOG_ERROR(
- "Error (TX) timestamping Sync (Retrying), "
- "error=%d", ts_good);
- ts_good =
- getTxTimestamp
- (sync, sync_timestamp,
- sync_timestamp_counter_value, iter == 0);
- req *= 2;
- }
- delete timer;
- putTxLock();
-
- if (ts_good != GPTP_EC_SUCCESS) {
- char msg [HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE];
- getExtendedError(msg);
- GPTP_LOG_ERROR(
- "Error (TX) timestamping Sync, error="
- "%d\n%s",
- ts_good, msg );
- }
-
- if (ts_good == GPTP_EC_SUCCESS) {
- GPTP_LOG_VERBOSE("Successful Sync timestamp");
- GPTP_LOG_VERBOSE("Seconds: %u",
- sync_timestamp.seconds_ls);
- GPTP_LOG_VERBOSE("Nanoseconds: %u",
- sync_timestamp.nanoseconds);
- } else {
- GPTP_LOG_ERROR
- ("*** Unsuccessful Sync timestamp");
- }
-
- PTPMessageFollowUp *follow_up;
- if (ts_good == GPTP_EC_SUCCESS) {
-
- follow_up =
- new PTPMessageFollowUp(this);
- PortIdentity dest_id;
- getPortIdentity(dest_id);
-
- follow_up->setClockSourceTime(getClock()->getFUPInfo());
- follow_up->setPortIdentity(&dest_id);
- follow_up->setSequenceId(sync->getSequenceId());
- follow_up->setPreciseOriginTimestamp(sync_timestamp);
- follow_up->sendPort(this, NULL);
- delete follow_up;
- } else {
- }
- delete sync;
- }
- /* Do getDeviceTime() after transmitting sync frame
- causing an update to local/system timestamp */
- getDeviceTime
- (system_time, device_time, local_clock, nominal_clock_rate);
-
- GPTP_LOG_VERBOSE
- ("port::processEvent(): System time: %u,%u Device Time: %u,%u",
- system_time.seconds_ls, system_time.nanoseconds,
- device_time.seconds_ls, device_time.nanoseconds);
-
- local_system_offset =
- TIMESTAMP_TO_NS(system_time) -
- TIMESTAMP_TO_NS(device_time);
- local_system_freq_offset =
- clock->calcLocalSystemClockRateDifference
- ( device_time, system_time );
- clock->setMasterOffset
- (this, 0, device_time, 1.0, local_system_offset,
- system_time, local_system_freq_offset, sync_count,
- pdelay_count, port_state, asCapable );
-
- syncDone();
-
- wait_time = ((long long) (pow((double)2, getSyncInterval()) * 1000000000.0));
- wait_time = wait_time > EVENT_TIMER_GRANULARITY ? wait_time : EVENT_TIMER_GRANULARITY;
- startSyncIntervalTimer(wait_time);
-
- }
- break;
- case ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES:
- GPTP_LOG_DEBUG("ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES occured");
- if (asCapable) {
- // Send an announce message
- PTPMessageAnnounce *annc = new PTPMessageAnnounce(this);
- PortIdentity dest_id;
- PortIdentity gmId;
- ClockIdentity clock_id = clock->getClockIdentity();
- gmId.setClockIdentity(clock_id);
- getPortIdentity(dest_id);
- annc->setPortIdentity(&dest_id);
- annc->sendPort(this, NULL);
- delete annc;
- }
- startAnnounceIntervalTimer((uint64_t)(pow((double)2, getAnnounceInterval()) * 1000000000.0));
- break;
- case FAULT_DETECTED:
- GPTP_LOG_ERROR("Received FAULT_DETECTED event");
- if (!automotive_profile) {
- setAsCapable(false);
- }
- break;
- case PDELAY_DEFERRED_PROCESSING:
- GPTP_LOG_DEBUG("PDELAY_DEFERRED_PROCESSING occured");
- pdelay_rx_lock->lock();
- if (last_pdelay_resp_fwup == NULL) {
- GPTP_LOG_ERROR("PDelay Response Followup is NULL!");
- abort();
- }
- last_pdelay_resp_fwup->processMessage(this);
- if (last_pdelay_resp_fwup->garbage()) {
- delete last_pdelay_resp_fwup;
- this->setLastPDelayRespFollowUp(NULL);
- }
- pdelay_rx_lock->unlock();
- break;
- case PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES:
- if (!automotive_profile) {
- GPTP_LOG_EXCEPTION("PDelay Response Receipt Timeout");
- setAsCapable(false);
- }
- pdelay_count = 0;
- break;
-
- case PDELAY_RESP_PEER_MISBEHAVING_TIMEOUT_EXPIRES:
- GPTP_LOG_EXCEPTION("PDelay Resp Peer Misbehaving timeout expired! Restarting PDelay");
-
- haltPdelay(false);
- if( port_state != PTP_SLAVE && port_state != PTP_MASTER ) {
- GPTP_LOG_STATUS("Starting PDelay" );
- startPDelay();
- }
- break;
- case SYNC_RATE_INTERVAL_TIMEOUT_EXPIRED:
- {
- GPTP_LOG_INFO("SYNC_RATE_INTERVAL_TIMEOUT_EXPIRED occured");
-
- sync_rate_interval_timer_started = false;
-
- bool sendSignalMessage = false;
- if (log_mean_sync_interval != operLogSyncInterval) {
- log_mean_sync_interval = operLogSyncInterval;
- sendSignalMessage = true;
- }
-
- if (log_min_mean_pdelay_req_interval != operLogPdelayReqInterval) {
- log_min_mean_pdelay_req_interval = operLogPdelayReqInterval;
- sendSignalMessage = true;
- }
-
- if (sendSignalMessage) {
- if (!isGM) {
- // Send operational signalling message
- PTPMessageSignalling *sigMsg = new PTPMessageSignalling(this);
- if (sigMsg) {
- if (automotive_profile)
- sigMsg->setintervals(PTPMessageSignalling::sigMsgInterval_NoChange, log_mean_sync_interval, PTPMessageSignalling::sigMsgInterval_NoChange);
- else
- sigMsg->setintervals(log_min_mean_pdelay_req_interval, log_mean_sync_interval, PTPMessageSignalling::sigMsgInterval_NoChange);
- sigMsg->sendPort(this, NULL);
- delete sigMsg;
- }
-
- startSyncReceiptTimer((unsigned long long)
- (SYNC_RECEIPT_TIMEOUT_MULTIPLIER *
- ((double) pow((double)2, getSyncInterval()) *
- 1000000000.0)));
- }
- }
- }
-
- break;
- default:
- GPTP_LOG_ERROR
- ("Unhandled event type in IEEE1588Port::processEvent(), %d",
- e);
- break;
- }
-
- return;
-}
-
-PTPMessageAnnounce *IEEE1588Port::calculateERBest(void)
-{
- return qualified_announce;
-}
-
-void IEEE1588Port::recoverPort(void)
-{
- return;
-}
-
-IEEE1588Clock *IEEE1588Port::getClock(void)
-{
- return clock;
-}
-
-void IEEE1588Port::getDeviceTime
-(Timestamp & system_time, Timestamp & device_time,
- uint32_t & local_clock, uint32_t & nominal_clock_rate)
-{
- if (_hw_timestamper) {
- _hw_timestamper->HWTimestamper_gettime
- (&system_time, &device_time, &local_clock, &nominal_clock_rate);
- } else {
- device_time = system_time = clock->getSystemTime();
- local_clock = nominal_clock_rate = 0;
- }
- return;
-}
-
-void IEEE1588Port::becomeMaster( bool annc ) {
- port_state = PTP_MASTER;
- // Stop announce receipt timeout timer
- clock->deleteEventTimerLocked( this, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES );
-
- // Stop sync receipt timeout timer
- stopSyncReceiptTimer();
-
- if( annc ) {
- if (!automotive_profile) {
- startAnnounce();
- }
- }
- startSyncIntervalTimer(16000000);
- GPTP_LOG_STATUS("Switching to Master" );
-
- clock->updateFUPInfo();
-
- return;
-}
-
-void IEEE1588Port::becomeSlave( bool restart_syntonization ) {
- clock->deleteEventTimerLocked( this, ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES );
- clock->deleteEventTimerLocked( this, SYNC_INTERVAL_TIMEOUT_EXPIRES );
-
- port_state = PTP_SLAVE;
-
- if (!automotive_profile) {
- clock->addEventTimerLocked
- (this, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES,
- (ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER*
- (unsigned long long)
- (pow((double)2,getAnnounceInterval())*1000000000.0)));
- }
-
- GPTP_LOG_STATUS("Switching to Slave" );
- if( restart_syntonization ) clock->newSyntonizationSetPoint();
-
- getClock()->updateFUPInfo();
-
- return;
-}
-
-void IEEE1588Port::recommendState
-( PortState state, bool changed_external_master )
-{
- bool reset_sync = false;
- switch (state) {
- case PTP_MASTER:
- if (port_state != PTP_MASTER) {
- port_state = PTP_MASTER;
- // Start announce receipt timeout timer
- // Start sync receipt timeout timer
- becomeMaster( true );
- reset_sync = true;
- }
- break;
- case PTP_SLAVE:
- if (port_state != PTP_SLAVE) {
- becomeSlave( true );
- reset_sync = true;
- } else {
- if( changed_external_master ) {
- GPTP_LOG_STATUS("Changed master!" );
- clock->newSyntonizationSetPoint();
- getClock()->updateFUPInfo();
- reset_sync = true;
- }
- }
- break;
- default:
- GPTP_LOG_ERROR
- ("Invalid state change requested by call to "
- "1588Port::recommendState()");
- break;
- }
- if( reset_sync ) sync_count = 0;
- return;
- }
-
-void IEEE1588Port::mapSocketAddr
-(PortIdentity * destIdentity, LinkLayerAddress * remote)
-{
- *remote = identity_map[*destIdentity];
- return;
-}
-
-void IEEE1588Port::addSockAddrMap
-(PortIdentity * destIdentity, LinkLayerAddress * remote)
-{
- identity_map[*destIdentity] = *remote;
- return;
-}
-
-int IEEE1588Port::getTxTimestamp
-(PTPMessageCommon * msg, Timestamp & timestamp, unsigned &counter_value,
- bool last)
-{
- PortIdentity identity;
- msg->getPortIdentity(&identity);
- return getTxTimestamp
- (&identity, msg->getMessageId(), timestamp, counter_value, last);
-}
-
-int IEEE1588Port::getRxTimestamp(PTPMessageCommon * msg, Timestamp & timestamp,
- unsigned &counter_value, bool last)
-{
- PortIdentity identity;
- msg->getPortIdentity(&identity);
- return getRxTimestamp
- (&identity, msg->getMessageId(), timestamp, counter_value, last);
-}
-
-int IEEE1588Port::getTxTimestamp(PortIdentity * sourcePortIdentity,
- PTPMessageId messageId, Timestamp & timestamp,
- unsigned &counter_value, bool last)
-{
- if (_hw_timestamper) {
- return _hw_timestamper->HWTimestamper_txtimestamp
- (sourcePortIdentity, messageId, timestamp, counter_value,
- last);
- }
- timestamp = clock->getSystemTime();
- return 0;
-}
-
-int IEEE1588Port::getRxTimestamp(PortIdentity * sourcePortIdentity,
- PTPMessageId messageId, Timestamp & timestamp,
- unsigned &counter_value, bool last)
-{
- if (_hw_timestamper) {
- return _hw_timestamper->HWTimestamper_rxtimestamp
- (sourcePortIdentity, messageId, timestamp, counter_value,
- last);
- }
- timestamp = clock->getSystemTime();
- return 0;
-}
-
-void IEEE1588Port::startSyncReceiptTimer(long long unsigned int waitTime) {
- syncReceiptTimerLock->lock();
- clock->deleteEventTimerLocked(this, SYNC_RECEIPT_TIMEOUT_EXPIRES);
- clock->addEventTimerLocked(this, SYNC_RECEIPT_TIMEOUT_EXPIRES, waitTime);
- syncReceiptTimerLock->unlock();
-}
-
-void IEEE1588Port::stopSyncReceiptTimer(void)
-{
- syncReceiptTimerLock->lock();
- clock->deleteEventTimerLocked(this, SYNC_RECEIPT_TIMEOUT_EXPIRES);
- syncReceiptTimerLock->unlock();
-}
-
-void IEEE1588Port::startSyncIntervalTimer(long long unsigned int waitTime)
-{
- syncIntervalTimerLock->lock();
- clock->deleteEventTimerLocked(this, SYNC_INTERVAL_TIMEOUT_EXPIRES);
- clock->addEventTimerLocked(this, SYNC_INTERVAL_TIMEOUT_EXPIRES, waitTime);
- syncIntervalTimerLock->unlock();
-}
-
-void IEEE1588Port::startAnnounceIntervalTimer(long long unsigned int waitTime)
-{
- announceIntervalTimerLock->lock();
- clock->deleteEventTimerLocked(this, ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES);
- clock->addEventTimerLocked(this, ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES, waitTime);
- announceIntervalTimerLock->unlock();
-}
-
-void IEEE1588Port::startPDelayIntervalTimer(long long unsigned int waitTime)
-{
- pDelayIntervalTimerLock->lock();
- clock->deleteEventTimerLocked(this, PDELAY_INTERVAL_TIMEOUT_EXPIRES);
- clock->addEventTimerLocked(this, PDELAY_INTERVAL_TIMEOUT_EXPIRES, waitTime);
- pDelayIntervalTimerLock->unlock();
-}
-
diff --git a/daemons/gptp/common/ptp_message.cpp b/daemons/gptp/common/ptp_message.cpp
index 309b5486..a5f3aadc 100644
--- a/daemons/gptp/common/ptp_message.cpp
+++ b/daemons/gptp/common/ptp_message.cpp
@@ -34,14 +34,14 @@
#include <ieee1588.hpp>
#include <avbts_clock.hpp>
#include <avbts_message.hpp>
-#include <avbts_port.hpp>
+#include <ether_port.hpp>
#include <avbts_ostimer.hpp>
#include <stdio.h>
#include <string.h>
#include <math.h>
-PTPMessageCommon::PTPMessageCommon(IEEE1588Port * port)
+PTPMessageCommon::PTPMessageCommon( CommonPort *port )
{
// Fill in fields using port/clock dataset as a template
versionPTP = GPTP_VERSION;
@@ -65,7 +65,8 @@ bool PTPMessageCommon::isSenderEqual(PortIdentity portIdentity)
}
PTPMessageCommon *buildPTPMessage
-(char *buf, int size, LinkLayerAddress * remote, IEEE1588Port * port)
+( char *buf, int size, LinkLayerAddress *remote,
+ EtherPort *port )
{
OSTimer *timer = port->getTimerFactory()->createTimer();
PTPMessageCommon *msg = NULL;
@@ -541,7 +542,7 @@ abort:
return NULL;
}
-void PTPMessageCommon::processMessage(IEEE1588Port * port)
+void PTPMessageCommon::processMessage( EtherPort *port )
{
_gc = true;
return;
@@ -665,7 +666,8 @@ PTPMessageSync::PTPMessageSync() {
PTPMessageSync::~PTPMessageSync() {
}
-PTPMessageSync::PTPMessageSync(IEEE1588Port * port) : PTPMessageCommon(port)
+PTPMessageSync::PTPMessageSync( EtherPort *port ) :
+ PTPMessageCommon( port )
{
messageType = SYNC_MESSAGE; // This is an event message
sequenceId = port->getNextSyncSequenceId();
@@ -679,7 +681,8 @@ PTPMessageSync::PTPMessageSync(IEEE1588Port * port) : PTPMessageCommon(port)
return;
}
-void PTPMessageSync::sendPort(IEEE1588Port * port, PortIdentity * destIdentity)
+void PTPMessageSync::sendPort
+( EtherPort *port, PortIdentity *destIdentity )
{
uint8_t buf_t[256];
uint8_t *buf_ptr = buf_t + port->getPayloadOffset();
@@ -714,8 +717,8 @@ void PTPMessageSync::sendPort(IEEE1588Port * port, PortIdentity * destIdentity)
return;
}
- PTPMessageAnnounce::PTPMessageAnnounce(IEEE1588Port * port) : PTPMessageCommon
- (port)
+PTPMessageAnnounce::PTPMessageAnnounce( CommonPort *port ) :
+ PTPMessageCommon( port )
{
messageType = ANNOUNCE_MESSAGE; // This is an event message
sequenceId = port->getNextAnnounceSequenceId();
@@ -740,8 +743,8 @@ void PTPMessageSync::sendPort(IEEE1588Port * port, PortIdentity * destIdentity)
return;
}
-void PTPMessageAnnounce::sendPort(IEEE1588Port * port,
- PortIdentity * destIdentity)
+void PTPMessageAnnounce::sendPort
+( CommonPort *port, PortIdentity *destIdentity )
{
uint8_t buf_t[256];
uint8_t *buf_ptr = buf_t + port->getPayloadOffset();
@@ -786,7 +789,7 @@ void PTPMessageAnnounce::sendPort(IEEE1588Port * port,
return;
}
-void PTPMessageAnnounce::processMessage(IEEE1588Port * port)
+void PTPMessageAnnounce::processMessage( EtherPort *port )
{
ClockIdentity my_clock_identity;
@@ -809,7 +812,7 @@ void PTPMessageAnnounce::processMessage(IEEE1588Port * port)
}
// Add message to the list
- port->addQualifiedAnnounce(this);
+ port->setQualifiedAnnounce( this );
port->getClock()->addEventTimerLocked(port, STATE_CHANGE_EVENT, 16000000);
bail:
@@ -823,7 +826,7 @@ void PTPMessageAnnounce::processMessage(IEEE1588Port * port)
1000000000.0)));
}
-void PTPMessageSync::processMessage(IEEE1588Port * port)
+void PTPMessageSync::processMessage( EtherPort *port )
{
if (port->getPortState() == PTP_DISABLED ) {
// Do nothing Sync messages should be ignored when in this state
@@ -856,8 +859,8 @@ void PTPMessageSync::processMessage(IEEE1588Port * port)
return;
}
- PTPMessageFollowUp::PTPMessageFollowUp(IEEE1588Port * port):PTPMessageCommon
- (port)
+PTPMessageFollowUp::PTPMessageFollowUp( EtherPort *port ) :
+ PTPMessageCommon( port )
{
messageType = FOLLOWUP_MESSAGE; /* This is an event message */
control = FOLLOWUP;
@@ -867,8 +870,8 @@ void PTPMessageSync::processMessage(IEEE1588Port * port)
return;
}
-void PTPMessageFollowUp::sendPort(IEEE1588Port * port,
- PortIdentity * destIdentity)
+void PTPMessageFollowUp::sendPort
+( EtherPort *port, PortIdentity *destIdentity )
{
uint8_t buf_t[256];
uint8_t *buf_ptr = buf_t + port->getPayloadOffset();
@@ -927,7 +930,7 @@ void PTPMessageFollowUp::sendPort(IEEE1588Port * port,
return;
}
-void PTPMessageFollowUp::processMessage(IEEE1588Port * port)
+void PTPMessageFollowUp::processMessage( EtherPort *port )
{
uint64_t delay;
Timestamp sync_arrival;
@@ -1096,8 +1099,8 @@ done:
return;
}
- PTPMessagePathDelayReq::PTPMessagePathDelayReq(IEEE1588Port * port):
- PTPMessageCommon (port)
+PTPMessagePathDelayReq::PTPMessagePathDelayReq
+( EtherPort *port ) : PTPMessageCommon( port )
{
logMeanMessageInterval = 0;
control = MESSAGE_OTHER;
@@ -1106,7 +1109,7 @@ done:
return;
}
-void PTPMessagePathDelayReq::processMessage(IEEE1588Port * port)
+void PTPMessagePathDelayReq::processMessage( EtherPort *port )
{
OSTimer *timer = port->getTimerFactory()->createTimer();
PortIdentity resp_fwup_id;
@@ -1228,8 +1231,8 @@ done:
return;
}
-void PTPMessagePathDelayReq::sendPort(IEEE1588Port * port,
- PortIdentity * destIdentity)
+void PTPMessagePathDelayReq::sendPort
+( EtherPort *port, PortIdentity *destIdentity )
{
if(port->pdelayHalted())
return;
@@ -1248,8 +1251,8 @@ void PTPMessagePathDelayReq::sendPort(IEEE1588Port * port,
return;
}
- PTPMessagePathDelayResp::PTPMessagePathDelayResp(IEEE1588Port * port) :
- PTPMessageCommon(port)
+PTPMessagePathDelayResp::PTPMessagePathDelayResp
+( EtherPort *port ) : PTPMessageCommon( port )
{
/*TODO: Why 0x7F?*/
logMeanMessageInterval = 0x7F;
@@ -1268,7 +1271,7 @@ PTPMessagePathDelayResp::~PTPMessagePathDelayResp()
delete requestingPortIdentity;
}
-void PTPMessagePathDelayResp::processMessage(IEEE1588Port * port)
+void PTPMessagePathDelayResp::processMessage( EtherPort *port )
{
if (port->getPortState() == PTP_DISABLED) {
// Do nothing all messages should be ignored when in this state
@@ -1346,8 +1349,8 @@ bypass_verify_duplicate:
return;
}
-void PTPMessagePathDelayResp::sendPort(IEEE1588Port * port,
- PortIdentity * destIdentity)
+void PTPMessagePathDelayResp::sendPort
+( EtherPort *port, PortIdentity *destIdentity )
{
uint8_t buf_t[256];
uint8_t *buf_ptr = buf_t + port->getPayloadOffset();
@@ -1406,7 +1409,7 @@ void PTPMessagePathDelayResp::getRequestingPortIdentity
}
PTPMessagePathDelayRespFollowUp::PTPMessagePathDelayRespFollowUp
-(IEEE1588Port * port) : PTPMessageCommon (port)
+( EtherPort *port ) : PTPMessageCommon( port )
{
logMeanMessageInterval = 0x7F;
control = MESSAGE_OTHER;
@@ -1423,7 +1426,8 @@ PTPMessagePathDelayRespFollowUp::~PTPMessagePathDelayRespFollowUp()
}
#define US_PER_SEC 1000000
-void PTPMessagePathDelayRespFollowUp::processMessage(IEEE1588Port * port)
+void PTPMessagePathDelayRespFollowUp::processMessage
+( EtherPort *port )
{
Timestamp remote_resp_tx_timestamp(0, 0, 0);
Timestamp request_tx_timestamp(0, 0, 0);
@@ -1666,8 +1670,8 @@ void PTPMessagePathDelayRespFollowUp::processMessage(IEEE1588Port * port)
return;
}
-void PTPMessagePathDelayRespFollowUp::sendPort(IEEE1588Port * port,
- PortIdentity * destIdentity)
+void PTPMessagePathDelayRespFollowUp::sendPort
+( EtherPort *port, PortIdentity *destIdentity )
{
uint8_t buf_t[256];
uint8_t *buf_ptr = buf_t + port->getPayloadOffset();
@@ -1727,7 +1731,8 @@ void PTPMessagePathDelayRespFollowUp::setRequestingPortIdentity
{
}
- PTPMessageSignalling::PTPMessageSignalling(IEEE1588Port * port) : PTPMessageCommon(port)
+PTPMessageSignalling::PTPMessageSignalling
+( EtherPort *port ) : PTPMessageCommon( port )
{
messageType = SIGNALLING_MESSAGE;
sequenceId = port->getNextSignalSequenceId();
@@ -1750,7 +1755,8 @@ void PTPMessageSignalling::setintervals(int8_t linkDelayInterval, int8_t timeSyn
tlv.setAnnounceInterval(announceInterval);
}
-void PTPMessageSignalling::sendPort(IEEE1588Port * port, PortIdentity * destIdentity)
+void PTPMessageSignalling::sendPort
+( EtherPort *port, PortIdentity *destIdentity )
{
uint8_t buf_t[256];
uint8_t *buf_ptr = buf_t + port->getPayloadOffset();
@@ -1771,7 +1777,7 @@ void PTPMessageSignalling::sendPort(IEEE1588Port * port, PortIdentity * destIden
port->sendGeneralPort(PTP_ETHERTYPE, buf_t, messageLength, MCAST_OTHER, destIdentity);
}
-void PTPMessageSignalling::processMessage(IEEE1588Port * port)
+void PTPMessageSignalling::processMessage( EtherPort *port )
{
long long unsigned int waitTime;
@@ -1806,7 +1812,7 @@ void PTPMessageSignalling::processMessage(IEEE1588Port * port)
}
if (timeSyncInterval == PTPMessageSignalling::sigMsgInterval_Initial) {
- port->setInitSyncInterval();
+ port->resetInitSyncInterval();
waitTime = ((long long) (pow((double)2, port->getSyncInterval()) * 1000000000.0));
waitTime = waitTime > EVENT_TIMER_GRANULARITY ? waitTime : EVENT_TIMER_GRANULARITY;
diff --git a/daemons/gptp/linux/build/Makefile b/daemons/gptp/linux/build/Makefile
index 4ab409be..1e00b1a5 100644
--- a/daemons/gptp/linux/build/Makefile
+++ b/daemons/gptp/linux/build/Makefile
@@ -56,7 +56,8 @@ OBJ_DIR = obj
OBJ_FILES = $(OBJ_DIR)/ptp_message.o\
$(OBJ_DIR)/ap_message.o\
$(OBJ_DIR)/avbts_osnet.o\
- $(OBJ_DIR)/ieee1588port.o\
+ $(OBJ_DIR)/ether_port.o\
+ $(OBJ_DIR)/common_port.o\
$(OBJ_DIR)/ieee1588clock.o \
$(OBJ_DIR)/linux_hal_common.o\
$(OBJ_DIR)/linux_hal_persist_file.o\
@@ -65,7 +66,8 @@ OBJ_FILES = $(OBJ_DIR)/ptp_message.o\
$(OBJ_DIR)/ini.o \
$(OBJ_DIR)/gptp_cfg.o
-HEADER_FILES = $(COMMON_DIR)/avbts_port.hpp\
+HEADER_FILES = $(COMMON_DIR)/ether_port.hpp\
+ $(COMMON_DIR)/common_port.hpp\
$(COMMON_DIR)/avbts_ostimerq.hpp\
$(COMMON_DIR)/avbts_ostimer.hpp\
$(COMMON_DIR)/avbts_osthread.hpp\
@@ -156,8 +158,11 @@ $(OBJ_DIR)/linux_hal_i210.o: $(SRC_DIR)/linux_hal_i210.cpp $(HEADER_FILES)
$(OBJ_DIR)/linux_hal_intelce.o: $(SRC_DIR)/linux_hal_intelce.cpp $(HEADER_FILES)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_DIR)/linux_hal_intelce.cpp -o $(OBJ_DIR)/linux_hal_intelce.o
-$(OBJ_DIR)/ieee1588port.o: $(COMMON_DIR)/ieee1588port.cpp $(HEADER_FILES)
- $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(COMMON_DIR)/ieee1588port.cpp -o $(OBJ_DIR)/ieee1588port.o
+$(OBJ_DIR)/ether_port.o: $(COMMON_DIR)/ether_port.cpp $(HEADER_FILES)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@
+
+$(OBJ_DIR)/common_port.o: $(COMMON_DIR)/common_port.cpp $(HEADER_FILES)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@
$(OBJ_DIR)/ieee1588clock.o: $(COMMON_DIR)/ieee1588clock.cpp $(HEADER_FILES)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(COMMON_DIR)/ieee1588clock.cpp -o $(OBJ_DIR)/ieee1588clock.o
diff --git a/daemons/gptp/linux/src/daemon_cl.cpp b/daemons/gptp/linux/src/daemon_cl.cpp
index d6a74cee..129fbd6b 100644
--- a/daemons/gptp/linux/src/daemon_cl.cpp
+++ b/daemons/gptp/linux/src/daemon_cl.cpp
@@ -125,11 +125,11 @@ int watchdog_setup(OSThreadFactory *thread_factory)
}
static IEEE1588Clock *pClock = NULL;
-static IEEE1588Port *pPort = NULL;
+static EtherPort *pPort = NULL;
int main(int argc, char **argv)
{
- IEEE1588PortInit_t portInit;
+ PortInit_t portInit;
sigset_t set;
InterfaceName *ifname;
@@ -176,9 +176,7 @@ int main(int argc, char **argv)
portInit.clock = NULL;
portInit.index = 0;
- portInit.forceSlave = false;
portInit.timestamper = NULL;
- portInit.offset = 0;
portInit.net_label = NULL;
portInit.automotive_profile = false;
portInit.isGM = false;
@@ -380,16 +378,14 @@ int main(int argc, char **argv)
// just set directly into the portInit struct.
portInit.clock = pClock;
portInit.index = 1;
- portInit.forceSlave = false;
portInit.timestamper = timestamper;
- portInit.offset = 0;
portInit.net_label = ifname;
portInit.condition_factory = condition_factory;
portInit.thread_factory = thread_factory;
portInit.timer_factory = timer_factory;
portInit.lock_factory = lock_factory;
- pPort = new IEEE1588Port(&portInit);
+ pPort = new EtherPort(&portInit);
if(use_config_file)
{
diff --git a/daemons/gptp/linux/src/linux_hal_common.cpp b/daemons/gptp/linux/src/linux_hal_common.cpp
index d63f1096..1db97012 100644
--- a/daemons/gptp/linux/src/linux_hal_common.cpp
+++ b/daemons/gptp/linux/src/linux_hal_common.cpp
@@ -34,7 +34,7 @@
#include <linux_hal_common.hpp>
#include <sys/types.h>
#include <avbts_clock.hpp>
-#include <avbts_port.hpp>
+#include <ether_port.hpp>
#include <pthread.h>
#include <linux_ipc.hpp>
@@ -168,7 +168,8 @@ void LinuxNetworkInterface::clear_reenable_rx_queue() {
}
}
-static void x_readEvent(int sockint, IEEE1588Port *pPort, int ifindex)
+static void x_readEvent
+( int sockint, EtherPort *pPort, int ifindex )
{
int status;
char buf[4096];
@@ -223,7 +224,7 @@ static void x_readEvent(int sockint, IEEE1588Port *pPort, int ifindex)
return;
}
-static void x_initLinkUpStatus(IEEE1588Port *pPort, int ifindex)
+static void x_initLinkUpStatus( EtherPort *pPort, int ifindex )
{
struct ifreq device;
memset(&device, 0, sizeof(device));
@@ -254,12 +255,20 @@ static void x_initLinkUpStatus(IEEE1588Port *pPort, int ifindex)
close(inetSocket);
}
-void LinuxNetworkInterface::watchNetLink(IEEE1588Port *pPort)
+void LinuxNetworkInterface::watchNetLink( CommonPort *iPort )
{
fd_set netLinkFD;
int netLinkSocket;
struct sockaddr_nl addr;
+ EtherPort *pPort =
+ dynamic_cast<EtherPort *>(iPort);
+ if( pPort == NULL )
+ {
+ GPTP_LOG_ERROR("NETLINK socket open error");
+ return;
+ }
+
netLinkSocket = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (netLinkSocket < 0) {
GPTP_LOG_ERROR("NETLINK socket open error");
diff --git a/daemons/gptp/linux/src/linux_hal_common.hpp b/daemons/gptp/linux/src/linux_hal_common.hpp
index 732dfc13..5ea3ff0a 100644
--- a/daemons/gptp/linux/src/linux_hal_common.hpp
+++ b/daemons/gptp/linux/src/linux_hal_common.hpp
@@ -203,7 +203,7 @@ public:
/**
* @brief Watch for net link changes.
*/
- virtual void watchNetLink(IEEE1588Port *pPort);
+ virtual void watchNetLink( CommonPort *pPort );
/**
* @brief Gets the payload offset
@@ -292,7 +292,8 @@ public:
* @param type OSLockType enumeration
* @return Pointer to OSLock object
*/
- OSLock * createLock(OSLockType type) {
+ OSLock * createLock( OSLockType type ) const
+ {
LinuxLock *lock = new LinuxLock();
if (lock->initialize(type) != oslock_ok) {
delete lock;
@@ -365,7 +366,8 @@ public:
* @brief Creates LinuxCondition objects
* @return Pointer to the OSCondition object in case of success. NULL otherwise
*/
- OSCondition * createCondition() {
+ OSCondition *createCondition() const
+ {
LinuxCondition *result = new LinuxCondition();
return result->initialize() ? result : NULL;
}
@@ -487,7 +489,8 @@ class LinuxTimerFactory : public OSTimerFactory {
* @brief Creates the linux timer
* @return Pointer to OSTimer object
*/
- virtual OSTimer * createTimer() {
+ virtual OSTimer *createTimer() const
+ {
return new LinuxTimer();
}
};
@@ -551,7 +554,7 @@ class LinuxThreadFactory:public OSThreadFactory {
* @brief Creates a new LinuxThread
* @return Pointer to LinuxThread object
*/
- OSThread * createThread() {
+ OSThread *createThread() const {
return new LinuxThread();
}
};
diff --git a/daemons/gptp/linux/src/linux_hal_generic.cpp b/daemons/gptp/linux/src/linux_hal_generic.cpp
index beb22024..4a3d187f 100644
--- a/daemons/gptp/linux/src/linux_hal_generic.cpp
+++ b/daemons/gptp/linux/src/linux_hal_generic.cpp
@@ -433,7 +433,8 @@ static inline Timestamp pctTimestamp( struct ptp_clock_time *t ) {
// Use HW cross-timestamp if available
bool LinuxTimestamperGeneric::HWTimestamper_gettime
( Timestamp *system_time, Timestamp *device_time, uint32_t *local_clock,
- uint32_t *nominal_clock_rate ) {
+ uint32_t *nominal_clock_rate ) const
+{
if( phc_fd == -1 )
return false;
diff --git a/daemons/gptp/linux/src/linux_hal_generic.hpp b/daemons/gptp/linux/src/linux_hal_generic.hpp
index da33efbf..2257bf55 100644
--- a/daemons/gptp/linux/src/linux_hal_generic.hpp
+++ b/daemons/gptp/linux/src/linux_hal_generic.hpp
@@ -137,8 +137,8 @@ public:
* @return TRUE if got the time successfully, FALSE otherwise
*/
virtual bool HWTimestamper_gettime
- ( Timestamp *system_time, Timestamp *device_time, uint32_t *local_clock,
- uint32_t *nominal_clock_rate );
+ ( Timestamp *system_time, Timestamp *device_time,
+ uint32_t *local_clock, uint32_t *nominal_clock_rate ) const;
/**
* @brief Gets the TX timestamp from hardware interface
diff --git a/daemons/gptp/windows/daemon_cl/daemon_cl.cpp b/daemons/gptp/windows/daemon_cl/daemon_cl.cpp
index 19f15e73..5e164b0d 100644
--- a/daemons/gptp/windows/daemon_cl/daemon_cl.cpp
+++ b/daemons/gptp/windows/daemon_cl/daemon_cl.cpp
@@ -80,13 +80,11 @@ int parseMacAddr( _TCHAR *macstr, uint8_t *octet_string ) {
int _tmain(int argc, _TCHAR* argv[])
{
- IEEE1588PortInit_t portInit;
+ PortInit_t portInit;
portInit.clock = NULL;
portInit.index = 1;
- portInit.forceSlave = false;
portInit.timestamper = NULL;
- portInit.offset = 0;
portInit.net_label = NULL;
portInit.automotive_profile = false;
portInit.isGM = false;
@@ -166,7 +164,7 @@ int _tmain(int argc, _TCHAR* argv[])
// Create Clock object
portInit.clock = new IEEE1588Clock( false, false, priority1, portInit.timestamper, timerq_factory, ipc, portInit.lock_factory ); // Do not force slave
// Create Port Object linked to clock and low level
- IEEE1588Port *port = new IEEE1588Port( &portInit );
+ EtherPort *port = new EtherPort( &portInit );
if (!port->init_port(phy_delays)) {
printf( "Failed to initialize port\n" );
return -1;
diff --git a/daemons/gptp/windows/daemon_cl/windows_hal.cpp b/daemons/gptp/windows/daemon_cl/windows_hal.cpp
index ede0fdb2..1911b278 100644
--- a/daemons/gptp/windows/daemon_cl/windows_hal.cpp
+++ b/daemons/gptp/windows/daemon_cl/windows_hal.cpp
@@ -192,7 +192,7 @@ bool WindowsNamedPipeIPC::update(int64_t ml_phoffset, int64_t ls_phoffset, Frequ
}
-void WindowsPCAPNetworkInterface::watchNetLink(IEEE1588Port *pPort)
+void WindowsPCAPNetworkInterface::watchNetLink( CommonPort *pPort)
{
/* ToDo add link up/down detection, Google MIB_IPADDR_DISCONNECTED */
}
diff --git a/daemons/gptp/windows/daemon_cl/windows_hal.hpp b/daemons/gptp/windows/daemon_cl/windows_hal.hpp
index f3f4eaca..03fdfb8a 100644
--- a/daemons/gptp/windows/daemon_cl/windows_hal.hpp
+++ b/daemons/gptp/windows/daemon_cl/windows_hal.hpp
@@ -110,7 +110,7 @@ public:
/**
* @brief Watch for netlink changes.
*/
- virtual void watchNetLink(IEEE1588Port *pPort);
+ virtual void watchNetLink( CommonPort *pPort );
/**
* @brief Gets the offset to the start of data in the Layer 2 Frame
@@ -258,7 +258,7 @@ public:
* @param type Lock type - OSLockType
* @return New lock on OSLock format
*/
- OSLock *createLock( OSLockType type ) {
+ OSLock *createLock( OSLockType type ) const {
WindowsLock *lock = new WindowsLock();
if( !lock->initialize( type )) {
delete lock;
@@ -327,7 +327,7 @@ public:
*/
class WindowsConditionFactory : public OSConditionFactory {
public:
- OSCondition *createCondition() {
+ OSCondition *createCondition() const {
WindowsCondition *result = new WindowsCondition();
return result->initialize() ? result : NULL;
}
@@ -514,7 +514,7 @@ public:
* @brief Creates a new timer
* @return New windows OSTimer
*/
- virtual OSTimer *createTimer() {
+ virtual OSTimer *createTimer() const {
return new WindowsTimer();
}
};
@@ -583,7 +583,7 @@ public:
* @brief Creates a new windows thread
* @return New thread of type OSThread
*/
- OSThread *createThread() {
+ OSThread *createThread() const {
return new WindowsThread();
}
};
@@ -633,7 +633,7 @@ private:
HANDLE miniport;
LARGE_INTEGER tsc_hz;
LARGE_INTEGER netclock_hz;
- DWORD readOID( NDIS_OID oid, void *output_buffer, DWORD size, DWORD *size_returned ) {
+ DWORD readOID( NDIS_OID oid, void *output_buffer, DWORD size, DWORD *size_returned ) const {
NDIS_OID oid_l = oid;
DWORD rc = DeviceIoControl(
miniport,
@@ -647,19 +647,19 @@ private:
if( rc == 0 ) return GetLastError();
return ERROR_SUCCESS;
}
- Timestamp nanoseconds64ToTimestamp( uint64_t time ) {
+ Timestamp nanoseconds64ToTimestamp( uint64_t time ) const {
Timestamp timestamp;
timestamp.nanoseconds = time % 1000000000;
timestamp.seconds_ls = (time / 1000000000) & 0xFFFFFFFF;
timestamp.seconds_ms = (uint16_t)((time / 1000000000) >> 32);
return timestamp;
}
- uint64_t scaleNativeClockToNanoseconds( uint64_t time ) {
+ uint64_t scaleNativeClockToNanoseconds( uint64_t time ) const {
long double scaled_output = ((long double)netclock_hz.QuadPart)/1000000000;
scaled_output = ((long double) time)/scaled_output;
return (uint64_t) scaled_output;
}
- uint64_t scaleTSCClockToNanoseconds( uint64_t time ) {
+ uint64_t scaleTSCClockToNanoseconds( uint64_t time ) const {
long double scaled_output = ((long double)tsc_hz.QuadPart)/1000000000;
scaled_output = ((long double) time)/scaled_output;
return (uint64_t) scaled_output;
@@ -686,7 +686,7 @@ public:
* @return True in case of success. FALSE in case of error
*/
virtual bool HWTimestamper_gettime( Timestamp *system_time, Timestamp *device_time, uint32_t *local_clock,
- uint32_t *nominal_clock_rate ) {
+ uint32_t *nominal_clock_rate ) const {
DWORD buf[6];
DWORD returned;
uint64_t now_net, now_tsc;