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 Dec 29 19:14:35 2020 +0000
Revision:
178:52714fef5ca1
Parent:
174:60e5ab296671
Child:
179:55342264fca1
Included host name in DHCP request option 12 to allow my Sky router to display the host name instead of 'UNKNOWN'. Also removed different host names for IPv4 and IPv6.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 61:aad055f1b0d1 1 #include <stdint.h>
andrewboyson 61:aad055f1b0d1 2 #include <stdbool.h>
andrewboyson 61:aad055f1b0d1 3 #include <string.h>
andrewboyson 61:aad055f1b0d1 4
andrewboyson 128:79052cb4a41c 5 #include "log.h"
andrewboyson 128:79052cb4a41c 6 #include "mstimer.h"
andrewboyson 128:79052cb4a41c 7 #include "net.h"
andrewboyson 178:52714fef5ca1 8 #include "net-this.h"
andrewboyson 128:79052cb4a41c 9 #include "action.h"
andrewboyson 128:79052cb4a41c 10 #include "eth.h"
andrewboyson 128:79052cb4a41c 11 #include "ip4addr.h"
andrewboyson 128:79052cb4a41c 12 #include "mac.h"
andrewboyson 128:79052cb4a41c 13 #include "udp.h"
andrewboyson 128:79052cb4a41c 14 #include "dnslabel.h"
andrewboyson 136:8a65abb0dc63 15 #include "dhcphdr.h"
andrewboyson 10:f0854784e960 16
andrewboyson 37:793b39683406 17 bool DhcpTrace = false;
andrewboyson 10:f0854784e960 18
andrewboyson 10:f0854784e960 19 #define REQUEST 1
andrewboyson 10:f0854784e960 20 #define REPLY 2
andrewboyson 10:f0854784e960 21
andrewboyson 10:f0854784e960 22 #define DHCPDISCOVER 1
andrewboyson 10:f0854784e960 23 #define DHCPOFFER 2
andrewboyson 10:f0854784e960 24 #define DHCPREQUEST 3
andrewboyson 10:f0854784e960 25 #define DHCPDECLINE 4
andrewboyson 10:f0854784e960 26 #define DHCPACK 5
andrewboyson 10:f0854784e960 27 #define DHCPNAK 6
andrewboyson 10:f0854784e960 28 #define DHCPRELEASE 7
andrewboyson 10:f0854784e960 29 #define DHCPINFORM 8
andrewboyson 10:f0854784e960 30
andrewboyson 10:f0854784e960 31 #define ID 75648
andrewboyson 10:f0854784e960 32 #define COOKIE 0x63825363
andrewboyson 10:f0854784e960 33
andrewboyson 116:60521b29e4c9 34 #define MAX_REPEAT_DELAY_TIME_MS 60000
andrewboyson 119:8e1a7805b801 35 #define MIN_REPEAT_DELAY_TIME_MS 900
andrewboyson 119:8e1a7805b801 36 static uint32_t repeatDelayMsTimer = (uint32_t)-MIN_REPEAT_DELAY_TIME_MS; //Initial value ensures no delay at startup
andrewboyson 119:8e1a7805b801 37 static uint32_t delayMs = MIN_REPEAT_DELAY_TIME_MS; //Doubles on failure up to max; reset to min whenever an IP address request has been acknowledged
andrewboyson 116:60521b29e4c9 38
andrewboyson 136:8a65abb0dc63 39 static uint32_t elapsedLifeMsTimer = 0; //Started whenever an IP address request has been acknowledged
andrewboyson 93:580fc113d9e9 40
andrewboyson 93:580fc113d9e9 41 uint32_t DhcpGetElapsedLife()
andrewboyson 10:f0854784e960 42 {
andrewboyson 119:8e1a7805b801 43 if (!elapsedLifeMsTimer) return 0;
andrewboyson 119:8e1a7805b801 44 return (MsTimerCount - elapsedLifeMsTimer) / 1000;
andrewboyson 10:f0854784e960 45 }
andrewboyson 10:f0854784e960 46
andrewboyson 10:f0854784e960 47 static uint8_t dhcpMessageType = 0;
andrewboyson 10:f0854784e960 48 uint32_t DhcpLeaseTime = 0;
andrewboyson 116:60521b29e4c9 49 uint32_t DhcpServerIp = 0;
andrewboyson 116:60521b29e4c9 50 uint32_t DhcpRouterIp = 0;
andrewboyson 10:f0854784e960 51 uint32_t DhcpSubnetMask = 0;
andrewboyson 116:60521b29e4c9 52 uint32_t DhcpNtpIp = 0;
andrewboyson 10:f0854784e960 53 uint32_t DhcpRenewalT1 = 0;
andrewboyson 10:f0854784e960 54 uint32_t DhcpRenewalT2 = 0;
andrewboyson 10:f0854784e960 55 uint32_t DhcpBroadcastIp = 0;
andrewboyson 10:f0854784e960 56 uint32_t DhcpLocalIp = 0;
andrewboyson 116:60521b29e4c9 57 uint32_t DhcpDnsServerIp = 0;
andrewboyson 128:79052cb4a41c 58 char DhcpDomainName[DNS_MAX_LABEL_LENGTH+1];
andrewboyson 128:79052cb4a41c 59 char DhcpHostName [DNS_MAX_LABEL_LENGTH+1];
andrewboyson 44:83ce5ace337b 60
andrewboyson 44:83ce5ace337b 61 bool DhcpIpNeedsToBeRouted(uint32_t ip)
andrewboyson 174:60e5ab296671 62 {
andrewboyson 174:60e5ab296671 63 if ((ip & 0x000000FF) == 0xFF) return false; //Broadcast 255.xxx.xxx.xxx
andrewboyson 174:60e5ab296671 64 if ((ip & 0x000000FF) == 0xE0) return false; //Multicast 224.xxx.xxx.xxx
andrewboyson 174:60e5ab296671 65 if (ip == (DhcpLocalIp | 0xFF000000)) return false; //Local broadcast ip == 192.168.0.255
andrewboyson 174:60e5ab296671 66
andrewboyson 174:60e5ab296671 67 return (ip & DhcpSubnetMask) != (DhcpLocalIp & DhcpSubnetMask); //ip != 192.168.0.xxx
andrewboyson 44:83ce5ace337b 68 }
andrewboyson 44:83ce5ace337b 69
andrewboyson 10:f0854784e960 70 static uint32_t readOption32(char** pp)
andrewboyson 10:f0854784e960 71 {
andrewboyson 10:f0854784e960 72 uint32_t value = 0;
andrewboyson 10:f0854784e960 73 char* p = *pp;
andrewboyson 10:f0854784e960 74 int len = *++p;
andrewboyson 10:f0854784e960 75 if (len >= 4)
andrewboyson 10:f0854784e960 76 {
andrewboyson 10:f0854784e960 77 value = *++p << 24;
andrewboyson 10:f0854784e960 78 value |= *++p << 16;
andrewboyson 10:f0854784e960 79 value |= *++p << 8;
andrewboyson 10:f0854784e960 80 value |= *++p << 0;
andrewboyson 10:f0854784e960 81 }
andrewboyson 10:f0854784e960 82 *pp += len + 1;
andrewboyson 10:f0854784e960 83 return value;
andrewboyson 10:f0854784e960 84 }
andrewboyson 10:f0854784e960 85 static uint32_t readIp(char** pp)
andrewboyson 10:f0854784e960 86 {
andrewboyson 10:f0854784e960 87 uint32_t value = 0;
andrewboyson 10:f0854784e960 88 char* p = *pp;
andrewboyson 10:f0854784e960 89 int len = *++p;
andrewboyson 10:f0854784e960 90 if (len >= 4)
andrewboyson 10:f0854784e960 91 {
andrewboyson 10:f0854784e960 92 value = *++p << 0;
andrewboyson 10:f0854784e960 93 value |= *++p << 8;
andrewboyson 10:f0854784e960 94 value |= *++p << 16;
andrewboyson 10:f0854784e960 95 value |= *++p << 24;
andrewboyson 10:f0854784e960 96 }
andrewboyson 10:f0854784e960 97 *pp += len + 1;
andrewboyson 10:f0854784e960 98 return value;
andrewboyson 10:f0854784e960 99 }
andrewboyson 10:f0854784e960 100 static void readString(char** pp, char* pText)
andrewboyson 10:f0854784e960 101 {
andrewboyson 10:f0854784e960 102 char* p = *pp;
andrewboyson 10:f0854784e960 103 int len = *++p;
andrewboyson 10:f0854784e960 104 for (int i = 0; i < len; i++) pText[i] = *++p;
andrewboyson 10:f0854784e960 105 *pp += len + 1;
andrewboyson 10:f0854784e960 106 }
andrewboyson 10:f0854784e960 107 static void readOptions(int size, char * pOptions)
andrewboyson 10:f0854784e960 108 {
andrewboyson 10:f0854784e960 109 int len = 0;
andrewboyson 10:f0854784e960 110 char* p = pOptions;
andrewboyson 10:f0854784e960 111 char* pE = pOptions + size;
andrewboyson 10:f0854784e960 112 while( p < pE)
andrewboyson 10:f0854784e960 113 {
andrewboyson 10:f0854784e960 114 switch (*p)
andrewboyson 10:f0854784e960 115 {
andrewboyson 10:f0854784e960 116 case 0: break; //NOP
andrewboyson 10:f0854784e960 117 case 255: return; //End of options
andrewboyson 136:8a65abb0dc63 118 case 1: DhcpSubnetMask = readIp(&p); break; //Subnet Mask
andrewboyson 136:8a65abb0dc63 119 case 3: DhcpRouterIp = readIp(&p); break; //Router
andrewboyson 136:8a65abb0dc63 120 case 6: DhcpDnsServerIp = readIp(&p); break; //DNS server
andrewboyson 10:f0854784e960 121 case 12: readString(&p, DhcpHostName); break; //Host name
andrewboyson 10:f0854784e960 122 case 15: readString(&p, DhcpDomainName); break; //Domain name
andrewboyson 10:f0854784e960 123 case 19: len = *++p; p+= len; break; //IP forwarding yes/no
andrewboyson 136:8a65abb0dc63 124 case 28: DhcpBroadcastIp = readIp(&p); break; //Broadcast IP
andrewboyson 136:8a65abb0dc63 125 case 42: DhcpNtpIp = readIp(&p); break; //NTP
andrewboyson 10:f0854784e960 126 case 44: len = *++p; p+= len; break; //NetBIOS name server
andrewboyson 10:f0854784e960 127 case 45: len = *++p; p+= len; break; //NetBIOS datagram server
andrewboyson 10:f0854784e960 128 case 46: len = *++p; p+= len; break; //NetBIOS node type
andrewboyson 10:f0854784e960 129 case 47: len = *++p; p+= len; break; //NetBIOS scope
andrewboyson 10:f0854784e960 130 case 53: len = *++p; dhcpMessageType = *++p; break; //DHCP message type
andrewboyson 10:f0854784e960 131 case 51: DhcpLeaseTime = readOption32(&p); break; //Address lease time
andrewboyson 116:60521b29e4c9 132 case 54: DhcpServerIp = readIp(&p); break; //DHCP server
andrewboyson 10:f0854784e960 133 case 58: DhcpRenewalT1 = readOption32(&p); break; //T1
andrewboyson 10:f0854784e960 134 case 59: DhcpRenewalT2 = readOption32(&p); break; //T2
andrewboyson 10:f0854784e960 135 default:
andrewboyson 37:793b39683406 136 if (DhcpTrace) LogTimeF("Ignoring option %d\r\n", *p);
andrewboyson 10:f0854784e960 137 len = *++p;
andrewboyson 10:f0854784e960 138 p += len;
andrewboyson 10:f0854784e960 139 return;
andrewboyson 10:f0854784e960 140 }
andrewboyson 10:f0854784e960 141 p++;
andrewboyson 10:f0854784e960 142 }
andrewboyson 10:f0854784e960 143 }
andrewboyson 10:f0854784e960 144 static void writeIp(uint8_t code, uint32_t value, char** pp)
andrewboyson 10:f0854784e960 145 {
andrewboyson 10:f0854784e960 146 if (!value) return;
andrewboyson 136:8a65abb0dc63 147
andrewboyson 10:f0854784e960 148 char* p = *pp;
andrewboyson 136:8a65abb0dc63 149
andrewboyson 10:f0854784e960 150 *p++ = code;
andrewboyson 10:f0854784e960 151 *p++ = 4;
andrewboyson 10:f0854784e960 152 *p++ = (value & 0x000000FF) >> 0;
andrewboyson 10:f0854784e960 153 *p++ = (value & 0x0000FF00) >> 8;
andrewboyson 10:f0854784e960 154 *p++ = (value & 0x00FF0000) >> 16;
andrewboyson 10:f0854784e960 155 *p++ = (value & 0xFF000000) >> 24;
andrewboyson 136:8a65abb0dc63 156
andrewboyson 10:f0854784e960 157 *pp += 6;
andrewboyson 10:f0854784e960 158 }
andrewboyson 178:52714fef5ca1 159 static void writeText(uint8_t code, const char* pText, char** pp)
andrewboyson 178:52714fef5ca1 160 {
andrewboyson 178:52714fef5ca1 161 if (!pText) return;
andrewboyson 178:52714fef5ca1 162 if (!*pText) return;
andrewboyson 178:52714fef5ca1 163
andrewboyson 178:52714fef5ca1 164 char* p = *pp;
andrewboyson 178:52714fef5ca1 165
andrewboyson 178:52714fef5ca1 166 *p++ = code;
andrewboyson 178:52714fef5ca1 167 char* pLength = p++;
andrewboyson 178:52714fef5ca1 168 while (true) //Copy pText without the end zero
andrewboyson 178:52714fef5ca1 169 {
andrewboyson 178:52714fef5ca1 170 *p = *pText;
andrewboyson 178:52714fef5ca1 171 pText++;
andrewboyson 178:52714fef5ca1 172 if (!*pText) break;
andrewboyson 178:52714fef5ca1 173 p++;
andrewboyson 178:52714fef5ca1 174 }
andrewboyson 178:52714fef5ca1 175
andrewboyson 178:52714fef5ca1 176 *pLength = p - pLength;
andrewboyson 178:52714fef5ca1 177
andrewboyson 178:52714fef5ca1 178 *pp += *pLength + 2;
andrewboyson 178:52714fef5ca1 179 }
andrewboyson 10:f0854784e960 180 int sendRequest(void* pPacket, uint8_t code, uint32_t srvIp, uint32_t reqIp)
andrewboyson 10:f0854784e960 181 {
andrewboyson 136:8a65abb0dc63 182
andrewboyson 10:f0854784e960 183 switch (code)
andrewboyson 10:f0854784e960 184 {
andrewboyson 10:f0854784e960 185 case DHCPDISCOVER:
andrewboyson 37:793b39683406 186 if (DhcpTrace) LogTimeF("DHCP -> discover");
andrewboyson 10:f0854784e960 187 break;
andrewboyson 10:f0854784e960 188 case DHCPREQUEST:
andrewboyson 37:793b39683406 189 if (DhcpTrace) LogTimeF("DHCP -> request");
andrewboyson 10:f0854784e960 190 break;
andrewboyson 10:f0854784e960 191 default:
andrewboyson 10:f0854784e960 192 LogTimeF("DHCP -> unknown message %d", code);
andrewboyson 10:f0854784e960 193 break;
andrewboyson 10:f0854784e960 194 }
andrewboyson 37:793b39683406 195 if (DhcpTrace)
andrewboyson 10:f0854784e960 196 {
andrewboyson 47:73af5c0b0dc2 197 Log(" server=" ); Ip4AddressLog(srvIp);
andrewboyson 47:73af5c0b0dc2 198 Log(" request="); Ip4AddressLog(reqIp);
andrewboyson 47:73af5c0b0dc2 199 Log(" local=" ); Ip4AddressLog(DhcpLocalIp);
andrewboyson 47:73af5c0b0dc2 200 Log("\r\n");
andrewboyson 10:f0854784e960 201 }
andrewboyson 136:8a65abb0dc63 202
andrewboyson 10:f0854784e960 203 bool broadcast = DhcpLocalIp == 0;
andrewboyson 10:f0854784e960 204 uint16_t flags = 0;
andrewboyson 136:8a65abb0dc63 205 if (broadcast) flags |= 0x8000;
andrewboyson 136:8a65abb0dc63 206 DhcpHdrSetOp (pPacket, REQUEST );
andrewboyson 136:8a65abb0dc63 207 DhcpHdrSetHtype (pPacket, ETHERNET );
andrewboyson 136:8a65abb0dc63 208 DhcpHdrSetHlen (pPacket, 6 );
andrewboyson 136:8a65abb0dc63 209 DhcpHdrSetHops (pPacket, 0 );
andrewboyson 136:8a65abb0dc63 210 DhcpHdrSetXid (pPacket, ID ); //Randomly chosed transaction id used to associate messages to responses
andrewboyson 136:8a65abb0dc63 211 DhcpHdrSetSecs (pPacket, 0 ); //Seconds since started to boot
andrewboyson 136:8a65abb0dc63 212 DhcpHdrSetFlags (pPacket, flags ); //Broadcast (1) Unicast (0)
andrewboyson 136:8a65abb0dc63 213 DhcpHdrSetCiaddr(pPacket, DhcpLocalIp ); //'Client' address set by client or 0 if don't know address
andrewboyson 136:8a65abb0dc63 214 DhcpHdrSetYiaddr(pPacket, 0 ); //'Your' address returned by server
andrewboyson 136:8a65abb0dc63 215 DhcpHdrSetSiaddr(pPacket, srvIp ); //'Server' address to use if required
andrewboyson 136:8a65abb0dc63 216 DhcpHdrSetGiaddr(pPacket, 0 ); //'Gateway' address
andrewboyson 136:8a65abb0dc63 217 memcpy(DhcpHdrPtrChaddr(pPacket), MacLocal, 6); //'Client hardware' address. 6 bytes for ethernet
andrewboyson 136:8a65abb0dc63 218 memset(DhcpHdrPtrLegacy(pPacket), 0, 192 ); //BootP legacy fill with zeros
andrewboyson 136:8a65abb0dc63 219 DhcpHdrSetCookie(pPacket, COOKIE ); //Magic cookie
andrewboyson 136:8a65abb0dc63 220
andrewboyson 136:8a65abb0dc63 221 char* pOptions = (char*)pPacket + DHCP_HEADER_LENGTH;
andrewboyson 10:f0854784e960 222 char* p = pOptions;
andrewboyson 10:f0854784e960 223 *p++ = 53; //Message code
andrewboyson 10:f0854784e960 224 *p++ = 1;
andrewboyson 10:f0854784e960 225 *p++ = code;
andrewboyson 136:8a65abb0dc63 226
andrewboyson 10:f0854784e960 227 writeIp(50, reqIp, &p); //Requested IP
andrewboyson 10:f0854784e960 228 writeIp(54, srvIp, &p); //Server ip
andrewboyson 178:52714fef5ca1 229
andrewboyson 178:52714fef5ca1 230 writeText(12, NET_NAME, &p);
andrewboyson 136:8a65abb0dc63 231
andrewboyson 10:f0854784e960 232 *p++ = 255; //End of options
andrewboyson 10:f0854784e960 233
andrewboyson 136:8a65abb0dc63 234 return DHCP_HEADER_LENGTH + p - pOptions;
andrewboyson 136:8a65abb0dc63 235 }
andrewboyson 136:8a65abb0dc63 236 int DhcpHandleResponse(void (*traceback)(void), int sizeRx, char* pPacketRx, int* pSizeTx, char* pPacketTx)
andrewboyson 136:8a65abb0dc63 237 {
andrewboyson 136:8a65abb0dc63 238 uint8_t op = DhcpHdrGetOp (pPacketRx);
andrewboyson 136:8a65abb0dc63 239 uint8_t htype = DhcpHdrGetHtype (pPacketRx);
andrewboyson 136:8a65abb0dc63 240 uint8_t hlen = DhcpHdrGetHlen (pPacketRx);
andrewboyson 136:8a65abb0dc63 241 uint32_t xid = DhcpHdrGetXid (pPacketRx); //Randomly chosen transaction id used to associate messages to responses
andrewboyson 136:8a65abb0dc63 242 uint32_t yiaddr = DhcpHdrGetYiaddr(pPacketRx);
andrewboyson 136:8a65abb0dc63 243 uint32_t siaddr = DhcpHdrGetSiaddr(pPacketRx);
andrewboyson 136:8a65abb0dc63 244 uint32_t cookie = DhcpHdrGetCookie(pPacketRx);
andrewboyson 136:8a65abb0dc63 245
andrewboyson 136:8a65abb0dc63 246 if (op != REPLY) return DO_NOTHING;
andrewboyson 136:8a65abb0dc63 247 if (htype != ETHERNET) return DO_NOTHING;
andrewboyson 136:8a65abb0dc63 248 if (hlen != 6) return DO_NOTHING;
andrewboyson 136:8a65abb0dc63 249 if (memcmp(DhcpHdrPtrChaddr(pPacketRx), MacLocal, 6)) return DO_NOTHING;
andrewboyson 136:8a65abb0dc63 250 if (xid != ID) return DO_NOTHING;
andrewboyson 136:8a65abb0dc63 251 if (cookie != COOKIE) return DO_NOTHING;
andrewboyson 136:8a65abb0dc63 252
andrewboyson 136:8a65abb0dc63 253 char* pOptions = (char*)pPacketRx + DHCP_HEADER_LENGTH;
andrewboyson 136:8a65abb0dc63 254 readOptions(sizeRx - DHCP_HEADER_LENGTH, pOptions);
andrewboyson 136:8a65abb0dc63 255
andrewboyson 10:f0854784e960 256 switch (dhcpMessageType)
andrewboyson 10:f0854784e960 257 {
andrewboyson 10:f0854784e960 258 case DHCPOFFER:
andrewboyson 47:73af5c0b0dc2 259 if (DhcpTrace) { LogTime("DHCP <- offer ip "); Ip4AddressLog(yiaddr); Log("\r\n"); }
andrewboyson 59:e0e556c8bd46 260 *pSizeTx = sendRequest(pPacketTx, DHCPREQUEST, siaddr, yiaddr);
andrewboyson 10:f0854784e960 261 return BROADCAST;
andrewboyson 10:f0854784e960 262 case DHCPACK:
andrewboyson 47:73af5c0b0dc2 263 if (DhcpTrace) { LogTime("DHCP <- ack ip "); Ip4AddressLog(yiaddr); Log("\r\n"); }
andrewboyson 10:f0854784e960 264 DhcpLocalIp = yiaddr;
andrewboyson 119:8e1a7805b801 265 elapsedLifeMsTimer = MsTimerCount; //Start the life timer
andrewboyson 116:60521b29e4c9 266 delayMs = MIN_REPEAT_DELAY_TIME_MS; //Set the delay time back to minimum
andrewboyson 10:f0854784e960 267 break;
andrewboyson 10:f0854784e960 268 case DHCPNAK:
andrewboyson 47:73af5c0b0dc2 269 if (DhcpTrace) { LogTime("DHCP <- nack ip "); Ip4AddressLog(yiaddr); Log("\r\n"); }
andrewboyson 10:f0854784e960 270 break;
andrewboyson 10:f0854784e960 271 default:
andrewboyson 10:f0854784e960 272 LogTimeF("DHCP <- unknown message %d\r\n", dhcpMessageType);
andrewboyson 10:f0854784e960 273 break;
andrewboyson 10:f0854784e960 274 }
andrewboyson 10:f0854784e960 275 return DO_NOTHING;
andrewboyson 10:f0854784e960 276 }
andrewboyson 10:f0854784e960 277
andrewboyson 10:f0854784e960 278 int DhcpPollForRequestToSend(void* pPacket, int* pSize)
andrewboyson 116:60521b29e4c9 279 {
andrewboyson 119:8e1a7805b801 280 //Check if time to update
andrewboyson 119:8e1a7805b801 281 uint32_t elapsedTimeMs = MsTimerCount - elapsedLifeMsTimer;
andrewboyson 93:580fc113d9e9 282 uint32_t leaseTimeMs = DhcpLeaseTime * 1000;
andrewboyson 93:580fc113d9e9 283
andrewboyson 119:8e1a7805b801 284 if (DhcpLocalIp && elapsedTimeMs < (leaseTimeMs >> 1)) return DO_NOTHING; //Do nothing if have address and within T1
andrewboyson 136:8a65abb0dc63 285
andrewboyson 119:8e1a7805b801 286 //Limit retries with a backoff delay
andrewboyson 133:a37eb35a03f1 287 if (!MsTimerRelative(repeatDelayMsTimer, delayMs)) return DO_NOTHING; //Don't retry within the delay time
andrewboyson 119:8e1a7805b801 288 delayMs <<= 1; //Backoff (double) the delay time after each attempt
andrewboyson 119:8e1a7805b801 289 if (delayMs > MAX_REPEAT_DELAY_TIME_MS) delayMs = MAX_REPEAT_DELAY_TIME_MS; //Don't go beyond a maximum
andrewboyson 119:8e1a7805b801 290 repeatDelayMsTimer = MsTimerCount; //Start the delay timer
andrewboyson 136:8a65abb0dc63 291
andrewboyson 119:8e1a7805b801 292 //Send the renewal request
andrewboyson 10:f0854784e960 293 *pSize = 0;
andrewboyson 37:793b39683406 294 int dest = DO_NOTHING;
andrewboyson 93:580fc113d9e9 295 if (DhcpLocalIp && elapsedTimeMs < leaseTimeMs)
andrewboyson 10:f0854784e960 296 {
andrewboyson 116:60521b29e4c9 297 *pSize = sendRequest(pPacket, DHCPREQUEST, DhcpServerIp, DhcpLocalIp); //if within T2 then send request to the server - not broadcast
andrewboyson 37:793b39683406 298 dest = UNICAST_DHCP;
andrewboyson 10:f0854784e960 299 }
andrewboyson 10:f0854784e960 300 else
andrewboyson 10:f0854784e960 301 {
andrewboyson 37:793b39683406 302 if (DhcpTrace) LogTimeF("DHCP lease has expired\r\n");
andrewboyson 10:f0854784e960 303 DhcpLocalIp = 0;
andrewboyson 116:60521b29e4c9 304 DhcpServerIp = 0;
andrewboyson 10:f0854784e960 305 *pSize = sendRequest(pPacket, DHCPDISCOVER, 0, 0); //If outside T2 then start from scratch to do a full DHCP
andrewboyson 37:793b39683406 306 dest = BROADCAST;
andrewboyson 10:f0854784e960 307 }
andrewboyson 37:793b39683406 308 return ActionMakeFromDestAndTrace(dest, DhcpTrace);
andrewboyson 136:8a65abb0dc63 309 }