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

Committer:
andrewboyson
Date:
Tue Jan 22 15:41:12 2019 +0000
Revision:
113:904b40231907
Child:
116:60521b29e4c9
Incorporated ntp server module

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 113:904b40231907 1 #include <stdint.h>
andrewboyson 113:904b40231907 2 #include <string.h>
andrewboyson 113:904b40231907 3 #include <stdbool.h>
andrewboyson 113:904b40231907 4
andrewboyson 113:904b40231907 5 #include "log.h"
andrewboyson 113:904b40231907 6 #include "clk.h"
andrewboyson 113:904b40231907 7 #include "mstimer.h"
andrewboyson 113:904b40231907 8 #include "clktime.h"
andrewboyson 113:904b40231907 9 #include "clkntp.h"
andrewboyson 113:904b40231907 10 #include "clkutc.h"
andrewboyson 113:904b40231907 11 #include "clkgov.h"
andrewboyson 113:904b40231907 12 #include "clktm.h"
andrewboyson 113:904b40231907 13 #include "net.h"
andrewboyson 113:904b40231907 14 #include "ntp.h"
andrewboyson 113:904b40231907 15 #include "ntpclient.h"
andrewboyson 113:904b40231907 16 #include "dns.h"
andrewboyson 113:904b40231907 17 #include "ip4.h"
andrewboyson 113:904b40231907 18 #include "ar4.h"
andrewboyson 113:904b40231907 19 #include "ar6.h"
andrewboyson 113:904b40231907 20 #include "arp.h"
andrewboyson 113:904b40231907 21 #include "eth.h"
andrewboyson 113:904b40231907 22 #include "nr4.h"
andrewboyson 113:904b40231907 23 #include "nr6.h"
andrewboyson 113:904b40231907 24 #include "ip6addr.h"
andrewboyson 113:904b40231907 25 #include "mac.h"
andrewboyson 113:904b40231907 26 #include "action.h"
andrewboyson 113:904b40231907 27
andrewboyson 113:904b40231907 28 #define ONE_BILLION 1000000000ULL
andrewboyson 113:904b40231907 29 #define ONE_MILLION 1000000LL
andrewboyson 113:904b40231907 30
andrewboyson 113:904b40231907 31 char NtpClientQueryServerName[DNS_MAX_LABEL_LENGTH+1];
andrewboyson 113:904b40231907 32 int32_t NtpClientQueryInitialInterval;
andrewboyson 113:904b40231907 33 int32_t NtpClientQueryNormalInterval;
andrewboyson 113:904b40231907 34 int32_t NtpClientQueryRetryInterval;
andrewboyson 113:904b40231907 35
andrewboyson 113:904b40231907 36 bool NtpClientQuerySendRequestsViaIp4 = false;
andrewboyson 113:904b40231907 37 uint32_t NtpClientQueryServerIp4;
andrewboyson 113:904b40231907 38 char NtpClientQueryServerIp6[16];
andrewboyson 113:904b40231907 39
andrewboyson 113:904b40231907 40 static uint64_t startNtpMs = 0;
andrewboyson 113:904b40231907 41 static int intervalTypeNtp = NTP_QUERY_INTERVAL_INITIAL;
andrewboyson 113:904b40231907 42 static bool intervalCompleteNtp()
andrewboyson 113:904b40231907 43 {
andrewboyson 113:904b40231907 44 uint32_t interval;
andrewboyson 113:904b40231907 45 switch(intervalTypeNtp)
andrewboyson 113:904b40231907 46 {
andrewboyson 113:904b40231907 47 case NTP_QUERY_INTERVAL_INITIAL: interval = NtpClientQueryInitialInterval; break;
andrewboyson 113:904b40231907 48 case NTP_QUERY_INTERVAL_NORMAL: interval = NtpClientQueryNormalInterval; break;
andrewboyson 113:904b40231907 49 case NTP_QUERY_INTERVAL_RETRY: interval = NtpClientQueryRetryInterval; break;
andrewboyson 113:904b40231907 50 }
andrewboyson 113:904b40231907 51 return MsTimerHasElapsed(startNtpMs, interval * 1000);
andrewboyson 113:904b40231907 52 }
andrewboyson 113:904b40231907 53 void NtpClientQueryStartInterval(int type)
andrewboyson 113:904b40231907 54 {
andrewboyson 113:904b40231907 55 startNtpMs = MsTimerCount;
andrewboyson 113:904b40231907 56 intervalTypeNtp = type;
andrewboyson 113:904b40231907 57 }
andrewboyson 113:904b40231907 58
andrewboyson 113:904b40231907 59 static bool resolve4(char* server, uint32_t* pIp)
andrewboyson 113:904b40231907 60 {
andrewboyson 113:904b40231907 61 //Check if have IP, if not, then request it and stop
andrewboyson 113:904b40231907 62 Nr4NameToIp(server, pIp);
andrewboyson 113:904b40231907 63 if (!*pIp)
andrewboyson 113:904b40231907 64 {
andrewboyson 113:904b40231907 65 Nr4MakeRequestForIpFromName(server); //The request is only repeated if made after a freeze time - call as often as you want.
andrewboyson 113:904b40231907 66 return false;
andrewboyson 113:904b40231907 67 }
andrewboyson 113:904b40231907 68
andrewboyson 113:904b40231907 69 //Check if have MAC and, if not, request it and stop
andrewboyson 113:904b40231907 70 char mac[6];
andrewboyson 113:904b40231907 71 Ar4IpToMac(*pIp, mac);
andrewboyson 113:904b40231907 72 if (MacIsEmpty(mac))
andrewboyson 113:904b40231907 73 {
andrewboyson 113:904b40231907 74 Ar4MakeRequestForMacFromIp(*pIp); //The request is only repeated if made after a freeze time - call as often as you want.
andrewboyson 113:904b40231907 75 return false;
andrewboyson 113:904b40231907 76 }
andrewboyson 113:904b40231907 77
andrewboyson 113:904b40231907 78 return true;
andrewboyson 113:904b40231907 79 }
andrewboyson 113:904b40231907 80 static bool resolve6(char* server, char* ip)
andrewboyson 113:904b40231907 81 {
andrewboyson 113:904b40231907 82 //Check if have IP, if not, then request it and stop
andrewboyson 113:904b40231907 83 Nr6NameToIp(server, ip);
andrewboyson 113:904b40231907 84 if (Ip6AddressIsEmpty(ip))
andrewboyson 113:904b40231907 85 {
andrewboyson 113:904b40231907 86 Nr6MakeRequestForIpFromName(server); //The request is only repeated if made after a freeze time - call as often as you want.
andrewboyson 113:904b40231907 87 return false;
andrewboyson 113:904b40231907 88 }
andrewboyson 113:904b40231907 89
andrewboyson 113:904b40231907 90 //Check if have MAC and, if not, request it and stop
andrewboyson 113:904b40231907 91 char mac[6];
andrewboyson 113:904b40231907 92 Ar6IpToMac(ip, mac);
andrewboyson 113:904b40231907 93 if (MacIsEmpty(mac))
andrewboyson 113:904b40231907 94 {
andrewboyson 113:904b40231907 95 Ar6MakeRequestForMacFromIp(ip); //The request is only repeated if made after a freeze time - call as often as you want.
andrewboyson 113:904b40231907 96 return false;
andrewboyson 113:904b40231907 97 }
andrewboyson 113:904b40231907 98
andrewboyson 113:904b40231907 99 return true;
andrewboyson 113:904b40231907 100 }
andrewboyson 113:904b40231907 101 static bool haveIpAndMac(int type)
andrewboyson 113:904b40231907 102 {
andrewboyson 113:904b40231907 103 if (type == IPV4) return resolve4(NtpClientQueryServerName, &NtpClientQueryServerIp4);
andrewboyson 113:904b40231907 104 else if (type == IPV6) return resolve6(NtpClientQueryServerName, NtpClientQueryServerIp6);
andrewboyson 113:904b40231907 105 else return false;
andrewboyson 113:904b40231907 106 }
andrewboyson 113:904b40231907 107 void writeRequest(void* pPacket, int* pSize)
andrewboyson 113:904b40231907 108 {
andrewboyson 113:904b40231907 109 struct NtpHeader* pHeader = (struct NtpHeader*)pPacket;
andrewboyson 113:904b40231907 110
andrewboyson 113:904b40231907 111 pHeader->Mode = NTP_CLIENT;
andrewboyson 113:904b40231907 112 pHeader->VN = 3;
andrewboyson 113:904b40231907 113 pHeader->LI = 0;
andrewboyson 113:904b40231907 114 pHeader->Stratum = 0;
andrewboyson 113:904b40231907 115 pHeader->Poll = 0;
andrewboyson 113:904b40231907 116 pHeader->Precision = 0;
andrewboyson 113:904b40231907 117 pHeader->RootDelay = 0;
andrewboyson 113:904b40231907 118 pHeader->Dispersion = 0;
andrewboyson 113:904b40231907 119 pHeader->RefIdentifier[0] = 0;
andrewboyson 113:904b40231907 120 pHeader->RefIdentifier[1] = 0;
andrewboyson 113:904b40231907 121 pHeader->RefIdentifier[2] = 0;
andrewboyson 113:904b40231907 122 pHeader->RefIdentifier[3] = 0;
andrewboyson 113:904b40231907 123 pHeader->RefTimeStamp = 0;
andrewboyson 113:904b40231907 124 pHeader->OriTimeStamp = 0;
andrewboyson 113:904b40231907 125 pHeader->RecTimeStamp = 0;
andrewboyson 113:904b40231907 126 pHeader->TraTimeStamp = NetToHost64(ClkTimeToNtpTimeStamp(ClkTimeGet()));
andrewboyson 113:904b40231907 127
andrewboyson 113:904b40231907 128 *pSize = sizeof(struct NtpHeader);
andrewboyson 113:904b40231907 129 }
andrewboyson 113:904b40231907 130
andrewboyson 113:904b40231907 131 int NtpClientQueryPoll(int type, void* pPacket, int* pSize)
andrewboyson 113:904b40231907 132 {
andrewboyson 113:904b40231907 133 if (NtpClientQueryServerName[0]) //An empty name means ntp client is not enabled
andrewboyson 113:904b40231907 134 {
andrewboyson 113:904b40231907 135 if (intervalCompleteNtp()) //Wait for the time out
andrewboyson 113:904b40231907 136 {
andrewboyson 113:904b40231907 137 bool isMulticast = NtpClientQueryServerName[0] == '*';
andrewboyson 113:904b40231907 138 if (isMulticast || haveIpAndMac(type))
andrewboyson 113:904b40231907 139 {
andrewboyson 113:904b40231907 140 ClkGovIsReceivingTime = false;
andrewboyson 113:904b40231907 141 NtpClientQueryStartInterval(NTP_QUERY_INTERVAL_RETRY);
andrewboyson 113:904b40231907 142 writeRequest(pPacket, pSize);
andrewboyson 113:904b40231907 143
andrewboyson 113:904b40231907 144 if (isMulticast) return MULTICAST_NTP;
andrewboyson 113:904b40231907 145 else return UNICAST_NTP;
andrewboyson 113:904b40231907 146 }
andrewboyson 113:904b40231907 147 }
andrewboyson 113:904b40231907 148 }
andrewboyson 113:904b40231907 149 return DO_NOTHING;
andrewboyson 113:904b40231907 150 }