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
Diff: udp/ntp/ntpclientquery.c
- Revision:
- 113:904b40231907
- Child:
- 116:60521b29e4c9
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/udp/ntp/ntpclientquery.c Tue Jan 22 15:41:12 2019 +0000 @@ -0,0 +1,150 @@ +#include <stdint.h> +#include <string.h> +#include <stdbool.h> + +#include "log.h" +#include "clk.h" +#include "mstimer.h" +#include "clktime.h" +#include "clkntp.h" +#include "clkutc.h" +#include "clkgov.h" +#include "clktm.h" +#include "net.h" +#include "ntp.h" +#include "ntpclient.h" +#include "dns.h" +#include "ip4.h" +#include "ar4.h" +#include "ar6.h" +#include "arp.h" +#include "eth.h" +#include "nr4.h" +#include "nr6.h" +#include "ip6addr.h" +#include "mac.h" +#include "action.h" + +#define ONE_BILLION 1000000000ULL +#define ONE_MILLION 1000000LL + +char NtpClientQueryServerName[DNS_MAX_LABEL_LENGTH+1]; +int32_t NtpClientQueryInitialInterval; +int32_t NtpClientQueryNormalInterval; +int32_t NtpClientQueryRetryInterval; + +bool NtpClientQuerySendRequestsViaIp4 = false; +uint32_t NtpClientQueryServerIp4; +char NtpClientQueryServerIp6[16]; + +static uint64_t startNtpMs = 0; +static int intervalTypeNtp = NTP_QUERY_INTERVAL_INITIAL; +static bool intervalCompleteNtp() +{ + uint32_t interval; + switch(intervalTypeNtp) + { + case NTP_QUERY_INTERVAL_INITIAL: interval = NtpClientQueryInitialInterval; break; + case NTP_QUERY_INTERVAL_NORMAL: interval = NtpClientQueryNormalInterval; break; + case NTP_QUERY_INTERVAL_RETRY: interval = NtpClientQueryRetryInterval; break; + } + return MsTimerHasElapsed(startNtpMs, interval * 1000); +} +void NtpClientQueryStartInterval(int type) +{ + startNtpMs = MsTimerCount; + intervalTypeNtp = type; +} + +static bool resolve4(char* server, uint32_t* pIp) +{ + //Check if have IP, if not, then request it and stop + Nr4NameToIp(server, pIp); + if (!*pIp) + { + Nr4MakeRequestForIpFromName(server); //The request is only repeated if made after a freeze time - call as often as you want. + return false; + } + + //Check if have MAC and, if not, request it and stop + char mac[6]; + Ar4IpToMac(*pIp, mac); + if (MacIsEmpty(mac)) + { + Ar4MakeRequestForMacFromIp(*pIp); //The request is only repeated if made after a freeze time - call as often as you want. + return false; + } + + return true; +} +static bool resolve6(char* server, char* ip) +{ + //Check if have IP, if not, then request it and stop + Nr6NameToIp(server, ip); + if (Ip6AddressIsEmpty(ip)) + { + Nr6MakeRequestForIpFromName(server); //The request is only repeated if made after a freeze time - call as often as you want. + return false; + } + + //Check if have MAC and, if not, request it and stop + char mac[6]; + Ar6IpToMac(ip, mac); + if (MacIsEmpty(mac)) + { + Ar6MakeRequestForMacFromIp(ip); //The request is only repeated if made after a freeze time - call as often as you want. + return false; + } + + return true; +} +static bool haveIpAndMac(int type) +{ + if (type == IPV4) return resolve4(NtpClientQueryServerName, &NtpClientQueryServerIp4); + else if (type == IPV6) return resolve6(NtpClientQueryServerName, NtpClientQueryServerIp6); + else return false; +} +void writeRequest(void* pPacket, int* pSize) +{ + struct NtpHeader* pHeader = (struct NtpHeader*)pPacket; + + pHeader->Mode = NTP_CLIENT; + pHeader->VN = 3; + pHeader->LI = 0; + pHeader->Stratum = 0; + pHeader->Poll = 0; + pHeader->Precision = 0; + pHeader->RootDelay = 0; + pHeader->Dispersion = 0; + pHeader->RefIdentifier[0] = 0; + pHeader->RefIdentifier[1] = 0; + pHeader->RefIdentifier[2] = 0; + pHeader->RefIdentifier[3] = 0; + pHeader->RefTimeStamp = 0; + pHeader->OriTimeStamp = 0; + pHeader->RecTimeStamp = 0; + pHeader->TraTimeStamp = NetToHost64(ClkTimeToNtpTimeStamp(ClkTimeGet())); + + *pSize = sizeof(struct NtpHeader); +} + +int NtpClientQueryPoll(int type, void* pPacket, int* pSize) +{ + if (NtpClientQueryServerName[0]) //An empty name means ntp client is not enabled + { + if (intervalCompleteNtp()) //Wait for the time out + { + bool isMulticast = NtpClientQueryServerName[0] == '*'; + if (isMulticast || haveIpAndMac(type)) + { + ClkGovIsReceivingTime = false; + NtpClientQueryStartInterval(NTP_QUERY_INTERVAL_RETRY); + writeRequest(pPacket, pSize); + + if (isMulticast) return MULTICAST_NTP; + else return UNICAST_NTP; + } + } + } + return DO_NOTHING; +} \ No newline at end of file