Mbed library for ENC28J60 Ethernet modules. Full support for TCP/IP and UDP Server, Client and HTTP server (webserver). DHCP and DNS is included.

Dependents:   mBuino_ENC28_MQTT Nucleo_Web_ENC28J60 Nucleo_Web_ENC28J60_ADC Serial_over_Ethernet ... more

Library for ENC28J60 Ethernet modules.

/media/uploads/hudakz/enc28j60_module01.jpg

Ported to mbed from Norbert Truchsess's UIPEthernet library for Arduino. Thank you Norbert!

  • Full support for persistent (streaming) TCP/IP and UDP connections Client and Server each, ARP, ICMP, DHCP and DNS.
  • Works with both Mbed OS 2 and Mbed OS 5.

Usage:

  • Import the library into your project.
  • Add #include "UipEthernet.h" to main.cpp
  • Create one instance of the UipEthernet class initialized with the MAC address you'd like to use and SPI pins of the connected Mbed board.

Example programs:

Import programWebSwitch_ENC28J60

HTTP Server serving a simple webpage which enables to remotely turn a digital output on/off. Compile, download, run and type 'IP_address/secret/' (don't forget the last '/') into your web browser and hit ENTER.

Import programHTTPServer_Echo_ENC28J60

A simple HTTP server echoing received requests. Ethernet connection is over an ENC28J60 board. Usage: Type the server's IP address into you web browser and hit <ENTER>.

Import programTcpServer_ENC28J60

Simple TCP/IP Server using the UIPEthernet library for ENC28J60 Ethernet boards.

Import programTcpClient_ENC28J60

Simple TCP/IP Client using the UIPEthernet library for ENC28J60 Ethernet boards.

Import programUdpServer_ENC28J60

Simple UDP Server using the UIPEthernet library for ENC28J60 Ethernet boards.

Import programUdpClient_ENC28J60

Simple UDP Client using the UIPEthernet library for ENC28J60 Ethernet boards.

Import programMQTT_Hello_ENC28J60

MQTT Client example program. Ethernet connection is via an ENC28J60 module.

Committer:
hudakz
Date:
Tue Aug 27 15:01:10 2019 +0000
Revision:
9:a156d3de5647
Child:
15:53715cc81c63
Mbed OS 5 support added and API modified.

Who changed what in which revision?

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