mbed OS5

Fork of UIPEthernet by Zoltan Hudak

Committer:
pilotak
Date:
Sun Aug 06 16:01:26 2017 +0000
Revision:
9:e55652bed36c
Parent:
8:4acb22344932
mBed OS5

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:5350a66d5279 1 // DHCP Library v0.3 - April 25, 2009
hudakz 0:5350a66d5279 2 // Author: Jordan Terrell - blog.jordanterrell.com
hudakz 0:5350a66d5279 3 #include <string.h>
hudakz 0:5350a66d5279 4 #include <stdlib.h>
hudakz 0:5350a66d5279 5 #include "Dhcp.h"
hudakz 4:d774541a34da 6 #include "utility/util.h"
hudakz 4:d774541a34da 7 #include "utility/millis.h"
hudakz 0:5350a66d5279 8
hudakz 0:5350a66d5279 9 /**
hudakz 0:5350a66d5279 10 * @brief
hudakz 0:5350a66d5279 11 * @note
hudakz 0:5350a66d5279 12 * @param
hudakz 0:5350a66d5279 13 * @retval
hudakz 0:5350a66d5279 14 */
hudakz 0:5350a66d5279 15 int DhcpClass::beginWithDHCP(uint8_t* mac, unsigned long timeout, unsigned long responseTimeout) {
hudakz 0:5350a66d5279 16 _dhcpLeaseTime = 0;
hudakz 0:5350a66d5279 17 _dhcpT1 = 0;
hudakz 0:5350a66d5279 18 _dhcpT2 = 0;
hudakz 0:5350a66d5279 19 _lastCheck = 0;
hudakz 0:5350a66d5279 20 _timeout = timeout;
hudakz 0:5350a66d5279 21 _responseTimeout = responseTimeout;
hudakz 0:5350a66d5279 22
hudakz 0:5350a66d5279 23 // zero out _dhcpMacAddr
hudakz 0:5350a66d5279 24 memset(_dhcpMacAddr, 0, 6);
hudakz 0:5350a66d5279 25 reset_DHCP_lease();
hudakz 0:5350a66d5279 26
hudakz 0:5350a66d5279 27 memcpy((void*)_dhcpMacAddr, (void*)mac, 6);
hudakz 0:5350a66d5279 28 _dhcp_state = STATE_DHCP_START;
hudakz 0:5350a66d5279 29 return request_DHCP_lease();
hudakz 0:5350a66d5279 30 }
hudakz 0:5350a66d5279 31
hudakz 0:5350a66d5279 32 /**
hudakz 0:5350a66d5279 33 * @brief
hudakz 0:5350a66d5279 34 * @note
hudakz 0:5350a66d5279 35 * @param
hudakz 0:5350a66d5279 36 * @retval
hudakz 0:5350a66d5279 37 */
hudakz 0:5350a66d5279 38 void DhcpClass::reset_DHCP_lease(void) {
hudakz 0:5350a66d5279 39
hudakz 0:5350a66d5279 40 // zero out _dhcpSubnetMask, _dhcpGatewayIp, _dhcpLocalIp, _dhcpDhcpServerIp, _dhcpDnsServerIp
hudakz 0:5350a66d5279 41
hudakz 0:5350a66d5279 42 memset(_dhcpLocalIp, 0, 20);
hudakz 0:5350a66d5279 43 }
hudakz 0:5350a66d5279 44
hudakz 0:5350a66d5279 45 //return:0 on error, 1 if request is sent and response is received
hudakz 0:5350a66d5279 46 int DhcpClass::request_DHCP_lease(void) {
hudakz 0:5350a66d5279 47 uint8_t messageType = 0;
hudakz 0:5350a66d5279 48
hudakz 0:5350a66d5279 49 // Pick an initial transaction ID
hudakz 0:5350a66d5279 50
hudakz 6:10e42359e217 51 _dhcpTransactionId = (rand() % 2000UL) + 1;
hudakz 0:5350a66d5279 52 _dhcpInitialTransactionId = _dhcpTransactionId;
hudakz 0:5350a66d5279 53
hudakz 0:5350a66d5279 54 _dhcpUdpSocket.stop();
hudakz 8:4acb22344932 55 if (_dhcpUdpSocket.begin(DHCP_CLIENT_PORT) == 0) {
hudakz 0:5350a66d5279 56
hudakz 0:5350a66d5279 57 // Couldn't get a socket
hudakz 0:5350a66d5279 58 return 0;
hudakz 0:5350a66d5279 59 }
hudakz 0:5350a66d5279 60
hudakz 0:5350a66d5279 61 presend_DHCP();
hudakz 0:5350a66d5279 62
hudakz 8:4acb22344932 63 volatile int result = 0;
hudakz 0:5350a66d5279 64
hudakz 4:d774541a34da 65 unsigned long startTime = millis();
hudakz 0:5350a66d5279 66
hudakz 8:4acb22344932 67 while (_dhcp_state != STATE_DHCP_LEASED) {
hudakz 8:4acb22344932 68 if (_dhcp_state == STATE_DHCP_START) {
hudakz 0:5350a66d5279 69 _dhcpTransactionId++;
hudakz 0:5350a66d5279 70
hudakz 4:d774541a34da 71 send_DHCP_MESSAGE(DHCP_DISCOVER, ((millis() - startTime) / 1000));
hudakz 0:5350a66d5279 72 _dhcp_state = STATE_DHCP_DISCOVER;
hudakz 0:5350a66d5279 73 }
hudakz 0:5350a66d5279 74 else
hudakz 8:4acb22344932 75 if (_dhcp_state == STATE_DHCP_REREQUEST) {
hudakz 0:5350a66d5279 76 _dhcpTransactionId++;
hudakz 4:d774541a34da 77 send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime) / 1000));
hudakz 0:5350a66d5279 78 _dhcp_state = STATE_DHCP_REQUEST;
hudakz 0:5350a66d5279 79 }
hudakz 0:5350a66d5279 80 else
hudakz 8:4acb22344932 81 if (_dhcp_state == STATE_DHCP_DISCOVER) {
hudakz 0:5350a66d5279 82 uint32_t respId;
hudakz 0:5350a66d5279 83 messageType = parseDHCPResponse(_responseTimeout, respId);
hudakz 8:4acb22344932 84 if (messageType == DHCP_OFFER) {
hudakz 0:5350a66d5279 85
hudakz 0:5350a66d5279 86 // We'll use the transaction ID that the offer came with,
hudakz 0:5350a66d5279 87 // rather than the one we were up to
hudakz 0:5350a66d5279 88 _dhcpTransactionId = respId;
hudakz 4:d774541a34da 89 send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime) / 1000));
hudakz 0:5350a66d5279 90 _dhcp_state = STATE_DHCP_REQUEST;
hudakz 0:5350a66d5279 91 }
hudakz 0:5350a66d5279 92 }
hudakz 0:5350a66d5279 93 else
hudakz 8:4acb22344932 94 if (_dhcp_state == STATE_DHCP_REQUEST) {
hudakz 0:5350a66d5279 95 uint32_t respId;
hudakz 0:5350a66d5279 96 messageType = parseDHCPResponse(_responseTimeout, respId);
hudakz 8:4acb22344932 97 if (messageType == DHCP_ACK) {
hudakz 0:5350a66d5279 98 _dhcp_state = STATE_DHCP_LEASED;
hudakz 0:5350a66d5279 99 result = 1;
hudakz 0:5350a66d5279 100
hudakz 0:5350a66d5279 101 //use default lease time if we didn't get it
hudakz 8:4acb22344932 102 if (_dhcpLeaseTime == 0) {
hudakz 0:5350a66d5279 103 _dhcpLeaseTime = DEFAULT_LEASE;
hudakz 0:5350a66d5279 104 }
hudakz 0:5350a66d5279 105
hudakz 0:5350a66d5279 106 //calculate T1 & T2 if we didn't get it
hudakz 8:4acb22344932 107 if (_dhcpT1 == 0) {
hudakz 0:5350a66d5279 108
hudakz 0:5350a66d5279 109 //T1 should be 50% of _dhcpLeaseTime
hudakz 0:5350a66d5279 110 _dhcpT1 = _dhcpLeaseTime >> 1;
hudakz 0:5350a66d5279 111 }
hudakz 0:5350a66d5279 112
hudakz 8:4acb22344932 113 if (_dhcpT2 == 0) {
hudakz 0:5350a66d5279 114
hudakz 0:5350a66d5279 115 //T2 should be 87.5% (7/8ths) of _dhcpLeaseTime
hudakz 0:5350a66d5279 116 _dhcpT2 = _dhcpT1 << 1;
hudakz 0:5350a66d5279 117 }
hudakz 0:5350a66d5279 118
hudakz 0:5350a66d5279 119 _renewInSec = _dhcpT1;
hudakz 0:5350a66d5279 120 _rebindInSec = _dhcpT2;
hudakz 0:5350a66d5279 121 }
hudakz 0:5350a66d5279 122 else
hudakz 8:4acb22344932 123 if (messageType == DHCP_NAK)
hudakz 0:5350a66d5279 124 _dhcp_state = STATE_DHCP_START;
hudakz 0:5350a66d5279 125 }
hudakz 0:5350a66d5279 126
hudakz 8:4acb22344932 127 if (messageType == 255) {
hudakz 0:5350a66d5279 128 messageType = 0;
hudakz 0:5350a66d5279 129 _dhcp_state = STATE_DHCP_START;
hudakz 0:5350a66d5279 130 }
hudakz 0:5350a66d5279 131
hudakz 8:4acb22344932 132 if ((result != 1) && ((millis() - startTime) > _timeout))
hudakz 0:5350a66d5279 133 break;
hudakz 0:5350a66d5279 134 }
hudakz 0:5350a66d5279 135
hudakz 0:5350a66d5279 136 // We're done with the socket now
hudakz 0:5350a66d5279 137 _dhcpUdpSocket.stop();
hudakz 0:5350a66d5279 138 _dhcpTransactionId++;
hudakz 0:5350a66d5279 139
hudakz 0:5350a66d5279 140 return result;
hudakz 0:5350a66d5279 141 }
hudakz 0:5350a66d5279 142
hudakz 0:5350a66d5279 143 /**
hudakz 0:5350a66d5279 144 * @brief
hudakz 0:5350a66d5279 145 * @note
hudakz 0:5350a66d5279 146 * @param
hudakz 0:5350a66d5279 147 * @retval
hudakz 0:5350a66d5279 148 */
hudakz 0:5350a66d5279 149 void DhcpClass::presend_DHCP(void)
hudakz 0:5350a66d5279 150 { }
hudakz 0:5350a66d5279 151
hudakz 0:5350a66d5279 152 /**
hudakz 0:5350a66d5279 153 * @brief
hudakz 0:5350a66d5279 154 * @note
hudakz 0:5350a66d5279 155 * @param
hudakz 0:5350a66d5279 156 * @retval
hudakz 0:5350a66d5279 157 */
hudakz 0:5350a66d5279 158 void DhcpClass::send_DHCP_MESSAGE(uint8_t messageType, uint16_t secondsElapsed) {
hudakz 0:5350a66d5279 159 uint8_t buffer[32];
hudakz 0:5350a66d5279 160 memset(buffer, 0, 32);
hudakz 0:5350a66d5279 161
hudakz 0:5350a66d5279 162 IPAddress dest_addr(255, 255, 255, 255); // Broadcast address
hudakz 0:5350a66d5279 163
hudakz 8:4acb22344932 164 if (-1 == _dhcpUdpSocket.beginPacket(dest_addr, DHCP_SERVER_PORT)) {
hudakz 0:5350a66d5279 165
hudakz 0:5350a66d5279 166 // FIXME Need to return errors
hudakz 0:5350a66d5279 167 return;
hudakz 0:5350a66d5279 168 }
hudakz 0:5350a66d5279 169
hudakz 0:5350a66d5279 170 buffer[0] = DHCP_BOOTREQUEST; // op
hudakz 0:5350a66d5279 171 buffer[1] = DHCP_HTYPE10MB; // htype
hudakz 0:5350a66d5279 172 buffer[2] = DHCP_HLENETHERNET; // hlen
hudakz 0:5350a66d5279 173 buffer[3] = DHCP_HOPS; // hops
hudakz 0:5350a66d5279 174
hudakz 0:5350a66d5279 175 // xid
hudakz 0:5350a66d5279 176 unsigned long xid = htonl(_dhcpTransactionId);
hudakz 0:5350a66d5279 177 memcpy(buffer + 4, &(xid), 4);
hudakz 0:5350a66d5279 178
hudakz 0:5350a66d5279 179 // 8, 9 - seconds elapsed
hudakz 0:5350a66d5279 180 buffer[8] = ((secondsElapsed & 0xff00) >> 8);
hudakz 0:5350a66d5279 181 buffer[9] = (secondsElapsed & 0x00ff);
hudakz 0:5350a66d5279 182
hudakz 0:5350a66d5279 183 // flags
hudakz 0:5350a66d5279 184 unsigned short flags = htons(DHCP_FLAGSBROADCAST);
hudakz 0:5350a66d5279 185 memcpy(buffer + 10, &(flags), 2);
hudakz 0:5350a66d5279 186
hudakz 0:5350a66d5279 187 // ciaddr: already zeroed
hudakz 0:5350a66d5279 188 // yiaddr: already zeroed
hudakz 0:5350a66d5279 189 // siaddr: already zeroed
hudakz 0:5350a66d5279 190 // giaddr: already zeroed
hudakz 0:5350a66d5279 191 //put data in W5100 transmit buffer
hudakz 0:5350a66d5279 192 _dhcpUdpSocket.write(buffer, 28);
hudakz 0:5350a66d5279 193
hudakz 0:5350a66d5279 194 memset(buffer, 0, 32); // clear local buffer
hudakz 0:5350a66d5279 195 memcpy(buffer, _dhcpMacAddr, 6); // chaddr
hudakz 0:5350a66d5279 196
hudakz 0:5350a66d5279 197 //put data in W5100 transmit buffer
hudakz 0:5350a66d5279 198 _dhcpUdpSocket.write(buffer, 16);
hudakz 0:5350a66d5279 199
hudakz 0:5350a66d5279 200 memset(buffer, 0, 32); // clear local buffer
hudakz 0:5350a66d5279 201
hudakz 0:5350a66d5279 202 // leave zeroed out for sname && file
hudakz 0:5350a66d5279 203 // put in W5100 transmit buffer x 6 (192 bytes)
hudakz 8:4acb22344932 204 for (int i = 0; i < 6; i++) {
hudakz 0:5350a66d5279 205 _dhcpUdpSocket.write(buffer, 32);
hudakz 0:5350a66d5279 206 }
hudakz 0:5350a66d5279 207
hudakz 0:5350a66d5279 208 // OPT - Magic Cookie
hudakz 0:5350a66d5279 209 buffer[0] = (uint8_t) ((MAGIC_COOKIE >> 24) & 0xFF);
hudakz 0:5350a66d5279 210 buffer[1] = (uint8_t) ((MAGIC_COOKIE >> 16) & 0xFF);
hudakz 0:5350a66d5279 211 buffer[2] = (uint8_t) ((MAGIC_COOKIE >> 8) & 0xFF);
hudakz 0:5350a66d5279 212 buffer[3] = (uint8_t) (MAGIC_COOKIE & 0xFF);
hudakz 0:5350a66d5279 213
hudakz 0:5350a66d5279 214 // OPT - message type
hudakz 0:5350a66d5279 215 buffer[4] = dhcpMessageType;
hudakz 0:5350a66d5279 216 buffer[5] = 0x01;
hudakz 0:5350a66d5279 217 buffer[6] = messageType; //DHCP_REQUEST;
hudakz 0:5350a66d5279 218
hudakz 0:5350a66d5279 219 // OPT - client identifier
hudakz 0:5350a66d5279 220 buffer[7] = dhcpClientIdentifier;
hudakz 0:5350a66d5279 221 buffer[8] = 0x07;
hudakz 0:5350a66d5279 222 buffer[9] = 0x01;
hudakz 0:5350a66d5279 223 memcpy(buffer + 10, _dhcpMacAddr, 6);
hudakz 0:5350a66d5279 224
hudakz 0:5350a66d5279 225 // OPT - host name
hudakz 0:5350a66d5279 226 buffer[16] = hostName;
hudakz 0:5350a66d5279 227 buffer[17] = strlen(HOST_NAME) + 6; // length of hostname + last 3 bytes of mac address
hudakz 0:5350a66d5279 228 strcpy((char*) &(buffer[18]), HOST_NAME);
hudakz 0:5350a66d5279 229
hudakz 0:5350a66d5279 230 printByte((char*) &(buffer[24]), _dhcpMacAddr[3]);
hudakz 0:5350a66d5279 231 printByte((char*) &(buffer[26]), _dhcpMacAddr[4]);
hudakz 0:5350a66d5279 232 printByte((char*) &(buffer[28]), _dhcpMacAddr[5]);
hudakz 0:5350a66d5279 233
hudakz 0:5350a66d5279 234 //put data in W5100 transmit buffer
hudakz 0:5350a66d5279 235 _dhcpUdpSocket.write(buffer, 30);
hudakz 0:5350a66d5279 236
hudakz 8:4acb22344932 237 if (messageType == DHCP_REQUEST) {
hudakz 0:5350a66d5279 238 buffer[0] = dhcpRequestedIPaddr;
hudakz 0:5350a66d5279 239 buffer[1] = 0x04;
hudakz 0:5350a66d5279 240 buffer[2] = _dhcpLocalIp[0];
hudakz 0:5350a66d5279 241 buffer[3] = _dhcpLocalIp[1];
hudakz 0:5350a66d5279 242 buffer[4] = _dhcpLocalIp[2];
hudakz 0:5350a66d5279 243 buffer[5] = _dhcpLocalIp[3];
hudakz 0:5350a66d5279 244
hudakz 0:5350a66d5279 245 buffer[6] = dhcpServerIdentifier;
hudakz 0:5350a66d5279 246 buffer[7] = 0x04;
hudakz 8:4acb22344932 247
hudakz 7:1bc7e6120801 248 //buffer[8] = _dhcpDhcpServerIp[0];
hudakz 7:1bc7e6120801 249 buffer[8] = _dhcpLocalIp[0];
hudakz 0:5350a66d5279 250 buffer[9] = _dhcpDhcpServerIp[1];
hudakz 0:5350a66d5279 251 buffer[10] = _dhcpDhcpServerIp[2];
hudakz 0:5350a66d5279 252 buffer[11] = _dhcpDhcpServerIp[3];
hudakz 0:5350a66d5279 253
hudakz 0:5350a66d5279 254 //put data in W5100 transmit buffer
hudakz 0:5350a66d5279 255 _dhcpUdpSocket.write(buffer, 12);
hudakz 0:5350a66d5279 256 }
hudakz 0:5350a66d5279 257
hudakz 0:5350a66d5279 258 buffer[0] = dhcpParamRequest;
hudakz 0:5350a66d5279 259 buffer[1] = 0x06;
hudakz 0:5350a66d5279 260 buffer[2] = subnetMask;
hudakz 0:5350a66d5279 261 buffer[3] = routersOnSubnet;
hudakz 0:5350a66d5279 262 buffer[4] = dns;
hudakz 0:5350a66d5279 263 buffer[5] = domainName;
hudakz 0:5350a66d5279 264 buffer[6] = dhcpT1value;
hudakz 0:5350a66d5279 265 buffer[7] = dhcpT2value;
hudakz 0:5350a66d5279 266 buffer[8] = endOption;
hudakz 0:5350a66d5279 267
hudakz 0:5350a66d5279 268 //put data in W5100 transmit buffer
hudakz 0:5350a66d5279 269 _dhcpUdpSocket.write(buffer, 9);
hudakz 0:5350a66d5279 270
hudakz 0:5350a66d5279 271 _dhcpUdpSocket.endPacket();
hudakz 0:5350a66d5279 272 }
hudakz 0:5350a66d5279 273
hudakz 0:5350a66d5279 274 /**
hudakz 0:5350a66d5279 275 * @brief
hudakz 0:5350a66d5279 276 * @note
hudakz 0:5350a66d5279 277 * @param
hudakz 0:5350a66d5279 278 * @retval
hudakz 0:5350a66d5279 279 */
hudakz 0:5350a66d5279 280 uint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId) {
hudakz 8:4acb22344932 281 volatile uint8_t type = 0;
hudakz 8:4acb22344932 282 uint8_t opt_len = 0;
hudakz 0:5350a66d5279 283
hudakz 8:4acb22344932 284 unsigned long startTime = millis();
hudakz 0:5350a66d5279 285
hudakz 8:4acb22344932 286 while (_dhcpUdpSocket.parsePacket() <= 0) {
hudakz 8:4acb22344932 287 if ((millis() - startTime) > responseTimeout) {
hudakz 0:5350a66d5279 288 return 255;
hudakz 0:5350a66d5279 289 }
hudakz 0:5350a66d5279 290
hudakz 4:d774541a34da 291 wait_ms(50);
hudakz 0:5350a66d5279 292 }
hudakz 0:5350a66d5279 293
hudakz 0:5350a66d5279 294 // start reading in the packet
hudakz 0:5350a66d5279 295 RIP_MSG_FIXED fixedMsg;
hudakz 0:5350a66d5279 296 _dhcpUdpSocket.read((uint8_t*) &fixedMsg, sizeof(RIP_MSG_FIXED));
hudakz 0:5350a66d5279 297
hudakz 8:4acb22344932 298 if (fixedMsg.op == DHCP_BOOTREPLY && _dhcpUdpSocket.remotePort() == DHCP_SERVER_PORT) {
hudakz 0:5350a66d5279 299 transactionId = ntohl(fixedMsg.xid);
hudakz 0:5350a66d5279 300 if
hudakz 0:5350a66d5279 301 (
hudakz 0:5350a66d5279 302 memcmp(fixedMsg.chaddr, _dhcpMacAddr, 6) != 0
hudakz 0:5350a66d5279 303 || (transactionId < _dhcpInitialTransactionId)
hudakz 0:5350a66d5279 304 || (transactionId > _dhcpTransactionId)
hudakz 0:5350a66d5279 305 ) {
hudakz 0:5350a66d5279 306
hudakz 0:5350a66d5279 307 // Need to read the rest of the packet here regardless
hudakz 0:5350a66d5279 308 _dhcpUdpSocket.flush();
hudakz 0:5350a66d5279 309 return 0;
hudakz 0:5350a66d5279 310 }
hudakz 0:5350a66d5279 311
hudakz 0:5350a66d5279 312 memcpy(_dhcpLocalIp, fixedMsg.yiaddr, 4);
hudakz 0:5350a66d5279 313
hudakz 0:5350a66d5279 314 // Skip to the option part
hudakz 0:5350a66d5279 315 // Doing this a byte at a time so we don't have to put a big buffer
hudakz 0:5350a66d5279 316 // on the stack (as we don't have lots of memory lying around)
hudakz 8:4acb22344932 317 for (int i = 0; i < (240 - (int)sizeof(RIP_MSG_FIXED)); i++) {
hudakz 0:5350a66d5279 318 _dhcpUdpSocket.read(); // we don't care about the returned byte
hudakz 0:5350a66d5279 319 }
hudakz 0:5350a66d5279 320
hudakz 8:4acb22344932 321 while (_dhcpUdpSocket.available() > 0) {
hudakz 8:4acb22344932 322 switch (_dhcpUdpSocket.read()) {
hudakz 8:4acb22344932 323 case endOption:
hudakz 8:4acb22344932 324 break;
hudakz 0:5350a66d5279 325
hudakz 8:4acb22344932 326 case padOption:
hudakz 8:4acb22344932 327 break;
hudakz 8:4acb22344932 328
hudakz 8:4acb22344932 329 case dhcpMessageType:
hudakz 8:4acb22344932 330 opt_len = _dhcpUdpSocket.read();
hudakz 8:4acb22344932 331 type = _dhcpUdpSocket.read();
hudakz 8:4acb22344932 332 break;
hudakz 0:5350a66d5279 333
hudakz 8:4acb22344932 334 case subnetMask:
hudakz 8:4acb22344932 335 opt_len = _dhcpUdpSocket.read();
hudakz 8:4acb22344932 336 _dhcpUdpSocket.read(_dhcpSubnetMask, 4);
hudakz 8:4acb22344932 337 break;
hudakz 0:5350a66d5279 338
hudakz 8:4acb22344932 339 case routersOnSubnet:
hudakz 8:4acb22344932 340 opt_len = _dhcpUdpSocket.read();
hudakz 8:4acb22344932 341 _dhcpUdpSocket.read(_dhcpGatewayIp, 4);
hudakz 8:4acb22344932 342 for (int i = 0; i < opt_len - 4; i++) {
hudakz 8:4acb22344932 343 _dhcpUdpSocket.read();
hudakz 8:4acb22344932 344 }
hudakz 8:4acb22344932 345 break;
hudakz 8:4acb22344932 346
hudakz 8:4acb22344932 347 case dns:
hudakz 8:4acb22344932 348 opt_len = _dhcpUdpSocket.read();
hudakz 8:4acb22344932 349 _dhcpUdpSocket.read(_dhcpDnsServerIp, 4);
hudakz 8:4acb22344932 350 for (int i = 0; i < opt_len - 4; i++) {
hudakz 8:4acb22344932 351 _dhcpUdpSocket.read();
hudakz 8:4acb22344932 352 }
hudakz 8:4acb22344932 353 break;
hudakz 0:5350a66d5279 354
hudakz 8:4acb22344932 355 case dhcpServerIdentifier:
hudakz 8:4acb22344932 356 opt_len = _dhcpUdpSocket.read();
hudakz 8:4acb22344932 357 if (*((uint32_t*)_dhcpDhcpServerIp) == 0 || IPAddress(_dhcpDhcpServerIp) == _dhcpUdpSocket.remoteIP()) {
hudakz 8:4acb22344932 358 _dhcpUdpSocket.read(_dhcpDhcpServerIp, sizeof(_dhcpDhcpServerIp));
hudakz 8:4acb22344932 359 }
hudakz 8:4acb22344932 360 else {
hudakz 8:4acb22344932 361
hudakz 8:4acb22344932 362 // Skip over the rest of this option
hudakz 8:4acb22344932 363 while (opt_len--) {
hudakz 8:4acb22344932 364 _dhcpUdpSocket.read();
hudakz 8:4acb22344932 365 }
hudakz 8:4acb22344932 366 }
hudakz 8:4acb22344932 367 break;
hudakz 0:5350a66d5279 368
hudakz 8:4acb22344932 369 case dhcpT1value:
hudakz 8:4acb22344932 370 opt_len = _dhcpUdpSocket.read();
hudakz 8:4acb22344932 371 _dhcpUdpSocket.read((uint8_t*) &_dhcpT1, sizeof(_dhcpT1));
hudakz 8:4acb22344932 372 _dhcpT1 = ntohl(_dhcpT1);
hudakz 8:4acb22344932 373 break;
hudakz 0:5350a66d5279 374
hudakz 8:4acb22344932 375 case dhcpT2value:
hudakz 8:4acb22344932 376 opt_len = _dhcpUdpSocket.read();
hudakz 8:4acb22344932 377 _dhcpUdpSocket.read((uint8_t*) &_dhcpT2, sizeof(_dhcpT2));
hudakz 8:4acb22344932 378 _dhcpT2 = ntohl(_dhcpT2);
hudakz 8:4acb22344932 379 break;
hudakz 8:4acb22344932 380
hudakz 8:4acb22344932 381 case dhcpIPaddrLeaseTime:
hudakz 8:4acb22344932 382 opt_len = _dhcpUdpSocket.read();
hudakz 8:4acb22344932 383 _dhcpUdpSocket.read((uint8_t*) &_dhcpLeaseTime, sizeof(_dhcpLeaseTime));
hudakz 8:4acb22344932 384 _dhcpLeaseTime = ntohl(_dhcpLeaseTime);
hudakz 8:4acb22344932 385 _renewInSec = _dhcpLeaseTime;
hudakz 8:4acb22344932 386 break;
hudakz 8:4acb22344932 387
hudakz 8:4acb22344932 388 default:
hudakz 8:4acb22344932 389 opt_len = _dhcpUdpSocket.read();
hudakz 0:5350a66d5279 390
hudakz 0:5350a66d5279 391 // Skip over the rest of this option
hudakz 8:4acb22344932 392 while (opt_len--) {
hudakz 0:5350a66d5279 393 _dhcpUdpSocket.read();
hudakz 0:5350a66d5279 394 }
hudakz 8:4acb22344932 395 break;
hudakz 0:5350a66d5279 396 }
hudakz 0:5350a66d5279 397 }
hudakz 0:5350a66d5279 398 }
hudakz 0:5350a66d5279 399
hudakz 0:5350a66d5279 400 // Need to skip to end of the packet regardless here
hudakz 0:5350a66d5279 401 _dhcpUdpSocket.flush();
hudakz 0:5350a66d5279 402
hudakz 0:5350a66d5279 403 return type;
hudakz 0:5350a66d5279 404 }
hudakz 0:5350a66d5279 405
hudakz 0:5350a66d5279 406 /*
hudakz 0:5350a66d5279 407 returns:
hudakz 0:5350a66d5279 408 0/DHCP_CHECK_NONE: nothing happened
hudakz 0:5350a66d5279 409 1/DHCP_CHECK_RENEW_FAIL: renew failed
hudakz 0:5350a66d5279 410 2/DHCP_CHECK_RENEW_OK: renew success
hudakz 0:5350a66d5279 411 3/DHCP_CHECK_REBIND_FAIL: rebind fail
hudakz 0:5350a66d5279 412 4/DHCP_CHECK_REBIND_OK: rebind success
hudakz 0:5350a66d5279 413 */
hudakz 0:5350a66d5279 414 int DhcpClass::checkLease(void) {
hudakz 0:5350a66d5279 415
hudakz 0:5350a66d5279 416 //this uses a signed / unsigned trick to deal with millis overflow
hudakz 4:d774541a34da 417 unsigned long now = millis();
hudakz 0:5350a66d5279 418 signed long snow = (long)now;
hudakz 8:4acb22344932 419 volatile int rc = DHCP_CHECK_NONE;
hudakz 8:4acb22344932 420 if (_lastCheck != 0) {
hudakz 0:5350a66d5279 421 signed long factor;
hudakz 0:5350a66d5279 422 //calc how many ms past the timeout we are
hudakz 0:5350a66d5279 423
hudakz 0:5350a66d5279 424 factor = snow - (long)_secTimeout;
hudakz 0:5350a66d5279 425
hudakz 0:5350a66d5279 426 //if on or passed the timeout, reduce the counters
hudakz 8:4acb22344932 427 if (factor >= 0) {
hudakz 0:5350a66d5279 428
hudakz 0:5350a66d5279 429 //next timeout should be now plus 1000 ms minus parts of second in factor
hudakz 0:5350a66d5279 430 _secTimeout = snow + 1000 - factor % 1000;
hudakz 0:5350a66d5279 431
hudakz 0:5350a66d5279 432 //how many seconds late are we, minimum 1
hudakz 0:5350a66d5279 433 factor = factor / 1000 + 1;
hudakz 0:5350a66d5279 434
hudakz 0:5350a66d5279 435 //reduce the counters by that mouch
hudakz 0:5350a66d5279 436 //if we can assume that the cycle time (factor) is fairly constant
hudakz 0:5350a66d5279 437 //and if the remainder is less than cycle time * 2
hudakz 0:5350a66d5279 438 //do it early instead of late
hudakz 8:4acb22344932 439 if (_renewInSec < factor * 2)
hudakz 0:5350a66d5279 440 _renewInSec = 0;
hudakz 0:5350a66d5279 441 else
hudakz 0:5350a66d5279 442 _renewInSec -= factor;
hudakz 0:5350a66d5279 443
hudakz 8:4acb22344932 444 if (_rebindInSec < factor * 2)
hudakz 0:5350a66d5279 445 _rebindInSec = 0;
hudakz 0:5350a66d5279 446 else
hudakz 0:5350a66d5279 447 _rebindInSec -= factor;
hudakz 0:5350a66d5279 448 }
hudakz 0:5350a66d5279 449
hudakz 0:5350a66d5279 450 //if we have a lease but should renew, do it
hudakz 8:4acb22344932 451 if (_dhcp_state == STATE_DHCP_LEASED && _renewInSec <= 0) {
hudakz 0:5350a66d5279 452 _dhcp_state = STATE_DHCP_REREQUEST;
hudakz 0:5350a66d5279 453 rc = 1 + request_DHCP_lease();
hudakz 0:5350a66d5279 454 }
hudakz 0:5350a66d5279 455
hudakz 0:5350a66d5279 456 //if we have a lease or is renewing but should bind, do it
hudakz 8:4acb22344932 457 if ((_dhcp_state == STATE_DHCP_LEASED || _dhcp_state == STATE_DHCP_START) && _rebindInSec <= 0) {
hudakz 0:5350a66d5279 458
hudakz 0:5350a66d5279 459 //this should basically restart completely
hudakz 0:5350a66d5279 460 _dhcp_state = STATE_DHCP_START;
hudakz 0:5350a66d5279 461 reset_DHCP_lease();
hudakz 0:5350a66d5279 462 rc = 3 + request_DHCP_lease();
hudakz 0:5350a66d5279 463 }
hudakz 0:5350a66d5279 464 }
hudakz 0:5350a66d5279 465 else {
hudakz 0:5350a66d5279 466 _secTimeout = snow + 1000;
hudakz 0:5350a66d5279 467 }
hudakz 0:5350a66d5279 468
hudakz 0:5350a66d5279 469 _lastCheck = now;
hudakz 0:5350a66d5279 470 return rc;
hudakz 0:5350a66d5279 471 }
hudakz 0:5350a66d5279 472
hudakz 0:5350a66d5279 473 /**
hudakz 0:5350a66d5279 474 * @brief
hudakz 0:5350a66d5279 475 * @note
hudakz 0:5350a66d5279 476 * @param
hudakz 0:5350a66d5279 477 * @retval
hudakz 0:5350a66d5279 478 */
hudakz 0:5350a66d5279 479 IPAddress DhcpClass::getLocalIp(void) {
hudakz 0:5350a66d5279 480 return IPAddress(_dhcpLocalIp);
hudakz 0:5350a66d5279 481 }
hudakz 0:5350a66d5279 482
hudakz 0:5350a66d5279 483 /**
hudakz 0:5350a66d5279 484 * @brief
hudakz 0:5350a66d5279 485 * @note
hudakz 0:5350a66d5279 486 * @param
hudakz 0:5350a66d5279 487 * @retval
hudakz 0:5350a66d5279 488 */
hudakz 0:5350a66d5279 489 IPAddress DhcpClass::getSubnetMask(void) {
hudakz 0:5350a66d5279 490 return IPAddress(_dhcpSubnetMask);
hudakz 0:5350a66d5279 491 }
hudakz 0:5350a66d5279 492
hudakz 0:5350a66d5279 493 /**
hudakz 0:5350a66d5279 494 * @brief
hudakz 0:5350a66d5279 495 * @note
hudakz 0:5350a66d5279 496 * @param
hudakz 0:5350a66d5279 497 * @retval
hudakz 0:5350a66d5279 498 */
hudakz 0:5350a66d5279 499 IPAddress DhcpClass::getGatewayIp(void) {
hudakz 0:5350a66d5279 500 return IPAddress(_dhcpGatewayIp);
hudakz 0:5350a66d5279 501 }
hudakz 0:5350a66d5279 502
hudakz 0:5350a66d5279 503 /**
hudakz 0:5350a66d5279 504 * @brief
hudakz 0:5350a66d5279 505 * @note
hudakz 0:5350a66d5279 506 * @param
hudakz 0:5350a66d5279 507 * @retval
hudakz 0:5350a66d5279 508 */
hudakz 0:5350a66d5279 509 IPAddress DhcpClass::getDhcpServerIp(void) {
hudakz 0:5350a66d5279 510 return IPAddress(_dhcpDhcpServerIp);
hudakz 0:5350a66d5279 511 }
hudakz 0:5350a66d5279 512
hudakz 0:5350a66d5279 513 /**
hudakz 0:5350a66d5279 514 * @brief
hudakz 0:5350a66d5279 515 * @note
hudakz 0:5350a66d5279 516 * @param
hudakz 0:5350a66d5279 517 * @retval
hudakz 0:5350a66d5279 518 */
hudakz 0:5350a66d5279 519 IPAddress DhcpClass::getDnsServerIp(void) {
hudakz 0:5350a66d5279 520 return IPAddress(_dhcpDnsServerIp);
hudakz 0:5350a66d5279 521 }
hudakz 0:5350a66d5279 522
hudakz 0:5350a66d5279 523 /**
hudakz 0:5350a66d5279 524 * @brief
hudakz 0:5350a66d5279 525 * @note
hudakz 0:5350a66d5279 526 * @param
hudakz 0:5350a66d5279 527 * @retval
hudakz 0:5350a66d5279 528 */
hudakz 0:5350a66d5279 529 void DhcpClass::printByte(char* buf, uint8_t n) {
hudakz 0:5350a66d5279 530 char* str = &buf[1];
hudakz 0:5350a66d5279 531 buf[0] = '0';
hudakz 8:4acb22344932 532 do {
hudakz 0:5350a66d5279 533 unsigned long m = n;
hudakz 0:5350a66d5279 534 n /= 16;
hudakz 0:5350a66d5279 535
hudakz 0:5350a66d5279 536 char c = m - 16 * n;
hudakz 0:5350a66d5279 537 *str-- = c < 10 ? c + '0' : c + 'A' - 10;
hudakz 8:4acb22344932 538 } while (n);
hudakz 0:5350a66d5279 539 }