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
ntpserver.c
00001 #include <stdint.h> 00002 #include <stdlib.h> 00003 00004 #include "clk.h" 00005 #include "clkgov.h" 00006 #include "clktime.h" 00007 #include "clkutc.h" 00008 #include "ntptimestamp.h" 00009 #include "ntp.h" 00010 #include "ntphdr.h" 00011 #include "action.h" 00012 #include "log.h" 00013 #include "net.h" 00014 00015 #define LI_PRIOR_NOTICE_SECONDS 10LL * 24 * 60 * 60 00016 00017 bool NtpServerEnable = false; 00018 00019 char* NtpServerName = ""; 00020 00021 static int getPrecision() 00022 { 00023 /* 00024 The Precision field is set to reflect the maximum reading error of the local clock. 00025 For all practical cases it is computed as the negative of the number of significant bits 00026 to the right of the decimal point in the NTP timestamp format. 00027 While that could be CLK_TIME_ONE_SECOND_SHIFT I think that would be the resolution not the precision 00028 I therefore assume I can count on the clock to be good to about a microsecond or 2^-20 00029 */ 00030 return -20; 00031 } 00032 static int getLi() 00033 { 00034 if (!ClkTimeIsSet() ) return 3; //Alarm condition; clock is not synchronised 00035 if (!ClkUtcGetNextLeapEnable()) return 0; //No warning 00036 00037 clktime nowTime = ClkUtcFromTai(ClkNowTai()); //Use the less costly time this scan 00038 clktime liPriorNotice = LI_PRIOR_NOTICE_SECONDS << CLK_TIME_ONE_SECOND_SHIFT; 00039 00040 if (nowTime > ClkUtcGetNextEpoch() - liPriorNotice) 00041 { 00042 if (ClkUtcGetNextLeapForward()) return 1; //Last minute has 61 seconds 00043 else return 2; //Last minute has 59 seconds 00044 } 00045 else 00046 { 00047 return 0; //No warning 00048 } 00049 } 00050 00051 static int getStratum() 00052 { 00053 if (ClkTimeIsSet()) return 1; 00054 else return 0; 00055 } 00056 static char* getIdent() 00057 { 00058 if (!ClkTimeIsSet() ) return "INIT"; 00059 if (!ClkGovIsSynced()) return "LOCL"; 00060 return NtpServerName; 00061 } 00062 static uint64_t getRefNtp() 00063 { 00064 return NtpTimeStampFromClkTime(ClkRefTai()); 00065 } 00066 int NtpServerRequest(void (*traceback)(void), char* pPacketRx, char* pPacketTx) 00067 { 00068 if (!NtpServerEnable) return DO_NOTHING; 00069 00070 if (NtpTrace) 00071 { 00072 if (NetTraceNewLine) Log("\r\n"); 00073 LogTimeF("NTP received request\r\n"); 00074 if (NetTraceStack) traceback(); 00075 NtpLogHeader(pPacketRx); 00076 } 00077 00078 uint64_t refNtp = getRefNtp(); 00079 uint64_t nowNtp = NtpTimeStampFromClkTime(ClkTimeGet()); //use the costly time at this instant 00080 int stratum = getStratum(); 00081 char* ident = getIdent(); 00082 int li = getLi(); 00083 int precision = getPrecision(); 00084 00085 NtpHdrSetMode (pPacketTx, NTP_SERVER); 00086 NtpHdrSetVersion (pPacketTx, NtpHdrGetVersion(pPacketRx)); 00087 NtpHdrSetLI (pPacketTx, li); 00088 NtpHdrSetStratum (pPacketTx, stratum); 00089 NtpHdrSetPoll (pPacketTx, NtpHdrGetPoll(pPacketRx)); 00090 NtpHdrSetPrecision (pPacketTx, precision); 00091 NtpHdrSetRootDelay (pPacketTx, 0); 00092 NtpHdrSetDispersion (pPacketTx, 0); 00093 char* p = NtpHdrPtrRefIdentifier(pPacketTx); 00094 *p++ = ident[0]; //For stratum 1 (reference clock), this is a four-octet, left-justified, zero-padded ASCII string. 00095 *p++ = ident[1]; 00096 *p++ = ident[2]; 00097 *p = ident[3]; 00098 NtpHdrSetRefTimeStamp(pPacketTx, refNtp); 00099 NtpHdrSetOriTimeStamp(pPacketTx, NtpHdrGetTraTimeStamp(pPacketRx)); 00100 NtpHdrSetRecTimeStamp(pPacketTx, nowNtp); 00101 NtpHdrSetTraTimeStamp(pPacketTx, nowNtp); 00102 00103 if (NtpTrace) NtpLogHeader(pPacketTx); 00104 return UNICAST; 00105 } 00106
Generated on Tue Jul 12 2022 18:53:40 by 1.7.2