in source/core_sntp_serializer.c [312:390]
static int64_t safeTimeDifference( const SntpTimestamp_t * pServerTime,
const SntpTimestamp_t * pClientTime )
{
int64_t eraAdjustedDiff = 0;
/* Convert the timestamps into 64 bit signed integer values of milliseconds. */
int64_t serverTime = ( ( int64_t ) pServerTime->seconds * 1000 ) + ( int64_t ) fractionsToMs( pServerTime->fractions );
int64_t clientTime = ( ( int64_t ) pClientTime->seconds * 1000 ) + ( int64_t ) fractionsToMs( pClientTime->fractions );
/* The difference between the 2 timestamps is calculated by determining the whether the timestamps
* are present in the same NTP era or adjacent NTP eras (i.e. the NTP timestamp overflow case). */
/* First, calculate the first order time difference assuming that server and client times
* are in the same NTP era. */
int64_t diffWithNoEraAdjustment = serverTime - clientTime;
/* Store the absolute value of the time difference which will be used for comparison with
* different cases of relative NTP era configuration of client and server times. */
int64_t absSameEraDiff = absoluteOf( diffWithNoEraAdjustment );
/* If the absolute difference value is 2^31 seconds, it means that the server and client times are
* away by exactly half the range of SNTP timestamp "second" values representable in unsigned 32 bits.
* In such a case, irrespective of whether the 2 systems exist in the same or adjacent NTP eras, the
* time difference calculated between the systems will ALWAYS yield the same value when viewed from
* all NTP era configurations of the times.
* For such a case, we will ASSUME that the server time is AHEAD of client time, and thus, generate
* a positive clock-offset value.
*/
if( absSameEraDiff == CLOCK_OFFSET_MAX_TIME_DIFFERENCE )
{
/* It does not matter whether server and client are in the same era for this
* special case as the difference value for both same and adjacent eras will yield
* the same absolute value of 2^31.*/
eraAdjustedDiff = CLOCK_OFFSET_MAX_TIME_DIFFERENCE;
}
else
{
/* Determine if server time belongs to an NTP era different than the client time, and accordingly
* choose the 64 bit representation of the first order difference to account for the era.
* The logic for determining the relative era presence of the timestamps is by calculating the
* first order difference (of "Server Time - Client Time") for all the 3 different era combinations
* (1. both timestamps in same era, 2. server time one era ahead, 3. client time one era ahead)
* and choosing the NTP era configuration that has the smallest first order difference value.
*/
int64_t diffWithServerEraAdjustment = serverTime + TOTAL_MILLISECONDS_IN_NTP_ERA -
clientTime; /* This helps determine whether server is an
* era ahead of client time. */
int64_t diffWithClientEraAdjustment = serverTime -
( TOTAL_MILLISECONDS_IN_NTP_ERA + clientTime ); /* This helps determine whether server is an
* era behind of client time. */
/* Store the absolute value equivalents of all the time difference configurations
* for easier comparison to smallest value from them. */
int64_t absServerEraAheadDiff = absoluteOf( diffWithServerEraAdjustment );
int64_t absClientEraAheadDiff = absoluteOf( diffWithClientEraAdjustment );
/* Determine the correct relative era of client and server times by checking which era
* configuration of difference value represents the least difference. */
if( ( absSameEraDiff <= absServerEraAheadDiff ) && ( absSameEraDiff <= absClientEraAheadDiff ) )
{
/* Both server and client times are in the same era. */
eraAdjustedDiff = diffWithNoEraAdjustment;
}
/* Check if server time is an NTP era ahead of client time. */
else if( absServerEraAheadDiff < absSameEraDiff )
{
/* Server time is in NTP era 1 while client time is in NTP era 0. */
eraAdjustedDiff = diffWithServerEraAdjustment;
}
/* Now, we know that the client time is an era ahead of server time. */
else
{
/* Server time is in NTP era 0 while client time is in NTP era 1. */
eraAdjustedDiff = diffWithClientEraAdjustment;
}
}
return eraAdjustedDiff;
}