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/ntpclientquery.c
- Committer:
- andrewboyson
- Date:
- 2019-01-22
- Revision:
- 113:904b40231907
- Child:
- 116:60521b29e4c9
File content as of revision 113:904b40231907:
#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; }