mirror of
https://github.com/arduino/Arduino.git
synced 2024-11-29 10:24:12 +01:00
Fix for issue 62, adding DHCP support. New begin() method added to EthernetClass which takes just a MAC address and gets the rest of its configuration information via DHCP. Examples updated to use the IPAddress class and some have been changed to get their config via DHCP.
This commit is contained in:
parent
5caad5bdb4
commit
a42dc0b455
@ -16,7 +16,7 @@ uint16_t Client::_srcport = 1024;
|
||||
Client::Client(uint8_t sock) : _sock(sock) {
|
||||
}
|
||||
|
||||
Client::Client(uint8_t *ip, uint16_t port) : _ip(ip), _port(port), _sock(MAX_SOCK_NUM) {
|
||||
Client::Client(IPAddress& ip, uint16_t port) : _ip(ip), _port(port), _sock(MAX_SOCK_NUM) {
|
||||
}
|
||||
|
||||
uint8_t Client::connect() {
|
||||
@ -38,7 +38,7 @@ uint8_t Client::connect() {
|
||||
if (_srcport == 0) _srcport = 1024;
|
||||
socket(_sock, SnMR::TCP, _srcport, 0);
|
||||
|
||||
if (!::connect(_sock, _ip, _port)) {
|
||||
if (!::connect(_sock, _ip.raw_address(), _port)) {
|
||||
_sock = MAX_SOCK_NUM;
|
||||
return 0;
|
||||
}
|
||||
|
@ -7,8 +7,8 @@ class Client : public Stream {
|
||||
|
||||
public:
|
||||
Client();
|
||||
Client(uint8_t);
|
||||
Client(uint8_t *, uint16_t);
|
||||
Client(uint8_t sock);
|
||||
Client(IPAddress& ip, uint16_t port);
|
||||
|
||||
uint8_t status();
|
||||
uint8_t connect();
|
||||
@ -31,7 +31,7 @@ public:
|
||||
private:
|
||||
static uint16_t _srcport;
|
||||
uint8_t _sock;
|
||||
uint8_t *_ip;
|
||||
IPAddress _ip;
|
||||
uint16_t _port;
|
||||
};
|
||||
|
||||
|
341
libraries/Ethernet/Dhcp.cpp
Executable file
341
libraries/Ethernet/Dhcp.cpp
Executable file
@ -0,0 +1,341 @@
|
||||
// DHCP Library v0.3 - April 25, 2009
|
||||
// Author: Jordan Terrell - blog.jordanterrell.com
|
||||
|
||||
#include "w5100.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "Dhcp.h"
|
||||
#include "wiring.h"
|
||||
#include "util.h"
|
||||
|
||||
int DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout)
|
||||
{
|
||||
uint8_t dhcp_state = STATE_DHCP_START;
|
||||
uint8_t messageType = 0;
|
||||
|
||||
// zero out _dhcpMacAddr, _dhcpSubnetMask, _dhcpGatewayIp, _dhcpLocalIp, _dhcpDhcpServerIp, _dhcpDnsServerIp
|
||||
memset(_dhcpMacAddr, 0, 26);
|
||||
|
||||
memcpy((void*)_dhcpMacAddr, (void*)mac, 6);
|
||||
|
||||
// Pick an initial transaction ID
|
||||
_dhcpTransactionId = random(1UL, 2000UL);
|
||||
_dhcpInitialTransactionId = _dhcpTransactionId;
|
||||
|
||||
if (_dhcpUdpSocket.begin(DHCP_CLIENT_PORT) == 0)
|
||||
{
|
||||
// Couldn't get a socket
|
||||
return 0;
|
||||
}
|
||||
|
||||
presend_DHCP();
|
||||
|
||||
int result = 0;
|
||||
|
||||
unsigned long startTime = millis();
|
||||
|
||||
while(dhcp_state != STATE_DHCP_LEASED)
|
||||
{
|
||||
if(dhcp_state == STATE_DHCP_START)
|
||||
{
|
||||
_dhcpTransactionId++;
|
||||
|
||||
send_DHCP_MESSAGE(DHCP_DISCOVER, ((millis() - startTime) / 1000));
|
||||
dhcp_state = STATE_DHCP_DISCOVER;
|
||||
}
|
||||
else if(dhcp_state == STATE_DHCP_DISCOVER)
|
||||
{
|
||||
uint32_t respId;
|
||||
messageType = parseDHCPResponse(responseTimeout, respId);
|
||||
if(messageType == DHCP_OFFER)
|
||||
{
|
||||
// We'll use the transaction ID that the offer came with,
|
||||
// rather than the one we were up to
|
||||
_dhcpTransactionId = respId;
|
||||
send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime) / 1000));
|
||||
dhcp_state = STATE_DHCP_REQUEST;
|
||||
}
|
||||
}
|
||||
else if(dhcp_state == STATE_DHCP_REQUEST)
|
||||
{
|
||||
uint32_t respId;
|
||||
messageType = parseDHCPResponse(responseTimeout, respId);
|
||||
if(messageType == DHCP_ACK)
|
||||
{
|
||||
dhcp_state = STATE_DHCP_LEASED;
|
||||
result = 1;
|
||||
}
|
||||
else if(messageType == DHCP_NAK)
|
||||
dhcp_state = STATE_DHCP_START;
|
||||
}
|
||||
|
||||
if(messageType == 255)
|
||||
{
|
||||
messageType = 0;
|
||||
dhcp_state = STATE_DHCP_START;
|
||||
}
|
||||
|
||||
if(result != 1 && ((millis() - startTime) > timeout))
|
||||
break;
|
||||
}
|
||||
|
||||
// We're done with the socket now
|
||||
_dhcpUdpSocket.stop();
|
||||
_dhcpTransactionId++;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void DhcpClass::presend_DHCP()
|
||||
{
|
||||
}
|
||||
|
||||
void DhcpClass::send_DHCP_MESSAGE(uint8_t messageType, uint16_t secondsElapsed)
|
||||
{
|
||||
uint8_t buffer[32];
|
||||
memset(buffer, 0, 32);
|
||||
IPAddress dest_addr( 255, 255, 255, 255 ); // Broadcast address
|
||||
|
||||
if (-1 == _dhcpUdpSocket.beginPacket(dest_addr, DHCP_SERVER_PORT))
|
||||
{
|
||||
// FIXME Need to return errors
|
||||
return;
|
||||
}
|
||||
|
||||
buffer[0] = DHCP_BOOTREQUEST; // op
|
||||
buffer[1] = DHCP_HTYPE10MB; // htype
|
||||
buffer[2] = DHCP_HLENETHERNET; // hlen
|
||||
buffer[3] = DHCP_HOPS; // hops
|
||||
|
||||
// xid
|
||||
unsigned long xid = htonl(_dhcpTransactionId);
|
||||
memcpy(buffer + 4, &(xid), 4);
|
||||
|
||||
// 8, 9 - seconds elapsed
|
||||
buffer[8] = ((secondsElapsed & 0xff00) >> 8);
|
||||
buffer[9] = (secondsElapsed & 0x00ff);
|
||||
|
||||
// flags
|
||||
unsigned short flags = htons(DHCP_FLAGSBROADCAST);
|
||||
memcpy(buffer + 10, &(flags), 2);
|
||||
|
||||
// ciaddr: already zeroed
|
||||
// yiaddr: already zeroed
|
||||
// siaddr: already zeroed
|
||||
// giaddr: already zeroed
|
||||
|
||||
//put data in W5100 transmit buffer
|
||||
_dhcpUdpSocket.write(buffer, 28);
|
||||
|
||||
memset(buffer, 0, 32); // clear local buffer
|
||||
|
||||
memcpy(buffer, _dhcpMacAddr, 6); // chaddr
|
||||
|
||||
//put data in W5100 transmit buffer
|
||||
_dhcpUdpSocket.write(buffer, 16);
|
||||
|
||||
memset(buffer, 0, 32); // clear local buffer
|
||||
|
||||
// leave zeroed out for sname && file
|
||||
// put in W5100 transmit buffer x 6 (192 bytes)
|
||||
|
||||
for(int i = 0; i < 6; i++) {
|
||||
_dhcpUdpSocket.write(buffer, 32);
|
||||
}
|
||||
|
||||
// OPT - Magic Cookie
|
||||
buffer[0] = (uint8_t)((MAGIC_COOKIE >> 24)& 0xFF);
|
||||
buffer[1] = (uint8_t)((MAGIC_COOKIE >> 16)& 0xFF);
|
||||
buffer[2] = (uint8_t)((MAGIC_COOKIE >> 8)& 0xFF);
|
||||
buffer[3] = (uint8_t)(MAGIC_COOKIE& 0xFF);
|
||||
|
||||
// OPT - message type
|
||||
buffer[4] = dhcpMessageType;
|
||||
buffer[5] = 0x01;
|
||||
buffer[6] = messageType; //DHCP_REQUEST;
|
||||
|
||||
// OPT - client identifier
|
||||
buffer[7] = dhcpClientIdentifier;
|
||||
buffer[8] = 0x07;
|
||||
buffer[9] = 0x01;
|
||||
memcpy(buffer + 10, _dhcpMacAddr, 6);
|
||||
|
||||
// OPT - host name
|
||||
buffer[16] = hostName;
|
||||
buffer[17] = strlen(HOST_NAME) + 3; // length of hostname + last 3 bytes of mac address
|
||||
strcpy((char*)&(buffer[18]), HOST_NAME);
|
||||
|
||||
buffer[24] = _dhcpMacAddr[3];
|
||||
buffer[25] = _dhcpMacAddr[4];
|
||||
buffer[26] = _dhcpMacAddr[5];
|
||||
|
||||
//put data in W5100 transmit buffer
|
||||
_dhcpUdpSocket.write(buffer, 27);
|
||||
|
||||
if(messageType == DHCP_REQUEST)
|
||||
{
|
||||
buffer[0] = dhcpRequestedIPaddr;
|
||||
buffer[1] = 0x04;
|
||||
buffer[2] = _dhcpLocalIp[0];
|
||||
buffer[3] = _dhcpLocalIp[1];
|
||||
buffer[4] = _dhcpLocalIp[2];
|
||||
buffer[5] = _dhcpLocalIp[3];
|
||||
|
||||
buffer[6] = dhcpServerIdentifier;
|
||||
buffer[7] = 0x04;
|
||||
buffer[8] = _dhcpDhcpServerIp[0];
|
||||
buffer[9] = _dhcpDhcpServerIp[1];
|
||||
buffer[10] = _dhcpDhcpServerIp[2];
|
||||
buffer[11] = _dhcpDhcpServerIp[3];
|
||||
|
||||
//put data in W5100 transmit buffer
|
||||
_dhcpUdpSocket.write(buffer, 12);
|
||||
}
|
||||
|
||||
buffer[0] = dhcpParamRequest;
|
||||
buffer[1] = 0x06;
|
||||
buffer[2] = subnetMask;
|
||||
buffer[3] = routersOnSubnet;
|
||||
buffer[4] = dns;
|
||||
buffer[5] = domainName;
|
||||
buffer[6] = dhcpT1value;
|
||||
buffer[7] = dhcpT2value;
|
||||
buffer[8] = endOption;
|
||||
|
||||
//put data in W5100 transmit buffer
|
||||
_dhcpUdpSocket.write(buffer, 9);
|
||||
|
||||
_dhcpUdpSocket.endPacket();
|
||||
}
|
||||
|
||||
uint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId)
|
||||
{
|
||||
uint8_t type = 0;
|
||||
uint8_t opt_len = 0;
|
||||
|
||||
unsigned long startTime = millis();
|
||||
|
||||
while(_dhcpUdpSocket.parsePacket() <= 0)
|
||||
{
|
||||
if((millis() - startTime) > responseTimeout)
|
||||
{
|
||||
return 255;
|
||||
}
|
||||
delay(50);
|
||||
}
|
||||
// start reading in the packet
|
||||
RIP_MSG_FIXED fixedMsg;
|
||||
_dhcpUdpSocket.read((uint8_t*)&fixedMsg, sizeof(RIP_MSG_FIXED));
|
||||
|
||||
if(fixedMsg.op == DHCP_BOOTREPLY && _dhcpUdpSocket.remotePort() == DHCP_SERVER_PORT)
|
||||
{
|
||||
transactionId = ntohl(fixedMsg.xid);
|
||||
if(memcmp(fixedMsg.chaddr, _dhcpMacAddr, 6) != 0 || (transactionId < _dhcpInitialTransactionId) || (transactionId > _dhcpTransactionId))
|
||||
{
|
||||
// Need to read the rest of the packet here regardless
|
||||
_dhcpUdpSocket.flush();
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(_dhcpLocalIp, fixedMsg.yiaddr, 4);
|
||||
|
||||
// Skip to the option part
|
||||
// Doing this a byte at a time so we don't have to put a big buffer
|
||||
// on the stack (as we don't have lots of memory lying around)
|
||||
for (int i =0; i < (240 - sizeof(RIP_MSG_FIXED)); i++)
|
||||
{
|
||||
_dhcpUdpSocket.read(); // we don't care about the returned byte
|
||||
}
|
||||
|
||||
while (_dhcpUdpSocket.available() > 0)
|
||||
{
|
||||
switch (_dhcpUdpSocket.read())
|
||||
{
|
||||
case endOption :
|
||||
break;
|
||||
|
||||
case padOption :
|
||||
break;
|
||||
|
||||
case dhcpMessageType :
|
||||
opt_len = _dhcpUdpSocket.read();
|
||||
type = _dhcpUdpSocket.read();
|
||||
break;
|
||||
|
||||
case subnetMask :
|
||||
opt_len = _dhcpUdpSocket.read();
|
||||
_dhcpUdpSocket.read(_dhcpSubnetMask, 4);
|
||||
break;
|
||||
|
||||
case routersOnSubnet :
|
||||
opt_len = _dhcpUdpSocket.read();
|
||||
_dhcpUdpSocket.read(_dhcpGatewayIp, 4);
|
||||
break;
|
||||
|
||||
case dns :
|
||||
opt_len = _dhcpUdpSocket.read();
|
||||
_dhcpUdpSocket.read(_dhcpDnsServerIp, 4);
|
||||
break;
|
||||
|
||||
case dhcpServerIdentifier :
|
||||
opt_len = _dhcpUdpSocket.read();
|
||||
if( *((uint32_t*)_dhcpDhcpServerIp) == 0 ||
|
||||
IPAddress(_dhcpDhcpServerIp) == _dhcpUdpSocket.remoteIP() )
|
||||
{
|
||||
_dhcpUdpSocket.read(_dhcpDhcpServerIp, sizeof(_dhcpDhcpServerIp));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skip over the rest of this option
|
||||
while (opt_len--)
|
||||
{
|
||||
_dhcpUdpSocket.read();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case dhcpIPaddrLeaseTime :
|
||||
default :
|
||||
opt_len = _dhcpUdpSocket.read();
|
||||
// Skip over the rest of this option
|
||||
while (opt_len--)
|
||||
{
|
||||
_dhcpUdpSocket.read();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Need to skip to end of the packet regardless here
|
||||
_dhcpUdpSocket.flush();
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
IPAddress DhcpClass::getLocalIp()
|
||||
{
|
||||
return IPAddress(_dhcpLocalIp);
|
||||
}
|
||||
|
||||
IPAddress DhcpClass::getSubnetMask()
|
||||
{
|
||||
return IPAddress(_dhcpSubnetMask);
|
||||
}
|
||||
|
||||
IPAddress DhcpClass::getGatewayIp()
|
||||
{
|
||||
return IPAddress(_dhcpGatewayIp);
|
||||
}
|
||||
|
||||
IPAddress DhcpClass::getDhcpServerIp()
|
||||
{
|
||||
return IPAddress(_dhcpDhcpServerIp);
|
||||
}
|
||||
|
||||
IPAddress DhcpClass::getDnsServerIp()
|
||||
{
|
||||
return IPAddress(_dhcpDnsServerIp);
|
||||
}
|
||||
|
158
libraries/Ethernet/Dhcp.h
Executable file
158
libraries/Ethernet/Dhcp.h
Executable file
@ -0,0 +1,158 @@
|
||||
// DHCP Library v0.3 - April 25, 2009
|
||||
// Author: Jordan Terrell - blog.jordanterrell.com
|
||||
|
||||
#ifndef Dhcp_h
|
||||
#define Dhcp_h
|
||||
|
||||
#include "Udp.h"
|
||||
|
||||
/* DHCP state machine. */
|
||||
#define STATE_DHCP_START 0
|
||||
#define STATE_DHCP_DISCOVER 1
|
||||
#define STATE_DHCP_REQUEST 2
|
||||
#define STATE_DHCP_LEASED 3
|
||||
#define STATE_DHCP_REREQUEST 4
|
||||
#define STATE_DHCP_RELEASE 5
|
||||
|
||||
#define DHCP_FLAGSBROADCAST 0x8000
|
||||
|
||||
/* UDP port numbers for DHCP */
|
||||
#define DHCP_SERVER_PORT 67 /* from server to client */
|
||||
#define DHCP_CLIENT_PORT 68 /* from client to server */
|
||||
|
||||
/* DHCP message OP code */
|
||||
#define DHCP_BOOTREQUEST 1
|
||||
#define DHCP_BOOTREPLY 2
|
||||
|
||||
/* DHCP message type */
|
||||
#define DHCP_DISCOVER 1
|
||||
#define DHCP_OFFER 2
|
||||
#define DHCP_REQUEST 3
|
||||
#define DHCP_DECLINE 4
|
||||
#define DHCP_ACK 5
|
||||
#define DHCP_NAK 6
|
||||
#define DHCP_RELEASE 7
|
||||
#define DHCP_INFORM 8
|
||||
|
||||
#define DHCP_HTYPE10MB 1
|
||||
#define DHCP_HTYPE100MB 2
|
||||
|
||||
#define DHCP_HLENETHERNET 6
|
||||
#define DHCP_HOPS 0
|
||||
#define DHCP_SECS 0
|
||||
|
||||
#define MAGIC_COOKIE 0x63825363
|
||||
#define MAX_DHCP_OPT 16
|
||||
|
||||
#define HOST_NAME "WIZnet"
|
||||
|
||||
enum
|
||||
{
|
||||
padOption = 0,
|
||||
subnetMask = 1,
|
||||
timerOffset = 2,
|
||||
routersOnSubnet = 3,
|
||||
/* timeServer = 4,
|
||||
nameServer = 5,*/
|
||||
dns = 6,
|
||||
/*logServer = 7,
|
||||
cookieServer = 8,
|
||||
lprServer = 9,
|
||||
impressServer = 10,
|
||||
resourceLocationServer = 11,*/
|
||||
hostName = 12,
|
||||
/*bootFileSize = 13,
|
||||
meritDumpFile = 14,*/
|
||||
domainName = 15,
|
||||
/*swapServer = 16,
|
||||
rootPath = 17,
|
||||
extentionsPath = 18,
|
||||
IPforwarding = 19,
|
||||
nonLocalSourceRouting = 20,
|
||||
policyFilter = 21,
|
||||
maxDgramReasmSize = 22,
|
||||
defaultIPTTL = 23,
|
||||
pathMTUagingTimeout = 24,
|
||||
pathMTUplateauTable = 25,
|
||||
ifMTU = 26,
|
||||
allSubnetsLocal = 27,
|
||||
broadcastAddr = 28,
|
||||
performMaskDiscovery = 29,
|
||||
maskSupplier = 30,
|
||||
performRouterDiscovery = 31,
|
||||
routerSolicitationAddr = 32,
|
||||
staticRoute = 33,
|
||||
trailerEncapsulation = 34,
|
||||
arpCacheTimeout = 35,
|
||||
ethernetEncapsulation = 36,
|
||||
tcpDefaultTTL = 37,
|
||||
tcpKeepaliveInterval = 38,
|
||||
tcpKeepaliveGarbage = 39,
|
||||
nisDomainName = 40,
|
||||
nisServers = 41,
|
||||
ntpServers = 42,
|
||||
vendorSpecificInfo = 43,
|
||||
netBIOSnameServer = 44,
|
||||
netBIOSdgramDistServer = 45,
|
||||
netBIOSnodeType = 46,
|
||||
netBIOSscope = 47,
|
||||
xFontServer = 48,
|
||||
xDisplayManager = 49,*/
|
||||
dhcpRequestedIPaddr = 50,
|
||||
dhcpIPaddrLeaseTime = 51,
|
||||
/*dhcpOptionOverload = 52,*/
|
||||
dhcpMessageType = 53,
|
||||
dhcpServerIdentifier = 54,
|
||||
dhcpParamRequest = 55,
|
||||
/*dhcpMsg = 56,
|
||||
dhcpMaxMsgSize = 57,*/
|
||||
dhcpT1value = 58,
|
||||
dhcpT2value = 59,
|
||||
/*dhcpClassIdentifier = 60,*/
|
||||
dhcpClientIdentifier = 61,
|
||||
endOption = 255
|
||||
};
|
||||
|
||||
typedef struct _RIP_MSG_FIXED
|
||||
{
|
||||
uint8_t op;
|
||||
uint8_t htype;
|
||||
uint8_t hlen;
|
||||
uint8_t hops;
|
||||
uint32_t xid;
|
||||
uint16_t secs;
|
||||
uint16_t flags;
|
||||
uint8_t ciaddr[4];
|
||||
uint8_t yiaddr[4];
|
||||
uint8_t siaddr[4];
|
||||
uint8_t giaddr[4];
|
||||
uint8_t chaddr[6];
|
||||
}RIP_MSG_FIXED;
|
||||
|
||||
class DhcpClass {
|
||||
private:
|
||||
uint32_t _dhcpInitialTransactionId;
|
||||
uint32_t _dhcpTransactionId;
|
||||
uint8_t _dhcpMacAddr[6];
|
||||
uint8_t _dhcpLocalIp[4];
|
||||
uint8_t _dhcpSubnetMask[4];
|
||||
uint8_t _dhcpGatewayIp[4];
|
||||
uint8_t _dhcpDhcpServerIp[4];
|
||||
uint8_t _dhcpDnsServerIp[4];
|
||||
UDP _dhcpUdpSocket;
|
||||
|
||||
void presend_DHCP();
|
||||
void send_DHCP_MESSAGE(uint8_t, uint16_t);
|
||||
|
||||
uint8_t parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId);
|
||||
public:
|
||||
IPAddress getLocalIp();
|
||||
IPAddress getSubnetMask();
|
||||
IPAddress getGatewayIp();
|
||||
IPAddress getDhcpServerIp();
|
||||
IPAddress getDnsServerIp();
|
||||
|
||||
int beginWithDHCP(uint8_t *, unsigned long timeout = 60000, unsigned long responseTimeout = 4000);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,5 +1,6 @@
|
||||
#include "w5100.h"
|
||||
#include "Ethernet.h"
|
||||
#include "Dhcp.h"
|
||||
|
||||
// XXX: don't make assumptions about the value of MAX_SOCK_NUM.
|
||||
uint8_t EthernetClass::_state[MAX_SOCK_NUM] = {
|
||||
@ -7,30 +8,78 @@ uint8_t EthernetClass::_state[MAX_SOCK_NUM] = {
|
||||
uint16_t EthernetClass::_server_port[MAX_SOCK_NUM] = {
|
||||
0, 0, 0, 0 };
|
||||
|
||||
void EthernetClass::begin(uint8_t *mac, uint8_t *ip)
|
||||
int EthernetClass::begin(uint8_t *mac_address)
|
||||
{
|
||||
uint8_t gateway[4];
|
||||
gateway[0] = ip[0];
|
||||
gateway[1] = ip[1];
|
||||
gateway[2] = ip[2];
|
||||
DhcpClass dhcp;
|
||||
|
||||
// Initialise the basic info
|
||||
W5100.init();
|
||||
W5100.setMACAddress(mac_address);
|
||||
W5100.setIPAddress(IPAddress(0,0,0,0).raw_address());
|
||||
|
||||
// Now try to get our config info from a DHCP server
|
||||
int ret = dhcp.beginWithDHCP(mac_address);
|
||||
if(ret == 1)
|
||||
{
|
||||
// We've successfully found a DHCP server and got our configuration info, so set things
|
||||
// accordingly
|
||||
W5100.setIPAddress(dhcp.getLocalIp().raw_address());
|
||||
W5100.setGatewayIp(dhcp.getGatewayIp().raw_address());
|
||||
W5100.setSubnetMask(dhcp.getSubnetMask().raw_address());
|
||||
_dnsServerAddress = dhcp.getDnsServerIp();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EthernetClass::begin(uint8_t *mac_address, IPAddress local_ip)
|
||||
{
|
||||
// Assume the gateway will be the machine on the same network as the local IP
|
||||
// but with last octet being '1'
|
||||
IPAddress gateway = local_ip;
|
||||
gateway[3] = 1;
|
||||
begin(mac, ip, gateway);
|
||||
begin(mac_address, local_ip, gateway);
|
||||
}
|
||||
|
||||
void EthernetClass::begin(uint8_t *mac, uint8_t *ip, uint8_t *gateway)
|
||||
void EthernetClass::begin(uint8_t *mac_address, IPAddress local_ip, IPAddress gateway)
|
||||
{
|
||||
uint8_t subnet[] = {
|
||||
255, 255, 255, 0 };
|
||||
begin(mac, ip, gateway, subnet);
|
||||
IPAddress subnet(255, 255, 255, 0);
|
||||
begin(mac_address, local_ip, gateway, subnet);
|
||||
}
|
||||
|
||||
void EthernetClass::begin(uint8_t *mac, uint8_t *ip, uint8_t *gateway, uint8_t *subnet)
|
||||
void EthernetClass::begin(uint8_t *mac, IPAddress local_ip, IPAddress gateway, IPAddress subnet)
|
||||
{
|
||||
W5100.init();
|
||||
W5100.setMACAddress(mac);
|
||||
W5100.setIPAddress(ip);
|
||||
W5100.setGatewayIp(gateway);
|
||||
W5100.setSubnetMask(subnet);
|
||||
W5100.setIPAddress(local_ip._address);
|
||||
W5100.setGatewayIp(gateway._address);
|
||||
W5100.setSubnetMask(subnet._address);
|
||||
}
|
||||
|
||||
IPAddress EthernetClass::localIP()
|
||||
{
|
||||
IPAddress ret;
|
||||
W5100.getIPAddress(ret.raw_address());
|
||||
return ret;
|
||||
}
|
||||
|
||||
IPAddress EthernetClass::subnetMask()
|
||||
{
|
||||
IPAddress ret;
|
||||
W5100.getSubnetMask(ret.raw_address());
|
||||
return ret;
|
||||
}
|
||||
|
||||
IPAddress EthernetClass::gatewayIP()
|
||||
{
|
||||
IPAddress ret;
|
||||
W5100.getGatewayIp(ret.raw_address());
|
||||
return ret;
|
||||
}
|
||||
|
||||
IPAddress EthernetClass::dnsServerIP()
|
||||
{
|
||||
return _dnsServerAddress;
|
||||
}
|
||||
|
||||
EthernetClass Ethernet;
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
//#include "w5100.h"
|
||||
#include "IPAddress.h"
|
||||
#include "Client.h"
|
||||
#include "Server.h"
|
||||
|
||||
@ -10,12 +11,23 @@
|
||||
|
||||
class EthernetClass {
|
||||
private:
|
||||
IPAddress _dnsServerAddress;
|
||||
public:
|
||||
static uint8_t _state[MAX_SOCK_NUM];
|
||||
static uint16_t _server_port[MAX_SOCK_NUM];
|
||||
void begin(uint8_t *, uint8_t *);
|
||||
void begin(uint8_t *, uint8_t *, uint8_t *);
|
||||
void begin(uint8_t *, uint8_t *, uint8_t *, uint8_t *);
|
||||
// Initialise the Ethernet shield to use the provided MAC address and gain the rest of the
|
||||
// configuration through DHCP.
|
||||
// Returns 0 if the DHCP configuration failed, and 1 if it succeeded
|
||||
int begin(uint8_t *mac_address);
|
||||
void begin(uint8_t *mac_address, IPAddress local_ip);
|
||||
void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress gateway);
|
||||
void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress gateway, IPAddress subnet);
|
||||
|
||||
IPAddress localIP();
|
||||
IPAddress subnetMask();
|
||||
IPAddress gatewayIP();
|
||||
IPAddress dnsServerIP();
|
||||
|
||||
friend class Client;
|
||||
friend class Server;
|
||||
};
|
||||
|
@ -37,3 +37,8 @@ IPAddress& IPAddress::operator=(uint32_t address)
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool IPAddress::operator==(const uint8_t* addr)
|
||||
{
|
||||
return memcmp(addr, _address, sizeof(_address)) == 0;
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,11 @@
|
||||
class IPAddress {
|
||||
private:
|
||||
uint8_t _address[4]; // IPv4 address
|
||||
// Access the raw byte array containing the address. Because this returns a pointer
|
||||
// to the internal structure rather than a copy of the address this function should only
|
||||
// be used when you know that the usage of the returned uint8_t* will be transient and not
|
||||
// stored.
|
||||
uint8_t* raw_address() { return _address; };
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
@ -41,7 +46,9 @@ public:
|
||||
|
||||
// Overloaded cast operator to allow IPAddress objects to be used where a pointer
|
||||
// to a four-byte uint8_t array is expected
|
||||
operator uint8_t*() { return _address; };
|
||||
operator uint32_t() { return *((uint32_t*)_address); };
|
||||
bool operator==(const IPAddress& addr) { return (*((uint32_t*)_address)) == (*((uint32_t*)addr._address)); };
|
||||
bool operator==(const uint8_t* addr);
|
||||
|
||||
// Overloaded index operator to allow getting and setting individual octets of the address
|
||||
uint8_t operator[](int index) const { return _address[index]; };
|
||||
@ -50,6 +57,12 @@ public:
|
||||
// Overloaded copy operators to allow initialisation of IPAddress objects from other types
|
||||
IPAddress& operator=(const uint8_t *address);
|
||||
IPAddress& operator=(uint32_t address);
|
||||
|
||||
friend class EthernetClass;
|
||||
friend class UDP;
|
||||
friend class Client;
|
||||
friend class Server;
|
||||
friend class DhcpClass;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -77,7 +77,7 @@ void UDP::stop()
|
||||
int UDP::beginPacket(IPAddress ip, uint16_t port)
|
||||
{
|
||||
_offset = 0;
|
||||
return startUDP(_sock, ip, port);
|
||||
return startUDP(_sock, ip.raw_address(), port);
|
||||
}
|
||||
|
||||
int UDP::endPacket()
|
||||
|
@ -31,12 +31,9 @@
|
||||
byte mac[] = {
|
||||
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
|
||||
// assign an IP address for the controller:
|
||||
byte ip[] = {
|
||||
192,168,1,20 };
|
||||
byte gateway[] = {
|
||||
192,168,1,1};
|
||||
byte subnet[] = {
|
||||
255, 255, 255, 0 };
|
||||
IPAddress ip(192,168,1,20);
|
||||
IPAddress gateway(192,168,1,1);
|
||||
IPAddress subnet(255, 255, 255, 0);
|
||||
|
||||
|
||||
// Initialize the Ethernet server library
|
||||
|
@ -24,9 +24,9 @@
|
||||
// The IP address will be dependent on your local network.
|
||||
// gateway and subnet are optional:
|
||||
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
|
||||
byte ip[] = { 192,168,1, 177 };
|
||||
byte gateway[] = { 192,168,1, 1 };
|
||||
byte subnet[] = { 255, 255, 0, 0 };
|
||||
IPAddress ip(192,168,1, 177);
|
||||
IPAddress gateway(192,168,1, 1);
|
||||
IPAddress subnet(255, 255, 0, 0);
|
||||
|
||||
// telnet defaults to port 23
|
||||
Server server(23);
|
||||
@ -60,4 +60,4 @@ void loop() {
|
||||
// echo the bytes to the server as well:
|
||||
Serial.print(thisChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,20 +23,13 @@
|
||||
#include <Ethernet.h>
|
||||
|
||||
// assign a MAC address for the ethernet controller.
|
||||
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
|
||||
// fill in your address here:
|
||||
byte mac[] = {
|
||||
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
|
||||
// assign an IP address for the controller:
|
||||
byte ip[] = {
|
||||
192,169,1,20 };
|
||||
byte gateway[] = {
|
||||
192,168,1,1};
|
||||
byte subnet[] = {
|
||||
255, 255, 255, 0 };
|
||||
|
||||
// The address of the server you want to connect to (pachube.com):
|
||||
byte server[] = {
|
||||
209,40,205,190 };
|
||||
IPAddress server(209,40,205,190);
|
||||
|
||||
// initialize the library instance:
|
||||
Client client(server, 80);
|
||||
@ -46,9 +39,15 @@ boolean lastConnected = false; // state of the connection last time through
|
||||
const int postingInterval = 10000; //delay between updates to Pachube.com
|
||||
|
||||
void setup() {
|
||||
// start the ethernet connection and serial port:
|
||||
Ethernet.begin(mac, ip);
|
||||
// start serial port:
|
||||
Serial.begin(9600);
|
||||
// start the Ethernet connection:
|
||||
if (Ethernet.begin(mac) == 0) {
|
||||
Serial.println("Failed to configure Ethernet using DHCP");
|
||||
// no point in carrying on, so do nothing forevermore:
|
||||
for(;;)
|
||||
;
|
||||
}
|
||||
// give the ethernet module time to boot up:
|
||||
delay(1000);
|
||||
}
|
||||
|
@ -29,16 +29,12 @@
|
||||
byte mac[] = {
|
||||
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
|
||||
// assign an IP address for the controller:
|
||||
byte ip[] = {
|
||||
192,169,1,20 };
|
||||
byte gateway[] = {
|
||||
192,168,1,1};
|
||||
byte subnet[] = {
|
||||
255, 255, 255, 0 };
|
||||
IPAddress ip(192,169,1,20);
|
||||
IPAddress gateway(192,168,1,1);
|
||||
IPAddress subnet(255, 255, 255, 0);
|
||||
|
||||
// The address of the server you want to connect to (pachube.com):
|
||||
byte server[] = {
|
||||
209,40,205,190 };
|
||||
IPAddress server(209,40,205,190);
|
||||
|
||||
// initialize the library instance:
|
||||
Client client(server, 80);
|
||||
|
@ -24,12 +24,10 @@
|
||||
// The IP address will be dependent on your local network:
|
||||
byte mac[] = {
|
||||
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
|
||||
byte ip[] = {
|
||||
192,168,1,177 };
|
||||
IPAddress ip(192,168,1,177);
|
||||
|
||||
// Enter the IP address of the server you're connecting to:
|
||||
byte server[] = {
|
||||
1,1,1,1 };
|
||||
IPAddress server(1,1,1,1);
|
||||
|
||||
// Initialize the Ethernet client library
|
||||
// with the IP address and port of the server
|
||||
|
@ -20,13 +20,11 @@
|
||||
#include <Ethernet.h>
|
||||
#include <Udp.h>
|
||||
|
||||
// Enter a MAC address and IP address for your controller below.
|
||||
// The IP address will be dependent on your local network:
|
||||
// Enter a MAC address for your controller below.
|
||||
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
|
||||
byte mac[] = {
|
||||
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
|
||||
|
||||
IPAddress ip(192, 168, 1, 177);
|
||||
|
||||
unsigned int localPort = 8888; // local port to listen for UDP packets
|
||||
|
||||
IPAddress timeServer(192, 43, 244, 18); // time.nist.gov NTP server
|
||||
@ -40,11 +38,16 @@ UDP Udp;
|
||||
|
||||
void setup()
|
||||
{
|
||||
// start Ethernet and UDP
|
||||
Ethernet.begin(mac,ip);
|
||||
Udp.begin(localPort);
|
||||
|
||||
Serial.begin(9600);
|
||||
|
||||
// start Ethernet and UDP
|
||||
if (Ethernet.begin(mac) == 0) {
|
||||
Serial.println("Failed to configure Ethernet using DHCP");
|
||||
// no point in carrying on, so do nothing forevermore:
|
||||
for(;;)
|
||||
;
|
||||
}
|
||||
Udp.begin(localPort);
|
||||
}
|
||||
|
||||
void loop()
|
||||
@ -99,7 +102,7 @@ void loop()
|
||||
}
|
||||
|
||||
// send an NTP request to the time server at the given address
|
||||
unsigned long sendNTPpacket(byte *address)
|
||||
unsigned long sendNTPpacket(IPAddress& address)
|
||||
{
|
||||
// set all bytes in the buffer to 0
|
||||
memset(packetBuffer, 0, NTP_PACKET_SIZE);
|
||||
|
@ -15,11 +15,10 @@
|
||||
#include <SPI.h>
|
||||
#include <Ethernet.h>
|
||||
|
||||
// Enter a MAC address and IP address for your controller below.
|
||||
// The IP address will be dependent on your local network:
|
||||
// Enter a MAC address for your controller below.
|
||||
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
|
||||
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
|
||||
byte ip[] = { 192,168,1,177 };
|
||||
byte server[] = { 173,194,33,104 }; // Google
|
||||
IPAddress server(173,194,33,104); // Google
|
||||
|
||||
// Initialize the Ethernet client library
|
||||
// with the IP address and port of the server
|
||||
@ -27,10 +26,15 @@ byte server[] = { 173,194,33,104 }; // Google
|
||||
Client client(server, 80);
|
||||
|
||||
void setup() {
|
||||
// start the Ethernet connection:
|
||||
Ethernet.begin(mac, ip);
|
||||
// start the serial library:
|
||||
Serial.begin(9600);
|
||||
// start the Ethernet connection:
|
||||
if (Ethernet.begin(mac) == 0) {
|
||||
Serial.println("Failed to configure Ethernet using DHCP");
|
||||
// no point in carrying on, so do nothing forevermore:
|
||||
for(;;)
|
||||
;
|
||||
}
|
||||
// give the Ethernet shield a second to initialize:
|
||||
delay(1000);
|
||||
Serial.println("connecting...");
|
||||
|
@ -21,7 +21,7 @@
|
||||
// Enter a MAC address and IP address for your controller below.
|
||||
// The IP address will be dependent on your local network:
|
||||
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
|
||||
byte ip[] = { 192,168,1, 177 };
|
||||
IPAddress ip(192,168,1, 177);
|
||||
|
||||
// Initialize the Ethernet server library
|
||||
// with the IP address and port you want to use
|
||||
@ -79,4 +79,4 @@ void loop()
|
||||
// close the connection:
|
||||
client.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
13
libraries/Ethernet/util.h
Normal file
13
libraries/Ethernet/util.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#define htons(x) ( (x)<<8 | ((x)>>8)&0xFF )
|
||||
#define ntohs(x) htons(x)
|
||||
|
||||
#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \
|
||||
((x)<< 8 & 0x00FF0000UL) | \
|
||||
((x)>> 8 & 0x0000FF00UL) | \
|
||||
((x)>>24 & 0x000000FFUL) )
|
||||
#define ntohl(x) htonl(x)
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user