A stack which works with or without an Mbed os library. Provides IPv4 or IPv6 with a full 1500 byte buffer.

Dependents:   oldheating gps motorhome heating

udp/ntp/ntpclientreply.c

Committer:
andrewboyson
Date:
2019-01-22
Revision:
113:904b40231907
Child:
124:6e558721ec1c

File content as of revision 113:904b40231907:

#include <stdint.h>

#include "ntpclient.h"
#include "clkntp.h"
#include "clktime.h"
#include "clktm.h"
#include "clkutc.h"
#include "clkgov.h"
#include "log.h"
#include "net.h"

int32_t NtpClientReplyOffsetMs;                           
int32_t NtpClientReplyMaxDelayMs;   

void NtpClientReply(void (*traceback)(void), struct NtpHeader* pHeader)
{
    if (NtpTrace)
    {
        if (NetTraceNewLine) Log("\r\n");
        LogTimeF("NTP received reply\r\n");
        if (NetTraceStack) traceback();
        NtpLogHeader(pHeader);
    }
    
    uint64_t ori = NetToHost64(pHeader->OriTimeStamp);
    uint64_t rec = NetToHost64(pHeader->RecTimeStamp);
    int      li  =             pHeader->LI;
    
    //Check the received timestamp delay
    int64_t oriTicks = ClkTimeFromNtpTimeStamp(ori);
    int64_t ntpTicks = ClkTimeFromNtpTimeStamp(rec);
    int64_t clkTicks = ClkTimeGet();
    
    int64_t roundTripTicks = clkTicks - oriTicks;
    int64_t delayMs        = roundTripTicks >> CLK_TIME_ONE_MS_ISH_SHIFT;
    int64_t limit          = NtpClientReplyMaxDelayMs;
    if (delayMs > limit)
    {
        LogTimeF("NtpClient error: delay %lld ms is greater than limit %lld ms\r\n", delayMs, limit);
        return; 
    }
    
    if (NtpClientTrace)
    {
        int64_t diffMs = ((int64_t)(ntpTicks - clkTicks)) >> CLK_TIME_ONE_MS_ISH_SHIFT;
        LogTimeF("NtpClient difference (ext-int) is %lld ms\r\n", diffMs);
    }
    
    //Handle the LI
    if (li == 3) 
    {
        LogTimeF("NtpClient error: NTP server is not synchronised (LI = 3)\r\n");
        return; 
    }
    if (li == 1 || li == 2)
    {
        struct tm tm;
        ClkTimeToTmUtc(clkTicks, &tm);
        int year1970 = tm.tm_year - 70; //1900
        int month    = tm.tm_mon;       //0 to 11
        ClkUtcSetNextEpochMonth1970(year1970 * 12 + month + 1); //+1 as new UTC epoch is at the start of next month
        ClkUtcSetNextLeapForward(li == 1);
        ClkUtcSetNextLeapEnable(true);
    }
    if (li == 0)
    {
        ClkUtcSetNextLeapEnable(false);
    }
    
    //Set the clock
    int64_t offsetTime = NtpClientReplyOffsetMs << CLK_TIME_ONE_MS_ISH_SHIFT;
    ClkGovSyncTime(ntpTicks + offsetTime);
    
    //Tell the query service that the time has been updated
    NtpClientTimeUpdateSuccessful();
}