summaryrefslogtreecommitdiff
path: root/daemons
diff options
context:
space:
mode:
authorPawel Modrzejewski <Pawel.Modrzejewski@harman.com>2017-05-12 11:17:42 +0200
committerPaweł Modrzejewski <pmodrzej@epf.pl>2017-05-17 21:46:34 +0200
commit1bc38706e7edfccfa0b7ddcbf0082ac29b22a130 (patch)
tree75ebb487302fe4a672cb842b7da0d4761fffd2b1 /daemons
parent402ce07d7547ced1e8e0582113acb1bb4aaaa591 (diff)
downloadOpen-AVB-1bc38706e7edfccfa0b7ddcbf0082ac29b22a130.tar.gz
gPTP: add negative time jumps detection
This change checks if time in follow_up messages is monotonic and will discard “wrong” sync/follow_up to prevent calculating incorrect values (ratio etc.). It was observed for some bridges and for some cases, that such situation might happens (bridge issue) and could lead to huge time instability, especially when syntonization functionality is activated.
Diffstat (limited to 'daemons')
-rw-r--r--daemons/gptp/common/avbts_clock.hpp3
-rw-r--r--daemons/gptp/common/ieee1588clock.cpp15
-rw-r--r--daemons/gptp/common/ptp_message.cpp18
3 files changed, 29 insertions, 7 deletions
diff --git a/daemons/gptp/common/avbts_clock.hpp b/daemons/gptp/common/avbts_clock.hpp
index 464b90d1..af6c89b3 100644
--- a/daemons/gptp/common/avbts_clock.hpp
+++ b/daemons/gptp/common/avbts_clock.hpp
@@ -61,6 +61,9 @@
adjustment is performed */
#define PHASE_ERROR_MAX_COUNT (6)
+/* Value returned by calcMasterLocalClockRateDifference() to indicate
+ detection of negative time jump in follow_up message */
+#define NEGATIVE_TIME_JUMP 0.0
/**
* @brief Provides the clock quality abstraction.
diff --git a/daemons/gptp/common/ieee1588clock.cpp b/daemons/gptp/common/ieee1588clock.cpp
index aae42dd1..4e9ae86e 100644
--- a/daemons/gptp/common/ieee1588clock.cpp
+++ b/daemons/gptp/common/ieee1588clock.cpp
@@ -322,8 +322,11 @@ FrequencyRatio IEEE1588Clock::calcMasterLocalClockRateDifference( Timestamp mast
inter_sync_time =
TIMESTAMP_TO_NS(sync_time) - TIMESTAMP_TO_NS(_prev_sync_time);
- inter_master_time =
- TIMESTAMP_TO_NS(master_time) - TIMESTAMP_TO_NS(_prev_master_time);
+
+ uint64_t master_time_ns = TIMESTAMP_TO_NS(master_time);
+ uint64_t prev_master_time_ns = TIMESTAMP_TO_NS(_prev_master_time);
+
+ inter_master_time = master_time_ns - prev_master_time_ns;
if( inter_sync_time != 0 ) {
ppt_offset = ((FrequencyRatio)inter_master_time)/inter_sync_time;
@@ -331,6 +334,14 @@ FrequencyRatio IEEE1588Clock::calcMasterLocalClockRateDifference( Timestamp mast
ppt_offset = 1.0;
}
+ if( master_time_ns < prev_master_time_ns ) {
+ GPTP_LOG_ERROR("Negative time jump detected - inter_master_time: %lld, inter_sync_time: %lld, icorrect ppt_offset: %Lf",
+ inter_master_time, inter_sync_time, ppt_offset);
+ _master_local_freq_offset_init = false;
+
+ return NEGATIVE_TIME_JUMP;
+ }
+
_prev_sync_time = sync_time;
_prev_master_time = master_time;
diff --git a/daemons/gptp/common/ptp_message.cpp b/daemons/gptp/common/ptp_message.cpp
index a31a24bc..fb7a63b9 100644
--- a/daemons/gptp/common/ptp_message.cpp
+++ b/daemons/gptp/common/ptp_message.cpp
@@ -1009,6 +1009,18 @@ void PTPMessageFollowUp::processMessage( EtherPort *port )
if( correction > 0 )
TIMESTAMP_ADD_NS( preciseOriginTimestamp, correction );
else TIMESTAMP_SUB_NS( preciseOriginTimestamp, -correction );
+
+ local_clock_adjustment =
+ port->getClock()->
+ calcMasterLocalClockRateDifference
+ ( preciseOriginTimestamp, sync_arrival );
+
+ if( local_clock_adjustment == NEGATIVE_TIME_JUMP )
+ {
+ GPTP_LOG_VERBOSE("Received Follow Up but preciseOrigintimestamp indicates negative time jump");
+ goto done;
+ }
+
scalar_offset = TIMESTAMP_TO_NS( sync_arrival );
scalar_offset -= TIMESTAMP_TO_NS( preciseOriginTimestamp );
@@ -1018,6 +1030,7 @@ void PTPMessageFollowUp::processMessage( EtherPort *port )
GPTP_LOG_VERBOSE
("FollowUp Scalar = %lld", scalar_offset);
+
/* Otherwise synchronize clock with approximate time from Sync message */
uint32_t local_clock, nominal_clock_rate;
uint32_t device_sync_time_offset;
@@ -1038,11 +1051,6 @@ void PTPMessageFollowUp::processMessage( EtherPort *port )
system_time.seconds_ls, system_time.nanoseconds,
device_time.seconds_ls, device_time.nanoseconds);
- local_clock_adjustment =
- port->getClock()->
- calcMasterLocalClockRateDifference
- ( preciseOriginTimestamp, sync_arrival );
-
/*Update information on local status structure.*/
scaledLastGmFreqChange = (int32_t)((1.0/local_clock_adjustment -1.0) * (1ULL << 41));
scaledLastGmPhaseChange.setLSB( tlv.getRateOffset() );