summaryrefslogtreecommitdiff
path: root/daemons/gptp/common/common_port.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'daemons/gptp/common/common_port.hpp')
-rw-r--r--daemons/gptp/common/common_port.hpp1455
1 files changed, 1455 insertions, 0 deletions
diff --git a/daemons/gptp/common/common_port.hpp b/daemons/gptp/common/common_port.hpp
new file mode 100644
index 00000000..d5d0adda
--- /dev/null
+++ b/daemons/gptp/common/common_port.hpp
@@ -0,0 +1,1455 @@
+/******************************************************************************
+
+ 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 <unordered_map>
+
+#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;
+ }
+};
+
+class phy_delay_spec_t;
+typedef std::unordered_map<uint32_t, phy_delay_spec_t> phy_delay_map_t;
+
+/**
+ * @brief Structure for initializing the port class
+ */
+typedef struct {
+ /* clock IEEE1588Clock instance */
+ IEEE1588Clock * clock;
+
+ /* index Interface index */
+ uint16_t index;
+
+ /* timestamper Hardware timestamper instance */
+ CommonTimestamper * 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 */
+ signed char initialLogSyncInterval;
+
+ /* gPTP 11.5.2.2 */
+ signed char initialLogPdelayReqInterval;
+
+ /* CDS 6.2.1.5 */
+ signed char operLogPdelayReqInterval;
+
+ /* CDS 6.2.1.6 */
+ signed 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;
+
+ /* phy delay */
+ phy_delay_map_t const *phy_delay;
+
+ /* sync receipt threshold */
+ unsigned int syncReceiptThreshold;
+
+ /* neighbor delay threshold */
+ int64_t neighborPropDelayThreshold;
+} 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;
+
+ /* Link speed in kb/sec */
+ uint32_t link_speed;
+
+ /* 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;
+
+ PortState port_state;
+ bool testMode;
+
+ signed char log_mean_sync_interval;
+ signed char log_mean_announce_interval;
+ signed 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 int64_t INVALID_LINKDELAY = 3600000000000;
+ static const int64_t ONE_WAY_DELAY_DEFAULT = INVALID_LINKDELAY;
+
+ OSThreadFactory const * const thread_factory;
+ OSTimerFactory const * const timer_factory;
+ OSLockFactory const * const lock_factory;
+ OSConditionFactory const * const condition_factory;
+ CommonTimestamper * const _hw_timestamper;
+ IEEE1588Clock * const clock;
+ const bool isGM;
+
+ phy_delay_map_t const * const phy_delay;
+
+public:
+ static const int64_t NEIGHBOR_PROP_DELAY_THRESH = 800;
+ static const unsigned int DEFAULT_SYNC_RECEIPT_THRESH = 5;
+
+ CommonPort( PortInit_t *portInit );
+ virtual ~CommonPort();
+
+ /**
+ * @brief Global media dependent port initialization
+ * @return true on success
+ */
+ bool init_port( void );
+
+ /**
+ * @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();
+
+ /**
+ * @brief Adjusts the clock frequency.
+ * @param freq_offset Frequency offset
+ * @return TRUE if adjusted. FALSE otherwise.
+ */
+ bool _adjustClockRate( FrequencyRatio freq_offset );
+
+ /**
+ * @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 Adjusts the clock phase.
+ * @param phase_adjust phase offset in ns
+ * @return TRUE if adjusted. FALSE otherwise.
+ */
+ bool adjustClockPhase( int64_t phase_adjust );
+
+ /**
+ * @brief Gets extended error message from hardware timestamper
+ * @param msg [out] Extended error message
+ * @return void
+ */
+ void getExtendedError(char *msg);
+
+ /**
+ * @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,
+ uint32_t &link_speed )
+ {
+ net_result result = net_iface->nrecv( addr, payload, length );
+ link_speed = this->link_speed;
+ return result;
+ }
+
+ /**
+ * @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
+ */
+ signed char getSyncInterval( void )
+ {
+ return log_mean_sync_interval;
+ }
+
+ /**
+ * @brief Sets the sync interval value
+ * @param val time interval
+ * @return none
+ */
+ void setSyncInterval( signed 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( signed char interval )
+ {
+ initialLogSyncInterval = interval;
+ }
+
+ /**
+ * @brief Gets the sync interval
+ * @return sync interval
+ */
+ signed char getInitSyncInterval( void )
+ {
+ return initialLogSyncInterval;
+ }
+
+ /**
+ * @brief Gets the announce interval
+ * @return Announce interval
+ */
+ signed char getAnnounceInterval( void ) {
+ return log_mean_announce_interval;
+ }
+
+ /**
+ * @brief Sets the announce interval
+ * @param val time interval
+ * @return none
+ */
+ void setAnnounceInterval(signed 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;
+
+ /**
+ * @brief Sets link speed
+ */
+ void setLinkSpeed( uint32_t link_speed )
+ {
+ this->link_speed = link_speed;
+ }
+
+ /**
+ * @brief Returns link speed
+ */
+ uint32_t getLinkSpeed( void )
+ {
+ return link_speed;
+ }
+
+ /**
+ * @brief Returns TX PHY delay
+ */
+ Timestamp getTxPhyDelay( uint32_t link_speed ) const;
+
+ /**
+ * @brief Returns RX PHY delay
+ */
+ Timestamp getRxPhyDelay( uint32_t link_speed ) const;
+};
+
+/**
+ * @brief Specifies a RX/TX PHY compensation pair
+ */
+class phy_delay_spec_t
+{
+private:
+ uint16_t tx_delay;
+ uint16_t rx_delay;
+public:
+ /**
+ * Constructor setting PHY compensation
+ */
+ phy_delay_spec_t(
+ uint16_t tx_delay,
+ uint16_t rx_delay )
+ {
+ this->tx_delay = tx_delay;
+ this->rx_delay = rx_delay;
+ }
+
+ /**
+ * Default constructor sets 0 PHY compensation
+ */
+ phy_delay_spec_t()
+ {
+ phy_delay_spec_t( 0, 0 );
+ }
+
+ /**
+ * @brief sets PHY compensation
+ */
+ void set_delay(
+ uint16_t tx_delay,
+ uint16_t rx_delay )
+ {
+ this->tx_delay = tx_delay;
+ this->rx_delay = rx_delay;
+ }
+
+ /**
+ * @brief sets RX PHY compensation
+ */
+ void set_tx_delay(
+ uint16_t tx_delay )
+ {
+ this->tx_delay = tx_delay;
+ }
+
+ /**
+ * @brief sets TX PHY compensation
+ */
+ void set_rx_delay(
+ uint16_t rx_delay )
+ {
+ this->rx_delay = rx_delay;
+ }
+
+ /**
+ * @brief gets TX PHY compensation
+ */
+ uint16_t get_tx_delay() const
+ {
+ return tx_delay;
+ }
+
+ /**
+ * @brief gets RX PHY compensation
+ */
+ uint16_t get_rx_delay() const
+ {
+ return rx_delay;
+ }
+};
+
+#endif/*COMMON_PORT_HPP*/