mbed OS5

Fork of UIPEthernet by Zoltan Hudak

Committer:
hudakz
Date:
Sun Nov 29 17:54:01 2015 +0000
Revision:
6:10e42359e217
Parent:
4:d774541a34da
Child:
7:1bc7e6120801
UIPClient modified to make MQTTClient work with the recent revision of mbed library.

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 0:5350a66d5279 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 0:5350a66d5279 63 int result = 0;
hudakz 0:5350a66d5279 64
hudakz 4:d774541a34da 65 unsigned long startTime = millis();
hudakz 0:5350a66d5279 66
hudakz 0:5350a66d5279 67 while(_dhcp_state != STATE_DHCP_LEASED) {
hudakz 0:5350a66d5279 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 0:5350a66d5279 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 0:5350a66d5279 81 if(_dhcp_state == STATE_DHCP_DISCOVER) {
hudakz 0:5350a66d5279 82 uint32_t respId;
hudakz 0:5350a66d5279 83 messageType = parseDHCPResponse(_responseTimeout, respId);
hudakz 0:5350a66d5279 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 0:5350a66d5279 94 if(_dhcp_state == STATE_DHCP_REQUEST) {
hudakz 0:5350a66d5279 95 uint32_t respId;
hudakz 0:5350a66d5279 96 messageType = parseDHCPResponse(_responseTimeout, respId);
hudakz 0:5350a66d5279 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 0:5350a66d5279 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 0:5350a66d5279 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 0:5350a66d5279 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 0:5350a66d5279 123 if(messageType == DHCP_NAK)
hudakz 0:5350a66d5279 124 _dhcp_state = STATE_DHCP_START;
hudakz 0:5350a66d5279 125 }
hudakz 0:5350a66d5279 126
hudakz 0:5350a66d5279 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 4:d774541a34da 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 0:5350a66d5279 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 0:5350a66d5279 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 0:5350a66d5279 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 0:5350a66d5279 247 buffer[8] = _dhcpDhcpServerIp[0];
hudakz 0:5350a66d5279 248 buffer[9] = _dhcpDhcpServerIp[1];
hudakz 0:5350a66d5279 249 buffer[10] = _dhcpDhcpServerIp[2];
hudakz 0:5350a66d5279 250 buffer[11] = _dhcpDhcpServerIp[3];
hudakz 0:5350a66d5279 251
hudakz 0:5350a66d5279 252 //put data in W5100 transmit buffer
hudakz 0:5350a66d5279 253 _dhcpUdpSocket.write(buffer, 12);
hudakz 0:5350a66d5279 254 }
hudakz 0:5350a66d5279 255
hudakz 0:5350a66d5279 256 buffer[0] = dhcpParamRequest;
hudakz 0:5350a66d5279 257 buffer[1] = 0x06;
hudakz 0:5350a66d5279 258 buffer[2] = subnetMask;
hudakz 0:5350a66d5279 259 buffer[3] = routersOnSubnet;
hudakz 0:5350a66d5279 260 buffer[4] = dns;
hudakz 0:5350a66d5279 261 buffer[5] = domainName;
hudakz 0:5350a66d5279 262 buffer[6] = dhcpT1value;
hudakz 0:5350a66d5279 263 buffer[7] = dhcpT2value;
hudakz 0:5350a66d5279 264 buffer[8] = endOption;
hudakz 0:5350a66d5279 265
hudakz 0:5350a66d5279 266 //put data in W5100 transmit buffer
hudakz 0:5350a66d5279 267 _dhcpUdpSocket.write(buffer, 9);
hudakz 0:5350a66d5279 268
hudakz 0:5350a66d5279 269 _dhcpUdpSocket.endPacket();
hudakz 0:5350a66d5279 270 }
hudakz 0:5350a66d5279 271
hudakz 0:5350a66d5279 272 /**
hudakz 0:5350a66d5279 273 * @brief
hudakz 0:5350a66d5279 274 * @note
hudakz 0:5350a66d5279 275 * @param
hudakz 0:5350a66d5279 276 * @retval
hudakz 0:5350a66d5279 277 */
hudakz 0:5350a66d5279 278 uint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId) {
hudakz 0:5350a66d5279 279 uint8_t type = 0;
hudakz 0:5350a66d5279 280 uint8_t opt_len = 0;
hudakz 0:5350a66d5279 281
hudakz 4:d774541a34da 282 unsigned long startTime = millis();
hudakz 0:5350a66d5279 283
hudakz 0:5350a66d5279 284 while(_dhcpUdpSocket.parsePacket() <= 0) {
hudakz 4:d774541a34da 285 if((millis() - startTime) > responseTimeout) {
hudakz 0:5350a66d5279 286 return 255;
hudakz 0:5350a66d5279 287 }
hudakz 0:5350a66d5279 288
hudakz 4:d774541a34da 289 wait_ms(50);
hudakz 0:5350a66d5279 290 }
hudakz 0:5350a66d5279 291
hudakz 0:5350a66d5279 292 // start reading in the packet
hudakz 0:5350a66d5279 293 RIP_MSG_FIXED fixedMsg;
hudakz 0:5350a66d5279 294 _dhcpUdpSocket.read((uint8_t*) &fixedMsg, sizeof(RIP_MSG_FIXED));
hudakz 0:5350a66d5279 295
hudakz 0:5350a66d5279 296 if(fixedMsg.op == DHCP_BOOTREPLY && _dhcpUdpSocket.remotePort() == DHCP_SERVER_PORT) {
hudakz 0:5350a66d5279 297 transactionId = ntohl(fixedMsg.xid);
hudakz 0:5350a66d5279 298 if
hudakz 0:5350a66d5279 299 (
hudakz 0:5350a66d5279 300 memcmp(fixedMsg.chaddr, _dhcpMacAddr, 6) != 0
hudakz 0:5350a66d5279 301 || (transactionId < _dhcpInitialTransactionId)
hudakz 0:5350a66d5279 302 || (transactionId > _dhcpTransactionId)
hudakz 0:5350a66d5279 303 ) {
hudakz 0:5350a66d5279 304
hudakz 0:5350a66d5279 305 // Need to read the rest of the packet here regardless
hudakz 0:5350a66d5279 306 _dhcpUdpSocket.flush();
hudakz 0:5350a66d5279 307 return 0;
hudakz 0:5350a66d5279 308 }
hudakz 0:5350a66d5279 309
hudakz 0:5350a66d5279 310 memcpy(_dhcpLocalIp, fixedMsg.yiaddr, 4);
hudakz 0:5350a66d5279 311
hudakz 0:5350a66d5279 312 // Skip to the option part
hudakz 0:5350a66d5279 313 // Doing this a byte at a time so we don't have to put a big buffer
hudakz 0:5350a66d5279 314 // on the stack (as we don't have lots of memory lying around)
hudakz 0:5350a66d5279 315 for(int i = 0; i < (240 - (int)sizeof(RIP_MSG_FIXED)); i++) {
hudakz 0:5350a66d5279 316 _dhcpUdpSocket.read(); // we don't care about the returned byte
hudakz 0:5350a66d5279 317 }
hudakz 0:5350a66d5279 318
hudakz 0:5350a66d5279 319 while(_dhcpUdpSocket.available() > 0) {
hudakz 0:5350a66d5279 320 switch(_dhcpUdpSocket.read()) {
hudakz 0:5350a66d5279 321 case endOption:
hudakz 0:5350a66d5279 322 break;
hudakz 0:5350a66d5279 323
hudakz 0:5350a66d5279 324 case padOption:
hudakz 0:5350a66d5279 325 break;
hudakz 0:5350a66d5279 326
hudakz 0:5350a66d5279 327 case dhcpMessageType:
hudakz 0:5350a66d5279 328 opt_len = _dhcpUdpSocket.read();
hudakz 0:5350a66d5279 329 type = _dhcpUdpSocket.read();
hudakz 0:5350a66d5279 330 break;
hudakz 0:5350a66d5279 331
hudakz 0:5350a66d5279 332 case subnetMask:
hudakz 0:5350a66d5279 333 opt_len = _dhcpUdpSocket.read();
hudakz 0:5350a66d5279 334 _dhcpUdpSocket.read(_dhcpSubnetMask, 4);
hudakz 0:5350a66d5279 335 break;
hudakz 0:5350a66d5279 336
hudakz 0:5350a66d5279 337 case routersOnSubnet:
hudakz 0:5350a66d5279 338 opt_len = _dhcpUdpSocket.read();
hudakz 0:5350a66d5279 339 _dhcpUdpSocket.read(_dhcpGatewayIp, 4);
hudakz 0:5350a66d5279 340 for(int i = 0; i < opt_len - 4; i++) {
hudakz 0:5350a66d5279 341 _dhcpUdpSocket.read();
hudakz 0:5350a66d5279 342 }
hudakz 0:5350a66d5279 343 break;
hudakz 0:5350a66d5279 344
hudakz 0:5350a66d5279 345 case dns:
hudakz 0:5350a66d5279 346 opt_len = _dhcpUdpSocket.read();
hudakz 0:5350a66d5279 347 _dhcpUdpSocket.read(_dhcpDnsServerIp, 4);
hudakz 0:5350a66d5279 348 for(int i = 0; i < opt_len - 4; i++) {
hudakz 0:5350a66d5279 349 _dhcpUdpSocket.read();
hudakz 0:5350a66d5279 350 }
hudakz 0:5350a66d5279 351 break;
hudakz 0:5350a66d5279 352
hudakz 0:5350a66d5279 353 case dhcpServerIdentifier:
hudakz 0:5350a66d5279 354 opt_len = _dhcpUdpSocket.read();
hudakz 0:5350a66d5279 355 if(*((uint32_t*)_dhcpDhcpServerIp) == 0 || IPAddress(_dhcpDhcpServerIp) == _dhcpUdpSocket.remoteIP()) {
hudakz 0:5350a66d5279 356 _dhcpUdpSocket.read(_dhcpDhcpServerIp, sizeof(_dhcpDhcpServerIp));
hudakz 0:5350a66d5279 357 }
hudakz 0:5350a66d5279 358 else {
hudakz 0:5350a66d5279 359
hudakz 0:5350a66d5279 360 // Skip over the rest of this option
hudakz 0:5350a66d5279 361 while(opt_len--) {
hudakz 0:5350a66d5279 362 _dhcpUdpSocket.read();
hudakz 0:5350a66d5279 363 }
hudakz 0:5350a66d5279 364 }
hudakz 0:5350a66d5279 365 break;
hudakz 0:5350a66d5279 366
hudakz 0:5350a66d5279 367 case dhcpT1value:
hudakz 0:5350a66d5279 368 opt_len = _dhcpUdpSocket.read();
hudakz 0:5350a66d5279 369 _dhcpUdpSocket.read((uint8_t*) &_dhcpT1, sizeof(_dhcpT1));
hudakz 0:5350a66d5279 370 _dhcpT1 = ntohl(_dhcpT1);
hudakz 0:5350a66d5279 371 break;
hudakz 0:5350a66d5279 372
hudakz 0:5350a66d5279 373 case dhcpT2value:
hudakz 0:5350a66d5279 374 opt_len = _dhcpUdpSocket.read();
hudakz 0:5350a66d5279 375 _dhcpUdpSocket.read((uint8_t*) &_dhcpT2, sizeof(_dhcpT2));
hudakz 0:5350a66d5279 376 _dhcpT2 = ntohl(_dhcpT2);
hudakz 0:5350a66d5279 377 break;
hudakz 0:5350a66d5279 378
hudakz 0:5350a66d5279 379 case dhcpIPaddrLeaseTime:
hudakz 0:5350a66d5279 380 opt_len = _dhcpUdpSocket.read();
hudakz 0:5350a66d5279 381 _dhcpUdpSocket.read((uint8_t*) &_dhcpLeaseTime, sizeof(_dhcpLeaseTime));
hudakz 0:5350a66d5279 382 _dhcpLeaseTime = ntohl(_dhcpLeaseTime);
hudakz 0:5350a66d5279 383 _renewInSec = _dhcpLeaseTime;
hudakz 0:5350a66d5279 384 break;
hudakz 0:5350a66d5279 385
hudakz 0:5350a66d5279 386 default:
hudakz 0:5350a66d5279 387 opt_len = _dhcpUdpSocket.read();
hudakz 0:5350a66d5279 388
hudakz 0:5350a66d5279 389 // Skip over the rest of this option
hudakz 0:5350a66d5279 390 while(opt_len--) {
hudakz 0:5350a66d5279 391 _dhcpUdpSocket.read();
hudakz 0:5350a66d5279 392 }
hudakz 0:5350a66d5279 393 break;
hudakz 0:5350a66d5279 394 }
hudakz 0:5350a66d5279 395 }
hudakz 0:5350a66d5279 396 }
hudakz 0:5350a66d5279 397
hudakz 0:5350a66d5279 398 // Need to skip to end of the packet regardless here
hudakz 0:5350a66d5279 399 _dhcpUdpSocket.flush();
hudakz 0:5350a66d5279 400
hudakz 0:5350a66d5279 401 return type;
hudakz 0:5350a66d5279 402 }
hudakz 0:5350a66d5279 403
hudakz 0:5350a66d5279 404 /*
hudakz 0:5350a66d5279 405 returns:
hudakz 0:5350a66d5279 406 0/DHCP_CHECK_NONE: nothing happened
hudakz 0:5350a66d5279 407 1/DHCP_CHECK_RENEW_FAIL: renew failed
hudakz 0:5350a66d5279 408 2/DHCP_CHECK_RENEW_OK: renew success
hudakz 0:5350a66d5279 409 3/DHCP_CHECK_REBIND_FAIL: rebind fail
hudakz 0:5350a66d5279 410 4/DHCP_CHECK_REBIND_OK: rebind success
hudakz 0:5350a66d5279 411 */
hudakz 0:5350a66d5279 412 int DhcpClass::checkLease(void) {
hudakz 0:5350a66d5279 413
hudakz 0:5350a66d5279 414 //this uses a signed / unsigned trick to deal with millis overflow
hudakz 4:d774541a34da 415 unsigned long now = millis();
hudakz 0:5350a66d5279 416 signed long snow = (long)now;
hudakz 0:5350a66d5279 417 int rc = DHCP_CHECK_NONE;
hudakz 0:5350a66d5279 418 if(_lastCheck != 0) {
hudakz 0:5350a66d5279 419 signed long factor;
hudakz 0:5350a66d5279 420 //calc how many ms past the timeout we are
hudakz 0:5350a66d5279 421
hudakz 0:5350a66d5279 422 factor = snow - (long)_secTimeout;
hudakz 0:5350a66d5279 423
hudakz 0:5350a66d5279 424 //if on or passed the timeout, reduce the counters
hudakz 0:5350a66d5279 425 if(factor >= 0) {
hudakz 0:5350a66d5279 426
hudakz 0:5350a66d5279 427 //next timeout should be now plus 1000 ms minus parts of second in factor
hudakz 0:5350a66d5279 428 _secTimeout = snow + 1000 - factor % 1000;
hudakz 0:5350a66d5279 429
hudakz 0:5350a66d5279 430 //how many seconds late are we, minimum 1
hudakz 0:5350a66d5279 431 factor = factor / 1000 + 1;
hudakz 0:5350a66d5279 432
hudakz 0:5350a66d5279 433 //reduce the counters by that mouch
hudakz 0:5350a66d5279 434 //if we can assume that the cycle time (factor) is fairly constant
hudakz 0:5350a66d5279 435 //and if the remainder is less than cycle time * 2
hudakz 0:5350a66d5279 436 //do it early instead of late
hudakz 0:5350a66d5279 437 if(_renewInSec < factor * 2)
hudakz 0:5350a66d5279 438 _renewInSec = 0;
hudakz 0:5350a66d5279 439 else
hudakz 0:5350a66d5279 440 _renewInSec -= factor;
hudakz 0:5350a66d5279 441
hudakz 0:5350a66d5279 442 if(_rebindInSec < factor * 2)
hudakz 0:5350a66d5279 443 _rebindInSec = 0;
hudakz 0:5350a66d5279 444 else
hudakz 0:5350a66d5279 445 _rebindInSec -= factor;
hudakz 0:5350a66d5279 446 }
hudakz 0:5350a66d5279 447
hudakz 0:5350a66d5279 448 //if we have a lease but should renew, do it
hudakz 0:5350a66d5279 449 if(_dhcp_state == STATE_DHCP_LEASED && _renewInSec <= 0) {
hudakz 0:5350a66d5279 450 _dhcp_state = STATE_DHCP_REREQUEST;
hudakz 0:5350a66d5279 451 rc = 1 + request_DHCP_lease();
hudakz 0:5350a66d5279 452 }
hudakz 0:5350a66d5279 453
hudakz 0:5350a66d5279 454 //if we have a lease or is renewing but should bind, do it
hudakz 0:5350a66d5279 455 if((_dhcp_state == STATE_DHCP_LEASED || _dhcp_state == STATE_DHCP_START) && _rebindInSec <= 0) {
hudakz 0:5350a66d5279 456
hudakz 0:5350a66d5279 457 //this should basically restart completely
hudakz 0:5350a66d5279 458 _dhcp_state = STATE_DHCP_START;
hudakz 0:5350a66d5279 459 reset_DHCP_lease();
hudakz 0:5350a66d5279 460 rc = 3 + request_DHCP_lease();
hudakz 0:5350a66d5279 461 }
hudakz 0:5350a66d5279 462 }
hudakz 0:5350a66d5279 463 else {
hudakz 0:5350a66d5279 464 _secTimeout = snow + 1000;
hudakz 0:5350a66d5279 465 }
hudakz 0:5350a66d5279 466
hudakz 0:5350a66d5279 467 _lastCheck = now;
hudakz 0:5350a66d5279 468 return rc;
hudakz 0:5350a66d5279 469 }
hudakz 0:5350a66d5279 470
hudakz 0:5350a66d5279 471 /**
hudakz 0:5350a66d5279 472 * @brief
hudakz 0:5350a66d5279 473 * @note
hudakz 0:5350a66d5279 474 * @param
hudakz 0:5350a66d5279 475 * @retval
hudakz 0:5350a66d5279 476 */
hudakz 0:5350a66d5279 477 IPAddress DhcpClass::getLocalIp(void) {
hudakz 0:5350a66d5279 478 return IPAddress(_dhcpLocalIp);
hudakz 0:5350a66d5279 479 }
hudakz 0:5350a66d5279 480
hudakz 0:5350a66d5279 481 /**
hudakz 0:5350a66d5279 482 * @brief
hudakz 0:5350a66d5279 483 * @note
hudakz 0:5350a66d5279 484 * @param
hudakz 0:5350a66d5279 485 * @retval
hudakz 0:5350a66d5279 486 */
hudakz 0:5350a66d5279 487 IPAddress DhcpClass::getSubnetMask(void) {
hudakz 0:5350a66d5279 488 return IPAddress(_dhcpSubnetMask);
hudakz 0:5350a66d5279 489 }
hudakz 0:5350a66d5279 490
hudakz 0:5350a66d5279 491 /**
hudakz 0:5350a66d5279 492 * @brief
hudakz 0:5350a66d5279 493 * @note
hudakz 0:5350a66d5279 494 * @param
hudakz 0:5350a66d5279 495 * @retval
hudakz 0:5350a66d5279 496 */
hudakz 0:5350a66d5279 497 IPAddress DhcpClass::getGatewayIp(void) {
hudakz 0:5350a66d5279 498 return IPAddress(_dhcpGatewayIp);
hudakz 0:5350a66d5279 499 }
hudakz 0:5350a66d5279 500
hudakz 0:5350a66d5279 501 /**
hudakz 0:5350a66d5279 502 * @brief
hudakz 0:5350a66d5279 503 * @note
hudakz 0:5350a66d5279 504 * @param
hudakz 0:5350a66d5279 505 * @retval
hudakz 0:5350a66d5279 506 */
hudakz 0:5350a66d5279 507 IPAddress DhcpClass::getDhcpServerIp(void) {
hudakz 0:5350a66d5279 508 return IPAddress(_dhcpDhcpServerIp);
hudakz 0:5350a66d5279 509 }
hudakz 0:5350a66d5279 510
hudakz 0:5350a66d5279 511 /**
hudakz 0:5350a66d5279 512 * @brief
hudakz 0:5350a66d5279 513 * @note
hudakz 0:5350a66d5279 514 * @param
hudakz 0:5350a66d5279 515 * @retval
hudakz 0:5350a66d5279 516 */
hudakz 0:5350a66d5279 517 IPAddress DhcpClass::getDnsServerIp(void) {
hudakz 0:5350a66d5279 518 return IPAddress(_dhcpDnsServerIp);
hudakz 0:5350a66d5279 519 }
hudakz 0:5350a66d5279 520
hudakz 0:5350a66d5279 521 /**
hudakz 0:5350a66d5279 522 * @brief
hudakz 0:5350a66d5279 523 * @note
hudakz 0:5350a66d5279 524 * @param
hudakz 0:5350a66d5279 525 * @retval
hudakz 0:5350a66d5279 526 */
hudakz 0:5350a66d5279 527 void DhcpClass::printByte(char* buf, uint8_t n) {
hudakz 0:5350a66d5279 528 char* str = &buf[1];
hudakz 0:5350a66d5279 529 buf[0] = '0';
hudakz 0:5350a66d5279 530 do
hudakz 0:5350a66d5279 531 {
hudakz 0:5350a66d5279 532 unsigned long m = n;
hudakz 0:5350a66d5279 533 n /= 16;
hudakz 0:5350a66d5279 534
hudakz 0:5350a66d5279 535 char c = m - 16 * n;
hudakz 0:5350a66d5279 536 *str-- = c < 10 ? c + '0' : c + 'A' - 10;
hudakz 0:5350a66d5279 537 } while(n);
hudakz 0:5350a66d5279 538 }