static int64_t safeTimeDifference()

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;
}