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:
amcewen 2011-01-16 20:11:50 +00:00
parent 5caad5bdb4
commit a42dc0b455
18 changed files with 662 additions and 74 deletions

View File

@ -16,7 +16,7 @@ uint16_t Client::_srcport = 1024;
Client::Client(uint8_t sock) : _sock(sock) { 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() { uint8_t Client::connect() {
@ -38,7 +38,7 @@ uint8_t Client::connect() {
if (_srcport == 0) _srcport = 1024; if (_srcport == 0) _srcport = 1024;
socket(_sock, SnMR::TCP, _srcport, 0); socket(_sock, SnMR::TCP, _srcport, 0);
if (!::connect(_sock, _ip, _port)) { if (!::connect(_sock, _ip.raw_address(), _port)) {
_sock = MAX_SOCK_NUM; _sock = MAX_SOCK_NUM;
return 0; return 0;
} }

View File

@ -7,8 +7,8 @@ class Client : public Stream {
public: public:
Client(); Client();
Client(uint8_t); Client(uint8_t sock);
Client(uint8_t *, uint16_t); Client(IPAddress& ip, uint16_t port);
uint8_t status(); uint8_t status();
uint8_t connect(); uint8_t connect();
@ -31,7 +31,7 @@ public:
private: private:
static uint16_t _srcport; static uint16_t _srcport;
uint8_t _sock; uint8_t _sock;
uint8_t *_ip; IPAddress _ip;
uint16_t _port; uint16_t _port;
}; };

341
libraries/Ethernet/Dhcp.cpp Executable file
View 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
View 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

View File

@ -1,5 +1,6 @@
#include "w5100.h" #include "w5100.h"
#include "Ethernet.h" #include "Ethernet.h"
#include "Dhcp.h"
// XXX: don't make assumptions about the value of MAX_SOCK_NUM. // XXX: don't make assumptions about the value of MAX_SOCK_NUM.
uint8_t EthernetClass::_state[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] = { uint16_t EthernetClass::_server_port[MAX_SOCK_NUM] = {
0, 0, 0, 0 }; 0, 0, 0, 0 };
void EthernetClass::begin(uint8_t *mac, uint8_t *ip) int EthernetClass::begin(uint8_t *mac_address)
{ {
uint8_t gateway[4]; DhcpClass dhcp;
gateway[0] = ip[0];
gateway[1] = ip[1]; // Initialise the basic info
gateway[2] = ip[2]; 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; 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[] = { IPAddress subnet(255, 255, 255, 0);
255, 255, 255, 0 }; begin(mac_address, local_ip, gateway, subnet);
begin(mac, 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.init();
W5100.setMACAddress(mac); W5100.setMACAddress(mac);
W5100.setIPAddress(ip); W5100.setIPAddress(local_ip._address);
W5100.setGatewayIp(gateway); W5100.setGatewayIp(gateway._address);
W5100.setSubnetMask(subnet); 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; EthernetClass Ethernet;

View File

@ -3,6 +3,7 @@
#include <inttypes.h> #include <inttypes.h>
//#include "w5100.h" //#include "w5100.h"
#include "IPAddress.h"
#include "Client.h" #include "Client.h"
#include "Server.h" #include "Server.h"
@ -10,12 +11,23 @@
class EthernetClass { class EthernetClass {
private: private:
IPAddress _dnsServerAddress;
public: public:
static uint8_t _state[MAX_SOCK_NUM]; static uint8_t _state[MAX_SOCK_NUM];
static uint16_t _server_port[MAX_SOCK_NUM]; static uint16_t _server_port[MAX_SOCK_NUM];
void begin(uint8_t *, uint8_t *); // Initialise the Ethernet shield to use the provided MAC address and gain the rest of the
void begin(uint8_t *, uint8_t *, uint8_t *); // configuration through DHCP.
void begin(uint8_t *, uint8_t *, uint8_t *, uint8_t *); // 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 Client;
friend class Server; friend class Server;
}; };

View File

@ -37,3 +37,8 @@ IPAddress& IPAddress::operator=(uint32_t address)
return *this; return *this;
} }
bool IPAddress::operator==(const uint8_t* addr)
{
return memcmp(addr, _address, sizeof(_address)) == 0;
}

View File

@ -31,6 +31,11 @@
class IPAddress { class IPAddress {
private: private:
uint8_t _address[4]; // IPv4 address 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: public:
// Constructors // Constructors
@ -41,7 +46,9 @@ public:
// Overloaded cast operator to allow IPAddress objects to be used where a pointer // Overloaded cast operator to allow IPAddress objects to be used where a pointer
// to a four-byte uint8_t array is expected // 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 // Overloaded index operator to allow getting and setting individual octets of the address
uint8_t operator[](int index) const { return _address[index]; }; 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 // Overloaded copy operators to allow initialisation of IPAddress objects from other types
IPAddress& operator=(const uint8_t *address); IPAddress& operator=(const uint8_t *address);
IPAddress& operator=(uint32_t address); IPAddress& operator=(uint32_t address);
friend class EthernetClass;
friend class UDP;
friend class Client;
friend class Server;
friend class DhcpClass;
}; };
#endif #endif

View File

@ -77,7 +77,7 @@ void UDP::stop()
int UDP::beginPacket(IPAddress ip, uint16_t port) int UDP::beginPacket(IPAddress ip, uint16_t port)
{ {
_offset = 0; _offset = 0;
return startUDP(_sock, ip, port); return startUDP(_sock, ip.raw_address(), port);
} }
int UDP::endPacket() int UDP::endPacket()

View File

@ -31,12 +31,9 @@
byte mac[] = { byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
// assign an IP address for the controller: // assign an IP address for the controller:
byte ip[] = { IPAddress ip(192,168,1,20);
192,168,1,20 }; IPAddress gateway(192,168,1,1);
byte gateway[] = { IPAddress subnet(255, 255, 255, 0);
192,168,1,1};
byte subnet[] = {
255, 255, 255, 0 };
// Initialize the Ethernet server library // Initialize the Ethernet server library

View File

@ -24,9 +24,9 @@
// The IP address will be dependent on your local network. // The IP address will be dependent on your local network.
// gateway and subnet are optional: // gateway and subnet are optional:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1, 177 }; IPAddress ip(192,168,1, 177);
byte gateway[] = { 192,168,1, 1 }; IPAddress gateway(192,168,1, 1);
byte subnet[] = { 255, 255, 0, 0 }; IPAddress subnet(255, 255, 0, 0);
// telnet defaults to port 23 // telnet defaults to port 23
Server server(23); Server server(23);

View File

@ -23,20 +23,13 @@
#include <Ethernet.h> #include <Ethernet.h>
// assign a MAC address for the ethernet controller. // 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: // fill in your address here:
byte mac[] = { byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; 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): // The address of the server you want to connect to (pachube.com):
byte server[] = { IPAddress server(209,40,205,190);
209,40,205,190 };
// initialize the library instance: // initialize the library instance:
Client client(server, 80); 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 const int postingInterval = 10000; //delay between updates to Pachube.com
void setup() { void setup() {
// start the ethernet connection and serial port: // start serial port:
Ethernet.begin(mac, ip);
Serial.begin(9600); 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: // give the ethernet module time to boot up:
delay(1000); delay(1000);
} }

View File

@ -29,16 +29,12 @@
byte mac[] = { byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
// assign an IP address for the controller: // assign an IP address for the controller:
byte ip[] = { IPAddress ip(192,169,1,20);
192,169,1,20 }; IPAddress gateway(192,168,1,1);
byte gateway[] = { IPAddress subnet(255, 255, 255, 0);
192,168,1,1};
byte subnet[] = {
255, 255, 255, 0 };
// The address of the server you want to connect to (pachube.com): // The address of the server you want to connect to (pachube.com):
byte server[] = { IPAddress server(209,40,205,190);
209,40,205,190 };
// initialize the library instance: // initialize the library instance:
Client client(server, 80); Client client(server, 80);

View File

@ -24,12 +24,10 @@
// The IP address will be dependent on your local network: // The IP address will be dependent on your local network:
byte mac[] = { byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { IPAddress ip(192,168,1,177);
192,168,1,177 };
// Enter the IP address of the server you're connecting to: // Enter the IP address of the server you're connecting to:
byte server[] = { IPAddress server(1,1,1,1);
1,1,1,1 };
// Initialize the Ethernet client library // Initialize the Ethernet client library
// with the IP address and port of the server // with the IP address and port of the server

View File

@ -20,13 +20,11 @@
#include <Ethernet.h> #include <Ethernet.h>
#include <Udp.h> #include <Udp.h>
// Enter a MAC address and IP address for your controller below. // Enter a MAC address for your controller below.
// The IP address will be dependent on your local network: // Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);
unsigned int localPort = 8888; // local port to listen for UDP packets unsigned int localPort = 8888; // local port to listen for UDP packets
IPAddress timeServer(192, 43, 244, 18); // time.nist.gov NTP server IPAddress timeServer(192, 43, 244, 18); // time.nist.gov NTP server
@ -40,11 +38,16 @@ UDP Udp;
void setup() void setup()
{ {
// start Ethernet and UDP
Ethernet.begin(mac,ip);
Udp.begin(localPort);
Serial.begin(9600); 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() void loop()
@ -99,7 +102,7 @@ void loop()
} }
// send an NTP request to the time server at the given address // 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 // set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE); memset(packetBuffer, 0, NTP_PACKET_SIZE);

View File

@ -15,11 +15,10 @@
#include <SPI.h> #include <SPI.h>
#include <Ethernet.h> #include <Ethernet.h>
// Enter a MAC address and IP address for your controller below. // Enter a MAC address for your controller below.
// The IP address will be dependent on your local network: // Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1,177 }; IPAddress server(173,194,33,104); // Google
byte server[] = { 173,194,33,104 }; // Google
// Initialize the Ethernet client library // Initialize the Ethernet client library
// with the IP address and port of the server // with the IP address and port of the server
@ -27,10 +26,15 @@ byte server[] = { 173,194,33,104 }; // Google
Client client(server, 80); Client client(server, 80);
void setup() { void setup() {
// start the Ethernet connection:
Ethernet.begin(mac, ip);
// start the serial library: // start the serial library:
Serial.begin(9600); 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: // give the Ethernet shield a second to initialize:
delay(1000); delay(1000);
Serial.println("connecting..."); Serial.println("connecting...");

View File

@ -21,7 +21,7 @@
// Enter a MAC address and IP address for your controller below. // Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network: // The IP address will be dependent on your local network:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 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 // Initialize the Ethernet server library
// with the IP address and port you want to use // with the IP address and port you want to use

13
libraries/Ethernet/util.h Normal file
View 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