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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ntpclientreply.c Source File

ntpclientreply.c

00001 #include <stdint.h>
00002 
00003 #include "ntpclient.h"
00004 #include "ntptimestamp.h"
00005 #include "ntphdr.h"
00006 #include "clktime.h"
00007 #include "clktm.h"
00008 #include "clkutc.h"
00009 #include "clkgov.h"
00010 #include "log.h"
00011 #include "net.h"
00012 
00013 int32_t NtpClientReplyOffsetMs;                           
00014 int32_t NtpClientReplyMaxDelayMs;   
00015 
00016 void NtpClientReply(void (*traceback)(void), char* pPacket)
00017 {
00018     if (NtpTrace)
00019     {
00020         if (NetTraceNewLine) Log("\r\n");
00021         LogTimeF("NTP received reply\r\n");
00022         if (NetTraceStack) traceback();
00023         NtpLogHeader(pPacket);
00024     }
00025     uint64_t ori = NtpHdrGetOriTimeStamp(pPacket);
00026     if (NtpClientQueryTime == 0 || ori != NtpClientQueryTime)
00027     {
00028         LogTimeF("NtpClient error: unsolicited reply\r\n");
00029         return;
00030     }
00031     
00032     uint64_t rec = NtpHdrGetRecTimeStamp(pPacket);
00033     int      li  = NtpHdrGetLI          (pPacket);
00034     
00035     //Check the received timestamp delay
00036     clktime oriTicks = NtpTimeStampToClkTime(ori);
00037     clktime ntpTicks = NtpTimeStampToClkTime(rec);
00038     clktime clkTicks = ClkTimeGet();  //Use the costly time this instant
00039     
00040     clktime roundTripTicks = clkTicks - oriTicks;
00041     clktime delayMs        = roundTripTicks >> CLK_TIME_ONE_MS_ISH_SHIFT;
00042     clktime limit          = NtpClientReplyMaxDelayMs;
00043     if (delayMs > limit)
00044     {
00045         LogTimeF("NtpClient error: delay %lld ms is greater than limit %lld ms\r\n", delayMs, limit);
00046         return; 
00047     }
00048     
00049     if (NtpClientTrace)
00050     {
00051         int64_t diffMs = (ntpTicks - clkTicks) >> CLK_TIME_ONE_MS_ISH_SHIFT;
00052         LogTimeF("NtpClient difference (ext-int) is %lld ms\r\n", diffMs);
00053     }
00054     
00055     //Handle the LI
00056     if (li == 3) 
00057     {
00058         LogTimeF("NtpClient error: NTP server is not synchronised (LI = 3)\r\n");
00059         return; 
00060     }
00061     if (li == 1 || li == 2)
00062     {
00063         struct tm tm;
00064         ClkTimeToTmUtc(clkTicks, &tm);
00065         int year1970 = tm.tm_year - 70; //1900
00066         int month    = tm.tm_mon;       //0 to 11
00067         ClkUtcSetNextEpochMonth1970(year1970 * 12 + month + 1); //+1 as new UTC epoch is at the start of next month
00068         ClkUtcSetNextLeapForward(li == 1);
00069         ClkUtcSetNextLeapEnable(true);
00070     }
00071     if (li == 0)
00072     {
00073         ClkUtcSetNextLeapEnable(false);
00074     }
00075     
00076     //Set the clock
00077     clktime offsetTime = NtpClientReplyOffsetMs << CLK_TIME_ONE_MS_ISH_SHIFT;
00078     ClkGovSyncTime(ntpTicks + offsetTime);
00079     
00080     //Tell the query service that the time has been updated
00081     NtpClientTimeUpdateSuccessful();
00082 }