diff --git a/libraries/MySensors/examples/EthernetGateway/EthernetGateway.ino b/libraries/MySensors/examples/EthernetGateway/EthernetGateway.ino index df3b935..a6537e7 100644 --- a/libraries/MySensors/examples/EthernetGateway/EthernetGateway.ino +++ b/libraries/MySensors/examples/EthernetGateway/EthernetGateway.ino @@ -14,11 +14,15 @@ * * The GW code is designed for Arduino 328p / 16MHz. ATmega168 does not have enough memory to run this program. * - * COMPILING - * You must make sure to disable DEBUG in Sensor.h before compiling this sketch. Othervise the sketch won't fit in program space when downloading. - * For UIPEthernet(ENC28J60) usage: Note that I had to disable UDP and DHCP support in uipethernet-conf.h to reduce space. (which meas you ave to choose a static IP) - * For WizNET usage: Do *not* install the provided UIPEthernet-library. Remove UIPEthernet-include below and uncomment the Ethernet.h. + * COMPILING ENC28J60 + * > Use Arduino IDE 1.5.7 (or later) + * > Disable DEBUG in Sensor.h before compiling this sketch. Othervise the sketch will probably not fit in program space when downloading. + * > Remove Ethernet.h include below and inlcude UIPEthernet.h + * COMPILING WizNET (W5100) + * > Remove UIPEthernet include below and include Ethernet.h. * + * Note that I had to disable UDP and DHCP support in uipethernet-conf.h to reduce space. (which meas you ave to choose a static IP for that module) + * VERA CONFIGURATION: * Enter "ip-number:port" in the ip-field of the Arduino GW device. This will temporarily override any serial configuration for the Vera plugin. * E.g. If you want to use the defualt values in this sketch enter: 192.168.178.66:5003 @@ -50,10 +54,10 @@ #include // Use this if you have attached a Ethernet ENC28J60 shields -//#include +#include // Use this fo WizNET module and Arduino Ethernet Shield -#include +//#include #define INCLUSION_MODE_TIME 1 // Number of minutes inclusion mode is enabled @@ -66,7 +70,7 @@ #define RADIO_TX_LED_PIN 9 // the PCB, on board LED #define IP_PORT 5003 // The port you want to open -IPAddress myIp (192, 168, 178, 66); // Configure your static ip-address here +IPAddress myIp (192, 168, 178, 66); // Configure your static ip-address here COMPILE ERROR HERE? Use Arduino IDE 1.5.7 or later! // The MAC address can be anything you want but should be unique on your network. // Newer boards have a MAC address printed on the underside of the PCB, which you can (optionally) use. diff --git a/libraries/UIPEthernet/README b/libraries/UIPEthernet/README index 0fb5d67..ec51f2d 100644 --- a/libraries/UIPEthernet/README +++ b/libraries/UIPEthernet/README @@ -1,4 +1,4 @@ -This is UIPEthernet version 1.01 +This is UIPEthernet version 1.07 An plugin-replacement of the stock Arduino Ethernet library for ENC28J60 shields and breakout boards. Full support for persistent (streaming) TCP-connections and UDP (Client and Server each), ARP, ICMP, DHCP and DNS. Just include 'UIPEthernet.h' instead of 'Ethernet.h' and use all your code written for the stock Arduino Ethernet lib! @@ -26,7 +26,9 @@ On a Mac, you will want to create a folder named "libraries" in in the "Document $ cd ~/Documents/Arduino/libraries $ git clone https://github.com/ntruchsess/arduino_uip UIPEthernet -Or you download the zipped version of the library from https://github.com/ntruchsess/arduino_uip/archive/master.zip, create a directory [path to Arduino distribution]\libraries\UIPEthernet and put the contents of the zip-file there. +Or you download the zipped version of the library from https://github.com/ntruchsess/arduino_uip/releases, and copy the contained directory UIPEthernet to [path to Arduino distribution]\libraries\UIPEthernet. + +If you are running Arduino-IDE 1.5.x use release-version 1.57 or checkout branch 'Arduino_1.5.5' Additional information can be found on the Arduino website: http://www.arduino.cc/en/Hacking/Libraries diff --git a/libraries/UIPEthernet/UIPClient.cpp b/libraries/UIPEthernet/UIPClient.cpp index 73daaba..ffbb3e1 100644 --- a/libraries/UIPEthernet/UIPClient.cpp +++ b/libraries/UIPEthernet/UIPClient.cpp @@ -49,19 +49,22 @@ UIPClient::UIPClient(uip_userdata_t* conn_data) : int UIPClient::connect(IPAddress ip, uint16_t port) { + stop(); uip_ipaddr_t ipaddr; uip_ip_addr(ipaddr, ip); struct uip_conn* conn = uip_connect(&ipaddr, htons(port)); if (conn) { +#if UIP_CONNECT_TIMEOUT > 0 + int32_t timeout = millis() + 1000 * UIP_CONNECT_TIMEOUT; +#endif while((conn->tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) { - UIPEthernet.tick(); + UIPEthernetClass::tick(); if ((conn->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) { data = (uip_userdata_t*) conn->appstate; #ifdef UIPETHERNET_DEBUG_CLIENT - Serial.print(F("connected, state: ")); Serial.print(data->state); Serial.print(F(", first packet in: ")); @@ -69,6 +72,13 @@ UIPClient::connect(IPAddress ip, uint16_t port) #endif return 1; } +#if UIP_CONNECT_TIMEOUT > 0 + if (((int32_t)(millis() - timeout)) > 0) + { + conn->tcpstateflags = UIP_CLOSED; + break; + } +#endif } } return 0; @@ -83,7 +93,7 @@ UIPClient::connect(const char *host, uint16_t port) DNSClient dns; IPAddress remote_addr; - dns.begin(UIPEthernet.dnsServerIP()); + dns.begin(UIPEthernetClass::_dnsServerAddress); ret = dns.getHostByName(host, remote_addr); if (ret == 1) { return connect(remote_addr, port); @@ -95,10 +105,14 @@ UIPClient::connect(const char *host, uint16_t port) void UIPClient::stop() { - if (data) + if (data && data->state) { +#ifdef UIPETHERNET_DEBUG_CLIENT + Serial.println(F("before stop(), with data")); + _dumpAllData(); +#endif _flushBlocks(&data->packets_in[0]); - if (data->state & UIP_CLIENT_CLOSED) + if (data->state & UIP_CLIENT_REMOTECLOSED) { data->state = 0; } @@ -106,9 +120,19 @@ UIPClient::stop() { data->state |= UIP_CLIENT_CLOSE; } +#ifdef UIPETHERNET_DEBUG_CLIENT + Serial.println(F("after stop()")); + _dumpAllData(); +#endif } +#ifdef UIPETHERNET_DEBUG_CLIENT + else + { + Serial.println(F("stop(), data: NULL")); + } +#endif data = NULL; - UIPEthernet.tick(); + UIPEthernetClass::tick(); } uint8_t @@ -125,8 +149,8 @@ UIPClient::operator==(const UIPClient& rhs) UIPClient::operator bool() { - UIPEthernet.tick(); - return data && (!(data->state & UIP_CLIENT_CLOSED) || data->packets_in[0] != NOBLOCK); + UIPEthernetClass::tick(); + return data && (!(data->state & UIP_CLIENT_REMOTECLOSED) || data->packets_in[0] != NOBLOCK); } size_t @@ -150,15 +174,15 @@ UIPClient::_write(uip_userdata_t* u, const uint8_t *buf, size_t size) uint16_t attempts = UIP_ATTEMPTS_ON_WRITE; #endif repeat: - UIPEthernet.tick(); - if (u && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_CLOSED))) + UIPEthernetClass::tick(); + if (u && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED))) { - memhandle* p = _currentBlock(&u->packets_out[0]); - if (*p == NOBLOCK) + uint8_t p = _currentBlock(&u->packets_out[0]); + if (u->packets_out[p] == NOBLOCK) { newpacket: - *p = UIPEthernet.network.allocBlock(UIP_SOCKET_DATALEN); - if (*p == NOBLOCK) + u->packets_out[p] = Enc28J60Network::allocBlock(UIP_SOCKET_DATALEN); + if (u->packets_out[p] == NOBLOCK) { #if UIP_ATTEMPTS_ON_WRITE > 0 if ((--attempts)>0) @@ -172,7 +196,7 @@ newpacket: } #ifdef UIPETHERNET_DEBUG_CLIENT Serial.print(F("UIPClient.write: writePacket(")); - Serial.print(*p); + Serial.print(u->packets_out[p]); Serial.print(F(") pos: ")); Serial.print(u->out_pos); Serial.print(F(", buf[")); @@ -183,12 +207,12 @@ newpacket: Serial.write((uint8_t*)buf+size-remain,remain); Serial.println(F("'")); #endif - written = UIPEthernet.network.writePacket(*p,u->out_pos,(uint8_t*)buf+size-remain,remain); + written = Enc28J60Network::writePacket(u->packets_out[p],u->out_pos,(uint8_t*)buf+size-remain,remain); remain -= written; u->out_pos+=written; if (remain > 0) { - if (p==&u->packets_out[UIP_SOCKET_NUMPACKETS-1]) + if (p == UIP_SOCKET_NUMPACKETS-1) { #if UIP_ATTEMPTS_ON_WRITE > 0 if ((--attempts)>0) @@ -218,15 +242,10 @@ UIPClient::available() int UIPClient::_available(uip_userdata_t *u) { - memhandle* p = &u->packets_in[0]; - if (*p == NOBLOCK) - return 0; int len = 0; - for(memhandle* end = p+UIP_SOCKET_NUMPACKETS; p < end; p++) + for (uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS; i++) { - if(*p == NOBLOCK) - break; - len += UIPEthernet.network.blockSize(*p); + len += Enc28J60Network::blockSize(u->packets_in[i]); } return len; } @@ -236,23 +255,22 @@ UIPClient::read(uint8_t *buf, size_t size) { if (*this) { - int remain = size; - memhandle* p = &data->packets_in[0]; - if (*p == NOBLOCK) + uint16_t remain = size; + if (data->packets_in[0] == NOBLOCK) return 0; - int read; + uint16_t read; do { - read = UIPEthernet.network.readPacket(*p,0,buf+size-remain,remain); - if (read == UIPEthernet.network.blockSize(*p)) + read = Enc28J60Network::readPacket(data->packets_in[0],0,buf+size-remain,remain); + if (read == Enc28J60Network::blockSize(data->packets_in[0])) { remain -= read; - _eatBlock(p); - if (uip_stopped(&uip_conns[data->state & UIP_CLIENT_SOCKETS]) && !(data->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_CLOSED))) + _eatBlock(&data->packets_in[0]); + if (uip_stopped(&uip_conns[data->state & UIP_CLIENT_SOCKETS]) && !(data->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED))) data->state |= UIP_CLIENT_RESTART; - if (*p == NOBLOCK) + if (data->packets_in[0] == NOBLOCK) { - if (data->state & UIP_CLIENT_CLOSED) + if (data->state & UIP_CLIENT_REMOTECLOSED) { data->state = 0; data = NULL; @@ -262,7 +280,7 @@ UIPClient::read(uint8_t *buf, size_t size) } else { - UIPEthernet.network.resizeBlock(*p,read); + Enc28J60Network::resizeBlock(data->packets_in[0],read); break; } } @@ -286,11 +304,10 @@ UIPClient::peek() { if (*this) { - memhandle p = data->packets_in[0]; - if (p != NOBLOCK) + if (data->packets_in[0] != NOBLOCK) { uint8_t c; - UIPEthernet.network.readPacket(p,0,&c,1); + Enc28J60Network::readPacket(data->packets_in[0],0,&c,1); return c; } } @@ -308,26 +325,21 @@ UIPClient::flush() void uipclient_appcall(void) -{ - UIPClient::uip_callback(); -} - -void -UIPClient::uip_callback() { uip_userdata_t *u = (uip_userdata_t*)uip_conn->appstate; if (!u && uip_connected()) { #ifdef UIPETHERNET_DEBUG_CLIENT Serial.println(F("UIPClient uip_connected")); + UIPClient::_dumpAllData(); #endif - u = (uip_userdata_t*) _allocateData(); + u = (uip_userdata_t*) UIPClient::_allocateData(); if (u) { uip_conn->appstate = u; #ifdef UIPETHERNET_DEBUG_CLIENT Serial.print(F("UIPClient allocated state: ")); - Serial.println(u->state); + Serial.println(u->state,BIN); #endif } #ifdef UIPETHERNET_DEBUG_CLIENT @@ -343,33 +355,24 @@ UIPClient::uip_callback() Serial.print(F("UIPClient uip_newdata, uip_len:")); Serial.println(uip_len); #endif - if (uip_len && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_CLOSED))) + if (uip_len && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED))) { - memhandle newPacket = UIPEthernet.network.allocBlock(uip_len); + memhandle newPacket = Enc28J60Network::allocBlock(uip_len); if (newPacket != NOBLOCK) { - memhandle* p = _currentBlock(&u->packets_in[0]); - //if it's not the first packet - if (*p != NOBLOCK) + for (uint8_t i=0; i < UIP_SOCKET_NUMPACKETS; i++) { - uint8_t slot = p - &u->packets_in[0]; - if (slot < UIP_SOCKET_NUMPACKETS-1) - p++; - //if this is the last slot stop this connection - if (slot >= UIP_SOCKET_NUMPACKETS-2) + if (u->packets_in[i] == NOBLOCK) { - uip_stop(); - //if there's no free slot left omit loosing this packet and (again) stop this connection - if (slot == UIP_SOCKET_NUMPACKETS-1) - goto reject_newdata; + if (i == UIP_SOCKET_NUMPACKETS-1) + uip_stop(); + Enc28J60Network::copyPacket(newPacket,0,UIPEthernetClass::in_packet,((uint8_t*)uip_appdata)-uip_buf,uip_len); + u->packets_in[i] = newPacket; + goto finish_newdata; } } - UIPEthernet.network.copyPacket(newPacket,0,UIPEthernet.in_packet,((uint8_t*)uip_appdata)-uip_buf,uip_len); - *p = newPacket; - goto finish_newdata; } -reject_newdata: - UIPEthernet.packetstate &= ~UIPETHERNET_FREEPACKET; + UIPEthernetClass::packetstate &= ~UIPETHERNET_FREEPACKET; uip_stop(); } } @@ -384,17 +387,22 @@ finish_newdata: { #ifdef UIPETHERNET_DEBUG_CLIENT Serial.println(F("UIPClient uip_closed")); + UIPClient::_dumpAllData(); #endif // drop outgoing packets not sent yet: - _flushBlocks(&u->packets_out[0]); + UIPClient::_flushBlocks(&u->packets_out[0]); if (u->packets_in[0] != NOBLOCK) { ((uip_userdata_closed_t *)u)->lport = uip_conn->lport; - u->state |= UIP_CLIENT_CLOSED; + u->state |= UIP_CLIENT_REMOTECLOSED; } else u->state = 0; // disassociate appdata. +#ifdef UIPETHERNET_DEBUG_CLIENT + Serial.println(F("after UIPClient uip_closed")); + UIPClient::_dumpAllData(); +#endif uip_conn->appstate = NULL; goto nodata; } @@ -403,34 +411,33 @@ finish_newdata: #ifdef UIPETHERNET_DEBUG_CLIENT Serial.println(F("UIPClient uip_acked")); #endif - _eatBlock(&u->packets_out[0]); + UIPClient::_eatBlock(&u->packets_out[0]); } if (uip_poll() || uip_rexmit()) { #ifdef UIPETHERNET_DEBUG_CLIENT //Serial.println(F("UIPClient uip_poll")); #endif - memhandle p = u->packets_out[0]; - if (p != NOBLOCK) + if (u->packets_out[0] != NOBLOCK) { if (u->packets_out[1] == NOBLOCK) { uip_len = u->out_pos; if (uip_len > 0) { - UIPEthernet.network.resizeBlock(p,0,uip_len); + Enc28J60Network::resizeBlock(u->packets_out[0],0,uip_len); } } else - uip_len = UIPEthernet.network.blockSize(p); + uip_len = Enc28J60Network::blockSize(u->packets_out[0]); if (uip_len > 0) { - UIPEthernet.uip_hdrlen = ((uint8_t*)uip_appdata)-uip_buf; - UIPEthernet.uip_packet = UIPEthernet.network.allocBlock(UIPEthernet.uip_hdrlen+uip_len); - if (UIPEthernet.uip_packet != NOBLOCK) + UIPEthernetClass::uip_hdrlen = ((uint8_t*)uip_appdata)-uip_buf; + UIPEthernetClass::uip_packet = Enc28J60Network::allocBlock(UIPEthernetClass::uip_hdrlen+uip_len); + if (UIPEthernetClass::uip_packet != NOBLOCK) { - UIPEthernet.network.copyPacket(UIPEthernet.uip_packet,UIPEthernet.uip_hdrlen,p,0,uip_len); - UIPEthernet.packetstate |= UIPETHERNET_SENDPACKET; + Enc28J60Network::copyPacket(UIPEthernetClass::uip_packet,UIPEthernetClass::uip_hdrlen,u->packets_out[0],0,uip_len); + UIPEthernetClass::packetstate |= UIPETHERNET_SENDPACKET; uip_send(uip_appdata,uip_len); } return; @@ -441,23 +448,30 @@ finish_newdata: if (u->state & UIP_CLIENT_CLOSE) { #ifdef UIPETHERNET_DEBUG_CLIENT - Serial.print(F("UIPClient state UIP_CLIENT_CLOSE")); + Serial.println(F("UIPClient state UIP_CLIENT_CLOSE")); + UIPClient::_dumpAllData(); #endif if (u->packets_out[0] == NOBLOCK) { -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.print(F("UIPClient state UIP_CLIENT_CLOSE -> free userdata")); -#endif u->state = 0; uip_conn->appstate = NULL; uip_close(); +#ifdef UIPETHERNET_DEBUG_CLIENT + Serial.println(F("no blocks out -> free userdata")); + UIPClient::_dumpAllData(); +#endif } else - uip_stop(); + { + uip_stop(); +#ifdef UIPETHERNET_DEBUG_CLIENT + Serial.println(F("blocks outstanding transfer -> uip_stop()")); +#endif + } } } nodata: - UIPEthernet.uip_packet = NOBLOCK; + UIPEthernetClass::uip_packet = NOBLOCK; uip_len=0; } @@ -477,13 +491,15 @@ UIPClient::_allocateData() return NULL; } -memhandle* +uint8_t UIPClient::_currentBlock(memhandle* block) { - for(memhandle* end = block+UIP_SOCKET_NUMPACKETS-1; block < end; block++) - if(*(block+1) == NOBLOCK) - break; - return block; + for (uint8_t i = 1; i < UIP_SOCKET_NUMPACKETS; i++) + { + if (block[i] == NOBLOCK) + return i-1; + } + return UIP_SOCKET_NUMPACKETS-1; } void @@ -493,19 +509,20 @@ UIPClient::_eatBlock(memhandle* block) memhandle* start = block; Serial.print(F("eatblock(")); Serial.print(*block); - Serial.print("): "); + Serial.print(F("): ")); for (uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS; i++) { Serial.print(start[i]); - Serial.print(" "); + Serial.print(F(" ")); } - Serial.print("-> "); + Serial.print(F("-> ")); #endif - memhandle* end = block+(UIP_SOCKET_NUMPACKETS-1); - UIPEthernet.network.freeBlock(*block); - while(block < end) - *block = *((block++)+1); - *end = NOBLOCK; + Enc28J60Network::freeBlock(block[0]); + for (uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS-1; i++) + { + block[i] = block[i+1]; + } + block[UIP_SOCKET_NUMPACKETS-1] = NOBLOCK; #ifdef UIPETHERNET_DEBUG_CLIENT for (uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS; i++) { @@ -519,15 +536,46 @@ UIPClient::_eatBlock(memhandle* block) void UIPClient::_flushBlocks(memhandle* block) { - for(memhandle* end = block+UIP_SOCKET_NUMPACKETS; block < end; block++) + for (uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS; i++) { - if(*block != NOBLOCK) - { - UIPEthernet.network.freeBlock(*block); - *block = NOBLOCK; - } - else - break; + Enc28J60Network::freeBlock(block[i]); + block[i] = NOBLOCK; } } +#ifdef UIPETHERNET_DEBUG_CLIENT +void +UIPClient::_dumpAllData() { + for (uint8_t i=0; i < UIP_CONNS; i++) + { + Serial.print(F("UIPClient::all_data[")); + Serial.print(i); + Serial.print(F("], state:")); + Serial.println(all_data[i].state, BIN); + Serial.print(F("packets_in: ")); + for (uint8_t j=0; j < UIP_SOCKET_NUMPACKETS; j++) + { + Serial.print(all_data[i].packets_in[j]); + Serial.print(F(" ")); + } + Serial.println(); + if (all_data[i].state & UIP_CLIENT_REMOTECLOSED) + { + Serial.print(F("state remote closed, local port: ")); + Serial.println(htons(((uip_userdata_closed_t *)(&all_data[i]))->lport)); + } + else + { + Serial.print(F("packets_out: ")); + for (uint8_t j=0; j < UIP_SOCKET_NUMPACKETS; j++) + { + Serial.print(all_data[i].packets_out[j]); + Serial.print(F(" ")); + } + Serial.println(); + Serial.print(F("out_pos: ")); + Serial.println(all_data[i].out_pos); + } + } +} +#endif diff --git a/libraries/UIPEthernet/UIPClient.h b/libraries/UIPEthernet/UIPClient.h index 0d8beab..ac601da 100644 --- a/libraries/UIPEthernet/UIPClient.h +++ b/libraries/UIPEthernet/UIPClient.h @@ -21,6 +21,7 @@ #define UIPCLIENT_H #include "ethernet_comp.h" +#include "Print.h" #import "Client.h" #import "utility/mempool.h" @@ -36,9 +37,9 @@ extern "C" { #define UIP_CLIENT_CONNECTED 0x10 #define UIP_CLIENT_CLOSE 0x20 -#define UIP_CLIENT_CLOSED 0x40 +#define UIP_CLIENT_REMOTECLOSED 0x40 #define UIP_CLIENT_RESTART 0x80 -#define UIP_CLIENT_STATEFLAGS (UIP_CLIENT_CONNECTED | UIP_CLIENT_CLOSE | UIP_CLIENT_CLOSED | UIP_CLIENT_RESTART) +#define UIP_CLIENT_STATEFLAGS (UIP_CLIENT_CONNECTED | UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED | UIP_CLIENT_RESTART) #define UIP_CLIENT_SOCKETS ~UIP_CLIENT_STATEFLAGS typedef uint8_t uip_socket_ptr; @@ -76,6 +77,8 @@ public: int peek(); void flush(); + using Print::write; + private: UIPClient(struct uip_conn *_conn); UIPClient(uip_userdata_t* conn_data); @@ -84,21 +87,23 @@ private: static uip_userdata_t all_data[UIP_CONNS]; static uip_userdata_t* _allocateData(); - static uip_userdata_t* _getData(struct uip_conn * conn); - + static size_t _write(uip_userdata_t *,const uint8_t *buf, size_t size); static int _available(uip_userdata_t *); - static memhandle * _currentBlock(memhandle* blocks); + static uint8_t _currentBlock(memhandle* blocks); static void _eatBlock(memhandle* blocks); static void _flushBlocks(memhandle* blocks); +#ifdef UIPETHERNET_DEBUG_CLIENT + static void _dumpAllData(); +#endif + friend class UIPEthernetClass; friend class UIPServer; friend void uipclient_appcall(void); - static void uip_callback(); }; #endif diff --git a/libraries/UIPEthernet/UIPEthernet.cpp b/libraries/UIPEthernet/UIPEthernet.cpp index ca59e93..ea02c97 100644 --- a/libraries/UIPEthernet/UIPEthernet.cpp +++ b/libraries/UIPEthernet/UIPEthernet.cpp @@ -25,6 +25,8 @@ #include "HardwareSerial.h" #endif +#include "UIPUdp.h" + extern "C" { #include "utility/uip-conf.h" @@ -35,18 +37,24 @@ extern "C" #define ETH_HDR ((struct uip_eth_hdr *)&uip_buf[0]) +memhandle UIPEthernetClass::in_packet(NOBLOCK); +memhandle UIPEthernetClass::uip_packet(NOBLOCK); +uint8_t UIPEthernetClass::uip_hdrlen(0); +uint8_t UIPEthernetClass::packetstate(0); + +IPAddress UIPEthernetClass::_dnsServerAddress; +DhcpClass* UIPEthernetClass::_dhcp(NULL); + +struct uip_timer UIPEthernetClass::periodic_timer; + // Because uIP isn't encapsulated within a class we have to use global // variables, so we can only have one TCP/IP stack per program. -UIPEthernetClass::UIPEthernetClass() : - in_packet(NOBLOCK), - uip_packet(NOBLOCK), - uip_hdrlen(0), - packetstate(0), - _dhcp(NULL) +UIPEthernetClass::UIPEthernetClass() { } +#if UIP_UDP int UIPEthernetClass::begin(const uint8_t* mac) { @@ -66,6 +74,7 @@ UIPEthernetClass::begin(const uint8_t* mac) } return ret; } +#endif void UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip) @@ -100,6 +109,7 @@ UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddre int UIPEthernetClass::maintain(){ tick(); int rc = DHCP_CHECK_NONE; +#if UIP_UDP if(_dhcp != NULL){ //we have a pointer to dhcp, use it rc = _dhcp->checkLease(); @@ -118,6 +128,7 @@ int UIPEthernetClass::maintain(){ } } return rc; +#endif } IPAddress UIPEthernetClass::localIP() @@ -154,7 +165,7 @@ UIPEthernetClass::tick() { if (in_packet == NOBLOCK) { - in_packet = network.receivePacket(); + in_packet = Enc28J60Network::receivePacket(); #ifdef UIPETHERNET_DEBUG if (in_packet != NOBLOCK) { @@ -166,10 +177,10 @@ UIPEthernetClass::tick() if (in_packet != NOBLOCK) { packetstate = UIPETHERNET_FREEPACKET; - uip_len = network.blockSize(in_packet); + uip_len = Enc28J60Network::blockSize(in_packet); if (uip_len > 0) { - network.readPacket(in_packet,0,(uint8_t*)uip_buf,UIP_BUFSIZE); + Enc28J60Network::readPacket(in_packet,0,(uint8_t*)uip_buf,UIP_BUFSIZE); if (ETH_HDR ->type == HTONS(UIP_ETHTYPE_IP)) { uip_packet = in_packet; @@ -204,7 +215,7 @@ UIPEthernetClass::tick() Serial.print(F("freeing packet: ")); Serial.println(in_packet); #endif - network.freePacket(); + Enc28J60Network::freePacket(); in_packet = NOBLOCK; } } @@ -216,7 +227,7 @@ UIPEthernetClass::tick() { uip_periodic(i); // If the above function invocation resulted in data that - // should be sent out on the network, the global variable + // should be sent out on the Enc28J60Network, the global variable // uip_len is set to a value > 0. if (uip_len > 0) { @@ -230,11 +241,11 @@ UIPEthernetClass::tick() { uip_udp_periodic(i); // If the above function invocation resulted in data that - // should be sent out on the network, the global variable + // should be sent out on the Enc28J60Network, the global variable // uip_len is set to a value > 0. */ if (uip_len > 0) { - network_send(); + UIPUDP::_send((uip_udp_userdata_t *)(uip_udp_conns[i].appstate)); } } #endif /* UIP_UDP */ @@ -246,41 +257,42 @@ boolean UIPEthernetClass::network_send() if (packetstate & UIPETHERNET_SENDPACKET) { #ifdef UIPETHERNET_DEBUG - Serial.print(F("network_send uip_packet: ")); + Serial.print(F("Enc28J60Network_send uip_packet: ")); Serial.print(uip_packet); Serial.print(F(", hdrlen: ")); Serial.println(uip_hdrlen); #endif - network.writePacket(uip_packet,0,uip_buf,uip_hdrlen); + Enc28J60Network::writePacket(uip_packet,0,uip_buf,uip_hdrlen); goto sendandfree; } - uip_packet = network.allocBlock(uip_len); + uip_packet = Enc28J60Network::allocBlock(uip_len); if (uip_packet != NOBLOCK) { #ifdef UIPETHERNET_DEBUG - Serial.print(F("network_send uip_buf (uip_len): ")); + Serial.print(F("Enc28J60Network_send uip_buf (uip_len): ")); Serial.print(uip_len); Serial.print(F(", packet: ")); Serial.println(uip_packet); #endif - network.writePacket(uip_packet,0,uip_buf,uip_len); + Enc28J60Network::writePacket(uip_packet,0,uip_buf,uip_len); goto sendandfree; } return false; sendandfree: - network.sendPacket(uip_packet); - network.freeBlock(uip_packet); + Enc28J60Network::sendPacket(uip_packet); + Enc28J60Network::freeBlock(uip_packet); uip_packet = NOBLOCK; return true; } void UIPEthernetClass::init(const uint8_t* mac) { - uip_timer_set(&this->periodic_timer, CLOCK_SECOND / 4); + uip_timer_set(&periodic_timer, CLOCK_SECOND / 4); - network.init((uint8_t*)mac); + Enc28J60Network::init((uint8_t*)mac); uip_seteth_addr(mac); uip_init(); + uip_arp_init(); } void UIPEthernetClass::configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet) { @@ -345,7 +357,11 @@ UIPEthernetClass::ipchksum(void) /*---------------------------------------------------------------------------*/ uint16_t +#if UIP_UDP UIPEthernetClass::upper_layer_chksum(uint8_t proto) +#else +uip_tcpchksum(void) +#endif { uint16_t upper_layer_len; uint16_t sum; @@ -359,27 +375,34 @@ UIPEthernetClass::upper_layer_chksum(uint8_t proto) /* First sum pseudoheader. */ /* IP protocol and length fields. This addition cannot carry. */ +#if UIP_UDP sum = upper_layer_len + proto; +#else + sum = upper_layer_len + UIP_PROTO_TCP; +#endif /* Sum IP source and destination addresses. */ - sum = chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t)); + sum = UIPEthernetClass::chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t)); uint8_t upper_layer_memlen; +#if UIP_UDP switch(proto) { - case UIP_PROTO_ICMP: - case UIP_PROTO_ICMP6: - upper_layer_memlen = upper_layer_len; - break; - case UIP_PROTO_TCP: - upper_layer_memlen = (BUF->tcpoffset >> 4) << 2; - break; -#if UIP_UDP - case UIP_PROTO_UDP: +// case UIP_PROTO_ICMP: +// case UIP_PROTO_ICMP6: +// upper_layer_memlen = upper_layer_len; +// break; + case UIP_PROTO_UDP: upper_layer_memlen = UIP_UDPH_LEN; break; + default: +// case UIP_PROTO_TCP: #endif + upper_layer_memlen = (BUF->tcpoffset >> 4) << 2; +#if UIP_UDP + break; } - sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], upper_layer_memlen); +#endif + sum = UIPEthernetClass::chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], upper_layer_memlen); #ifdef UIPETHERNET_DEBUG_CHKSUM Serial.print(F("chksum uip_buf[")); Serial.print(UIP_IPH_LEN + UIP_LLH_LEN); @@ -390,9 +413,9 @@ UIPEthernetClass::upper_layer_chksum(uint8_t proto) #endif if (upper_layer_memlen < upper_layer_len) { - sum = network.chksum( + sum = Enc28J60Network::chksum( sum, - uip_packet, + UIPEthernetClass::uip_packet, UIP_IPH_LEN + UIP_LLH_LEN + upper_layer_memlen, upper_layer_len - upper_layer_memlen ); @@ -403,7 +426,7 @@ UIPEthernetClass::upper_layer_chksum(uint8_t proto) Serial.print(UIP_IPH_LEN + UIP_LLH_LEN + upper_layer_memlen); Serial.print(F("-")); Serial.print(UIP_IPH_LEN + UIP_LLH_LEN + upper_layer_len); - Serial.print(F"]: ")); + Serial.print(F("]: ")); Serial.println(htons(sum),HEX); #endif } @@ -416,6 +439,7 @@ uip_ipchksum(void) return UIPEthernet.ipchksum(); } +#if UIP_UDP uint16_t uip_tcpchksum(void) { @@ -423,7 +447,6 @@ uip_tcpchksum(void) return sum; } -#if UIP_UDP uint16_t uip_udpchksum(void) { diff --git a/libraries/UIPEthernet/UIPEthernet.h b/libraries/UIPEthernet/UIPEthernet.h index 94502f1..3bb18d4 100644 --- a/libraries/UIPEthernet/UIPEthernet.h +++ b/libraries/UIPEthernet/UIPEthernet.h @@ -20,6 +20,11 @@ #ifndef UIPETHERNET_H #define UIPETHERNET_H +//#define UIPETHERNET_DEBUG +//#define UIPETHERNET_DEBUG_CHKSUM +//#define UIPETHERNET_DEBUG_UDP +//#define UIPETHERNET_DEBUG_CLIENT + #include "ethernet_comp.h" #include #include "Dhcp.h" @@ -35,11 +40,6 @@ extern "C" #include "utility/uip.h" } -//#define UIPETHERNET_DEBUG -//#define UIPETHERNET_DEBUG_CHKSUM -//#define UIPETHERNET_DEBUG_UDP -//#define UIPETHERNET_DEBUG_CLIENT - #define UIPETHERNET_FREEPACKET 1 #define UIPETHERNET_SENDPACKET 2 #define UIPETHERNET_BUFFERREAD 4 @@ -82,24 +82,22 @@ public: IPAddress dnsServerIP(); private: - IPAddress _dnsServerAddress; - DhcpClass* _dhcp; + static memhandle in_packet; + static memhandle uip_packet; + static uint8_t uip_hdrlen; + static uint8_t packetstate; + + static IPAddress _dnsServerAddress; + static DhcpClass* _dhcp; - struct uip_timer periodic_timer; + static struct uip_timer periodic_timer; - memhandle in_packet; - memhandle uip_packet; - uint8_t uip_hdrlen; - uint8_t packetstate; + static void init(const uint8_t* mac); + static void configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet); - Enc28J60Network network; + static void tick(); - void init(const uint8_t* mac); - void configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet); - - void tick(); - - boolean network_send(); + static boolean network_send(); friend class UIPServer; @@ -109,12 +107,16 @@ private: static uint16_t chksum(uint16_t sum, const uint8_t* data, uint16_t len); static uint16_t ipchksum(void); - uint16_t upper_layer_chksum(uint8_t proto); - +#if UIP_UDP + static uint16_t upper_layer_chksum(uint8_t proto); +#endif friend uint16_t uip_ipchksum(void); friend uint16_t uip_tcpchksum(void); friend uint16_t uip_udpchksum(void); + friend void uipclient_appcall(void); + friend void uipudp_appcall(void); + #if UIP_CONF_IPV6 uint16_t uip_icmp6chksum(void); #endif /* UIP_CONF_IPV6 */ diff --git a/libraries/UIPEthernet/UIPServer.cpp b/libraries/UIPEthernet/UIPServer.cpp index 12ff72f..21c7ef5 100644 --- a/libraries/UIPEthernet/UIPServer.cpp +++ b/libraries/UIPEthernet/UIPServer.cpp @@ -28,12 +28,12 @@ UIPServer::UIPServer(uint16_t port) : _port(htons(port)) UIPClient UIPServer::available() { - UIPEthernet.tick(); + UIPEthernetClass::tick(); for ( uip_userdata_t* data = &UIPClient::all_data[0]; data < &UIPClient::all_data[UIP_CONNS]; data++ ) { if (data->packets_in[0] != NOBLOCK && (((data->state & UIP_CLIENT_CONNECTED) && uip_conns[data->state & UIP_CLIENT_SOCKETS].lport ==_port) - || ((data->state & UIP_CLIENT_CLOSED) && ((uip_userdata_closed_t *)data)->lport == _port))) + || ((data->state & UIP_CLIENT_REMOTECLOSED) && ((uip_userdata_closed_t *)data)->lport == _port))) return UIPClient(data); } return UIPClient(); @@ -42,7 +42,7 @@ UIPClient UIPServer::available() void UIPServer::begin() { uip_listen(_port); - UIPEthernet.tick(); + UIPEthernetClass::tick(); } size_t UIPServer::write(uint8_t c) diff --git a/libraries/UIPEthernet/UIPServer.h b/libraries/UIPEthernet/UIPServer.h index 64bdade..0cc0619 100644 --- a/libraries/UIPEthernet/UIPServer.h +++ b/libraries/UIPEthernet/UIPServer.h @@ -23,7 +23,7 @@ #import "Server.h" #import "UIPClient.h" -class UIPServer : Server { +class UIPServer : public Server { public: UIPServer(uint16_t); diff --git a/libraries/UIPEthernet/UIPUdp.cpp b/libraries/UIPEthernet/UIPUdp.cpp index d1cb7b1..3deb2c4 100644 --- a/libraries/UIPEthernet/UIPUdp.cpp +++ b/libraries/UIPEthernet/UIPUdp.cpp @@ -65,28 +65,13 @@ UIPUDP::stop() { if (_uip_udp_conn) { - flush(); uip_udp_remove(_uip_udp_conn); _uip_udp_conn->appstate = NULL; _uip_udp_conn=NULL; - if (appdata.packet_in != NOBLOCK) - { - UIPEthernet.network.freeBlock(appdata.packet_in); - appdata.packet_in = NOBLOCK; - } - uint8_t i = 0; - memhandle* packet = &appdata.packets_in[0]; - while (*packet != NOBLOCK && i < UIP_UDP_NUMPACKETS) - { - UIPEthernet.network.freeBlock(*packet); - *packet++ = NOBLOCK; - i++; - } - if (appdata.packet_out != NOBLOCK) - { - UIPEthernet.network.freeBlock(appdata.packet_out); - appdata.packet_out = NOBLOCK; - } + Enc28J60Network::freeBlock(appdata.packet_in); + Enc28J60Network::freeBlock(appdata.packet_next); + Enc28J60Network::freeBlock(appdata.packet_out); + memset(&appdata,0,sizeof(appdata)); } } @@ -97,7 +82,7 @@ UIPUDP::stop() int UIPUDP::beginPacket(IPAddress ip, uint16_t port) { - UIPEthernet.tick(); + UIPEthernetClass::tick(); if (ip && port) { uip_ipaddr_t ripaddr; @@ -139,7 +124,7 @@ UIPUDP::beginPacket(IPAddress ip, uint16_t port) { if (appdata.packet_out == NOBLOCK) { - appdata.packet_out = UIPEthernet.network.allocBlock(UIP_UDP_MAXPACKETSIZE); + appdata.packet_out = Enc28J60Network::allocBlock(UIP_UDP_MAXPACKETSIZE); appdata.out_pos = UIP_UDP_PHYH_LEN; if (appdata.packet_out != NOBLOCK) return 1; @@ -183,11 +168,11 @@ UIPUDP::endPacket() if (_uip_udp_conn && appdata.packet_out != NOBLOCK) { appdata.send = true; - UIPEthernet.network.resizeBlock(appdata.packet_out,0,appdata.out_pos); + Enc28J60Network::resizeBlock(appdata.packet_out,0,appdata.out_pos); uip_udp_periodic_conn(_uip_udp_conn); if (uip_len > 0) { - UIPEthernet.network_send(); + _send(&appdata); return 1; } } @@ -207,7 +192,7 @@ UIPUDP::write(const uint8_t *buffer, size_t size) { if (appdata.packet_out != NOBLOCK) { - size_t ret = UIPEthernet.network.writePacket(appdata.packet_out,appdata.out_pos,(uint8_t*)buffer,size); + size_t ret = Enc28J60Network::writePacket(appdata.packet_out,appdata.out_pos,(uint8_t*)buffer,size); appdata.out_pos += ret; return ret; } @@ -219,61 +204,43 @@ UIPUDP::write(const uint8_t *buffer, size_t size) int UIPUDP::parsePacket() { - UIPEthernet.tick(); + UIPEthernetClass::tick(); +#ifdef UIPETHERNET_DEBUG_UDP if (appdata.packet_in != NOBLOCK) { -#ifdef UIPETHERNET_DEBUG_UDP Serial.print(F("udp parsePacket freeing previous packet: ")); Serial.println(appdata.packet_in); -#endif; - UIPEthernet.network.freeBlock(appdata.packet_in); } - memhandle *packet = &appdata.packets_in[0]; - appdata.packet_in = *packet; +#endif + Enc28J60Network::freeBlock(appdata.packet_in); + + appdata.packet_in = appdata.packet_next; + appdata.packet_next = NOBLOCK; + +#ifdef UIPETHERNET_DEBUG_UDP if (appdata.packet_in != NOBLOCK) { -#ifdef UIPETHERNET_DEBUG_UDP Serial.print(F("udp parsePacket received packet: ")); Serial.print(appdata.packet_in); + } #endif - if (UIP_UDP_NUMPACKETS > 1) - { - uint8_t i = 1; - memhandle* p = packet+1; -freeloop: - *packet = *p; - if (*packet == NOBLOCK) - goto freeready; - packet++; - if (i < UIP_UDP_NUMPACKETS-1) - { - i++; - p++; - goto freeloop; - } - } - *packet = NOBLOCK; -freeready: - int size = UIPEthernet.network.blockSize(appdata.packet_in); + int size = Enc28J60Network::blockSize(appdata.packet_in); #ifdef UIPETHERNET_DEBUG_UDP + if (appdata.packet_in != NOBLOCK) + { Serial.print(F(", size: ")); Serial.println(size); -#endif - return size; } - return 0; +#endif + return size; } // Number of bytes remaining in the current packet int UIPUDP::available() { - UIPEthernet.tick(); - if (appdata.packet_in != NOBLOCK) - { - return UIPEthernet.network.blockSize(appdata.packet_in); - } - return 0; + UIPEthernetClass::tick(); + return Enc28J60Network::blockSize(appdata.packet_in); } // Read a single byte from the current packet @@ -293,11 +260,17 @@ UIPUDP::read() int UIPUDP::read(unsigned char* buffer, size_t len) { - UIPEthernet.tick(); + UIPEthernetClass::tick(); if (appdata.packet_in != NOBLOCK) { - int read = UIPEthernet.network.readPacket(appdata.packet_in,0,buffer,len); - UIPEthernet.network.resizeBlock(appdata.packet_in,read); + memaddress read = Enc28J60Network::readPacket(appdata.packet_in,0,buffer,len); + if (read == Enc28J60Network::blockSize(appdata.packet_in)) + { + Enc28J60Network::freeBlock(appdata.packet_in); + appdata.packet_in = NOBLOCK; + } + else + Enc28J60Network::resizeBlock(appdata.packet_in,read); return read; } return 0; @@ -307,11 +280,11 @@ UIPUDP::read(unsigned char* buffer, size_t len) int UIPUDP::peek() { - UIPEthernet.tick(); + UIPEthernetClass::tick(); if (appdata.packet_in != NOBLOCK) { unsigned char c; - if (UIPEthernet.network.readPacket(appdata.packet_in,0,&c,1) == 1) + if (Enc28J60Network::readPacket(appdata.packet_in,0,&c,1) == 1) return c; } return -1; @@ -321,12 +294,9 @@ UIPUDP::peek() void UIPUDP::flush() { - UIPEthernet.tick(); - if (appdata.packet_in != NOBLOCK) - { - UIPEthernet.network.freeBlock(appdata.packet_in); - appdata.packet_in = NOBLOCK; - } + UIPEthernetClass::tick(); + Enc28J60Network::freeBlock(appdata.packet_in); + appdata.packet_in = NOBLOCK; } // Return the IP address of the host who sent the current incoming packet @@ -347,44 +317,28 @@ UIPUDP::remotePort() void uipudp_appcall(void) { - UIPUDP::uip_callback(); -} - -void -UIPUDP::uip_callback() { - if (appdata_t *data = (appdata_t *)(uip_udp_conn->appstate)) + if (uip_udp_userdata_t *data = (uip_udp_userdata_t *)(uip_udp_conn->appstate)) { if (uip_newdata()) { - uip_udp_conn->rport = UDPBUF->srcport; - uip_ipaddr_copy(uip_udp_conn->ripaddr,UDPBUF->srcipaddr); - memhandle *packet = &data->packets_in[0]; - uint8_t i = 0; - do + if (data->packet_next == NOBLOCK) { - if (*packet == NOBLOCK) - { - *packet = UIPEthernet.network.allocBlock(ntohs(UDPBUF->udplen)-UIP_UDPH_LEN); + uip_udp_conn->rport = UDPBUF->srcport; + uip_ipaddr_copy(uip_udp_conn->ripaddr,UDPBUF->srcipaddr); + data->packet_next = Enc28J60Network::allocBlock(ntohs(UDPBUF->udplen)-UIP_UDPH_LEN); //if we are unable to allocate memory the packet is dropped. udp doesn't guarantee packet delivery - if (*packet != NOBLOCK) - { - //discard Linklevel and IP and udp-header and any trailing bytes: - UIPEthernet.network.copyPacket(*packet,0,UIPEthernet.in_packet,UIP_UDP_PHYH_LEN,UIPEthernet.network.blockSize(*packet)); + if (data->packet_next != NOBLOCK) + { + //discard Linklevel and IP and udp-header and any trailing bytes: + Enc28J60Network::copyPacket(data->packet_next,0,UIPEthernetClass::in_packet,UIP_UDP_PHYH_LEN,Enc28J60Network::blockSize(data->packet_next)); #ifdef UIPETHERNET_DEBUG_UDP - Serial.print(F("udp, uip_newdata received packet: ")); - Serial.print(*packet); - Serial.print(F(", slot: ")); - Serial.print(i); - Serial.print(F(", size: ")); - Serial.println(UIPEthernet.network.blockSize(*packet)); + Serial.print(F("udp, uip_newdata received packet: ")); + Serial.print(data->packet_next); + Serial.print(F(", size: ")); + Serial.println(Enc28J60Network::blockSize(data->packet_next)); #endif - break; - } } - packet++; - i++; } - while (i < UIP_UDP_NUMPACKETS); } if (uip_poll() && data->send) { @@ -393,32 +347,37 @@ UIPUDP::uip_callback() { Serial.print(F("udp, uip_poll preparing packet to send: ")); Serial.print(data->packet_out); Serial.print(F(", size: ")); - Serial.println(UIPEthernet.network.blockSize(data->packet_out)); + Serial.println(Enc28J60Network::blockSize(data->packet_out)); #endif - UIPEthernet.uip_packet = data->packet_out; - data->packet_out = NOBLOCK; - UIPEthernet.uip_hdrlen = UIP_UDP_PHYH_LEN; - UIPEthernet.packetstate |= UIPETHERNET_SENDPACKET; + UIPEthernetClass::uip_packet = data->packet_out; + UIPEthernetClass::uip_hdrlen = UIP_UDP_PHYH_LEN; uip_udp_send(data->out_pos - (UIP_UDP_PHYH_LEN)); - uip_process(UIP_UDP_SEND_CONN); //generate udp + ip headers - uip_arp_out(); //add arp - if (uip_len == UIP_ARPHDRSIZE) - { - UIPEthernet.packetstate &= ~UIPETHERNET_SENDPACKET; -#ifdef UIPETHERNET_DEBUG_UDP - Serial.println(F("udp, uip_poll results in ARP-packet")); -#endif - } - else - //arp found ethaddr for ip (otherwise packet is replaced by arp-request) - { - data->send = false; -#ifdef UIPETHERNET_DEBUG_UDP - Serial.print(F("udp, uip_packet to send: ")); - Serial.println(UIPEthernet.uip_packet); -#endif - } } } } + +void +UIPUDP::_send(uip_udp_userdata_t *data) { + uip_arp_out(); //add arp + if (uip_len == UIP_ARPHDRSIZE) + { + UIPEthernetClass::uip_packet = NOBLOCK; + UIPEthernetClass::packetstate &= ~UIPETHERNET_SENDPACKET; +#ifdef UIPETHERNET_DEBUG_UDP + Serial.println(F("udp, uip_poll results in ARP-packet")); +#endif + } + else + //arp found ethaddr for ip (otherwise packet is replaced by arp-request) + { + data->send = false; + data->packet_out = NOBLOCK; + UIPEthernetClass::packetstate |= UIPETHERNET_SENDPACKET; +#ifdef UIPETHERNET_DEBUG_UDP + Serial.print(F("udp, uip_packet to send: ")); + Serial.println(UIPEthernetClass::uip_packet); +#endif + } + UIPEthernetClass::network_send(); +} #endif diff --git a/libraries/UIPEthernet/UIPUdp.h b/libraries/UIPEthernet/UIPUdp.h index c965ffa..b007a3c 100644 --- a/libraries/UIPEthernet/UIPUdp.h +++ b/libraries/UIPEthernet/UIPUdp.h @@ -25,15 +25,20 @@ #include #include "utility/mempool.h" extern "C" { - #include "utility/uip.h"; + #include "utility/uip.h" } #define UIP_UDP_MAXDATALEN 1500 #define UIP_UDP_PHYH_LEN UIP_LLH_LEN+UIP_IPUDPH_LEN #define UIP_UDP_MAXPACKETSIZE UIP_UDP_MAXDATALEN+UIP_UDP_PHYH_LEN -#ifndef UIP_UDP_NUMPACKETS -#define UIP_UDP_NUMPACKETS 5 -#endif + +typedef struct { + memaddress out_pos; + memhandle packet_next; + memhandle packet_in; + memhandle packet_out; + boolean send; +} uip_udp_userdata_t; class UIPUDP : public UDP { @@ -41,14 +46,7 @@ class UIPUDP : public UDP private: struct uip_udp_conn *_uip_udp_conn; - struct appdata_t - { - memaddress out_pos; - memhandle packets_in[UIP_UDP_NUMPACKETS]; - memhandle packet_in; - memhandle packet_out; - boolean send; - } appdata; + uip_udp_userdata_t appdata; public: UIPUDP(); // Constructor @@ -120,7 +118,9 @@ private: friend void uipudp_appcall(void); - static void uip_callback(); + friend class UIPEthernetClass; + static void _send(uip_udp_userdata_t *data); + }; #endif diff --git a/libraries/UIPEthernet/ethernet_comp.h b/libraries/UIPEthernet/ethernet_comp.h index 97a1ad7..4cec2ab 100644 --- a/libraries/UIPEthernet/ethernet_comp.h +++ b/libraries/UIPEthernet/ethernet_comp.h @@ -4,6 +4,6 @@ #define Ethernet UIPEthernet #define EthernetClient UIPClient #define EthernetServer UIPServer -//#define EthernetUDP UIPUDP +#define EthernetUDP UIPUDP #endif diff --git a/libraries/UIPEthernet/src/Dhcp.cpp b/libraries/UIPEthernet/src/Dhcp.cpp deleted file mode 100644 index d34e8e2..0000000 --- a/libraries/UIPEthernet/src/Dhcp.cpp +++ /dev/null @@ -1,478 +0,0 @@ -// DHCP Library v0.3 - April 25, 2009 -// Author: Jordan Terrell - blog.jordanterrell.com - -#include -#include -#include "Dhcp.h" -#include "Arduino.h" -#include "utility/util.h" - -int DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout) -{ - _dhcpLeaseTime=0; - _dhcpT1=0; - _dhcpT2=0; - _lastCheck=0; - _timeout = timeout; - _responseTimeout = responseTimeout; - - // zero out _dhcpMacAddr - memset(_dhcpMacAddr, 0, 6); - reset_DHCP_lease(); - - memcpy((void*)_dhcpMacAddr, (void*)mac, 6); - _dhcp_state = STATE_DHCP_START; - return request_DHCP_lease(); -} - -void DhcpClass::reset_DHCP_lease(){ - // zero out _dhcpSubnetMask, _dhcpGatewayIp, _dhcpLocalIp, _dhcpDhcpServerIp, _dhcpDnsServerIp - memset(_dhcpLocalIp, 0, 20); -} - -//return:0 on error, 1 if request is sent and response is received -int DhcpClass::request_DHCP_lease(){ - - uint8_t messageType = 0; - - - - // Pick an initial transaction ID - _dhcpTransactionId = random(1UL, 2000UL); - _dhcpInitialTransactionId = _dhcpTransactionId; - - _dhcpUdpSocket.stop(); - 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_REREQUEST){ - _dhcpTransactionId++; - send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime)/1000)); - _dhcp_state = STATE_DHCP_REQUEST; - } - 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; - //use default lease time if we didn't get it - if(_dhcpLeaseTime == 0){ - _dhcpLeaseTime = DEFAULT_LEASE; - } - //calculate T1 & T2 if we didn't get it - if(_dhcpT1 == 0){ - //T1 should be 50% of _dhcpLeaseTime - _dhcpT1 = _dhcpLeaseTime >> 1; - } - if(_dhcpT2 == 0){ - //T2 should be 87.5% (7/8ths) of _dhcpLeaseTime - _dhcpT2 = _dhcpT1 << 1; - } - _renewInSec = _dhcpT1; - _rebindInSec = _dhcpT2; - } - 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) + 6; // length of hostname + last 3 bytes of mac address - strcpy((char*)&(buffer[18]), HOST_NAME); - - printByte((char*)&(buffer[24]), _dhcpMacAddr[3]); - printByte((char*)&(buffer[26]), _dhcpMacAddr[4]); - printByte((char*)&(buffer[28]), _dhcpMacAddr[5]); - - //put data in W5100 transmit buffer - _dhcpUdpSocket.write(buffer, 30); - - 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 - (int)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); - for (int i = 0; i < opt_len-4; i++) - { - _dhcpUdpSocket.read(); - } - break; - - case dns : - opt_len = _dhcpUdpSocket.read(); - _dhcpUdpSocket.read(_dhcpDnsServerIp, 4); - for (int i = 0; i < opt_len-4; i++) - { - _dhcpUdpSocket.read(); - } - 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 dhcpT1value : - opt_len = _dhcpUdpSocket.read(); - _dhcpUdpSocket.read((uint8_t*)&_dhcpT1, sizeof(_dhcpT1)); - _dhcpT1 = ntohl(_dhcpT1); - break; - - case dhcpT2value : - opt_len = _dhcpUdpSocket.read(); - _dhcpUdpSocket.read((uint8_t*)&_dhcpT2, sizeof(_dhcpT2)); - _dhcpT2 = ntohl(_dhcpT2); - break; - - case dhcpIPaddrLeaseTime : - opt_len = _dhcpUdpSocket.read(); - _dhcpUdpSocket.read((uint8_t*)&_dhcpLeaseTime, sizeof(_dhcpLeaseTime)); - _dhcpLeaseTime = ntohl(_dhcpLeaseTime); - _renewInSec = _dhcpLeaseTime; - break; - - 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; -} - - -/* - returns: - 0/DHCP_CHECK_NONE: nothing happened - 1/DHCP_CHECK_RENEW_FAIL: renew failed - 2/DHCP_CHECK_RENEW_OK: renew success - 3/DHCP_CHECK_REBIND_FAIL: rebind fail - 4/DHCP_CHECK_REBIND_OK: rebind success -*/ -int DhcpClass::checkLease(){ - //this uses a signed / unsigned trick to deal with millis overflow - unsigned long now = millis(); - signed long snow = (long)now; - int rc=DHCP_CHECK_NONE; - if (_lastCheck != 0){ - signed long factor; - //calc how many ms past the timeout we are - factor = snow - (long)_secTimeout; - //if on or passed the timeout, reduce the counters - if ( factor >= 0 ){ - //next timeout should be now plus 1000 ms minus parts of second in factor - _secTimeout = snow + 1000 - factor % 1000; - //how many seconds late are we, minimum 1 - factor = factor / 1000 +1; - - //reduce the counters by that mouch - //if we can assume that the cycle time (factor) is fairly constant - //and if the remainder is less than cycle time * 2 - //do it early instead of late - if(_renewInSec < factor*2 ) - _renewInSec = 0; - else - _renewInSec -= factor; - - if(_rebindInSec < factor*2 ) - _rebindInSec = 0; - else - _rebindInSec -= factor; - } - - //if we have a lease but should renew, do it - if (_dhcp_state == STATE_DHCP_LEASED && _renewInSec <=0){ - _dhcp_state = STATE_DHCP_REREQUEST; - rc = 1 + request_DHCP_lease(); - } - - //if we have a lease or is renewing but should bind, do it - if( (_dhcp_state == STATE_DHCP_LEASED || _dhcp_state == STATE_DHCP_START) && _rebindInSec <=0){ - //this should basically restart completely - _dhcp_state = STATE_DHCP_START; - reset_DHCP_lease(); - rc = 3 + request_DHCP_lease(); - } - } - else{ - _secTimeout = snow + 1000; - } - - _lastCheck = now; - return rc; -} - -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); -} - -void DhcpClass::printByte(char * buf, uint8_t n ) { - char *str = &buf[1]; - buf[0]='0'; - do { - unsigned long m = n; - n /= 16; - char c = m - 16 * n; - *str-- = c < 10 ? c + '0' : c + 'A' - 10; - } while(n); -} diff --git a/libraries/UIPEthernet/src/Dhcp.h b/libraries/UIPEthernet/src/Dhcp.h deleted file mode 100644 index 01405d7..0000000 --- a/libraries/UIPEthernet/src/Dhcp.h +++ /dev/null @@ -1,178 +0,0 @@ -// DHCP Library v0.3 - April 25, 2009 -// Author: Jordan Terrell - blog.jordanterrell.com - -#ifndef Dhcp_h -#define Dhcp_h - -#include "UIPUdp.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 "ENC28J" -#define DEFAULT_LEASE (900) //default lease time in seconds - -#define DHCP_CHECK_NONE (0) -#define DHCP_CHECK_RENEW_FAIL (1) -#define DHCP_CHECK_RENEW_OK (2) -#define DHCP_CHECK_REBIND_FAIL (3) -#define DHCP_CHECK_REBIND_OK (4) - -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]; - uint32_t _dhcpLeaseTime; - uint32_t _dhcpT1, _dhcpT2; - signed long _renewInSec; - signed long _rebindInSec; - signed long _lastCheck; - unsigned long _timeout; - unsigned long _responseTimeout; - unsigned long _secTimeout; - uint8_t _dhcp_state; - UIPUDP _dhcpUdpSocket; - - int request_DHCP_lease(); - void reset_DHCP_lease(); - void presend_DHCP(); - void send_DHCP_MESSAGE(uint8_t, uint16_t); - void printByte(char *, uint8_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); - int checkLease(); -}; - -#endif diff --git a/libraries/UIPEthernet/src/Dns.cpp b/libraries/UIPEthernet/src/Dns.cpp deleted file mode 100644 index 2b97fb7..0000000 --- a/libraries/UIPEthernet/src/Dns.cpp +++ /dev/null @@ -1,422 +0,0 @@ -// Arduino DNS client for Enc28J60-based Ethernet shield -// (c) Copyright 2009-2010 MCQN Ltd. -// Released under Apache License, version 2.0 - -#include "Udp.h" -#include "utility/util.h" - -#include "Dns.h" -#include -//#include -#include "Arduino.h" - - -#define SOCKET_NONE 255 -// Various flags and header field values for a DNS message -#define UDP_HEADER_SIZE 8 -#define DNS_HEADER_SIZE 12 -#define TTL_SIZE 4 -#define QUERY_FLAG (0) -#define RESPONSE_FLAG (1<<15) -#define QUERY_RESPONSE_MASK (1<<15) -#define OPCODE_STANDARD_QUERY (0) -#define OPCODE_INVERSE_QUERY (1<<11) -#define OPCODE_STATUS_REQUEST (2<<11) -#define OPCODE_MASK (15<<11) -#define AUTHORITATIVE_FLAG (1<<10) -#define TRUNCATION_FLAG (1<<9) -#define RECURSION_DESIRED_FLAG (1<<8) -#define RECURSION_AVAILABLE_FLAG (1<<7) -#define RESP_NO_ERROR (0) -#define RESP_FORMAT_ERROR (1) -#define RESP_SERVER_FAILURE (2) -#define RESP_NAME_ERROR (3) -#define RESP_NOT_IMPLEMENTED (4) -#define RESP_REFUSED (5) -#define RESP_MASK (15) -#define TYPE_A (0x0001) -#define CLASS_IN (0x0001) -#define LABEL_COMPRESSION_MASK (0xC0) -// Port number that DNS servers listen on -#define DNS_PORT 53 - -// Possible return codes from ProcessResponse -#define SUCCESS 1 -#define TIMED_OUT -1 -#define INVALID_SERVER -2 -#define TRUNCATED -3 -#define INVALID_RESPONSE -4 - -void DNSClient::begin(const IPAddress& aDNSServer) -{ - iDNSServer = aDNSServer; - iRequestId = 0; -} - - -int DNSClient::inet_aton(const char* aIPAddrString, IPAddress& aResult) -{ - // See if we've been given a valid IP address - const char* p =aIPAddrString; - while (*p && - ( (*p == '.') || (*p >= '0') || (*p <= '9') )) - { - p++; - } - - if (*p == '\0') - { - // It's looking promising, we haven't found any invalid characters - p = aIPAddrString; - int segment =0; - int segmentValue =0; - while (*p && (segment < 4)) - { - if (*p == '.') - { - // We've reached the end of a segment - if (segmentValue > 255) - { - // You can't have IP address segments that don't fit in a byte - return 0; - } - else - { - aResult[segment] = (byte)segmentValue; - segment++; - segmentValue = 0; - } - } - else - { - // Next digit - segmentValue = (segmentValue*10)+(*p - '0'); - } - p++; - } - // We've reached the end of address, but there'll still be the last - // segment to deal with - if ((segmentValue > 255) || (segment > 3)) - { - // You can't have IP address segments that don't fit in a byte, - // or more than four segments - return 0; - } - else - { - aResult[segment] = (byte)segmentValue; - return 1; - } - } - else - { - return 0; - } -} - -int DNSClient::getHostByName(const char* aHostname, IPAddress& aResult) -{ - int ret =0; - - // See if it's a numeric IP address - if (inet_aton(aHostname, aResult)) - { - // It is, our work here is done - return 1; - } - - // Check we've got a valid DNS server to use - if (iDNSServer == INADDR_NONE) - { - return INVALID_SERVER; - } - - // Find a socket to use - if (iUdp.begin(1024+(millis() & 0xF)) == 1) - { - // Try up to three times - int retries = 0; -// while ((retries < 3) && (ret <= 0)) - { - // Send DNS request - ret = iUdp.beginPacket(iDNSServer, DNS_PORT); - if (ret != 0) - { - // Now output the request data - ret = BuildRequest(aHostname); - if (ret != 0) - { - // And finally send the request - ret = iUdp.endPacket(); - if (ret != 0) - { - // Now wait for a response - int wait_retries = 0; - ret = TIMED_OUT; - while ((wait_retries < 3) && (ret == TIMED_OUT)) - { - ret = ProcessResponse(5000, aResult); - wait_retries++; - } - } - } - } - retries++; - } - - // We're done with the socket now - iUdp.stop(); - } - - return ret; -} - -uint16_t DNSClient::BuildRequest(const char* aName) -{ - // Build header - // 1 1 1 1 1 1 - // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 - // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - // | ID | - // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - // |QR| Opcode |AA|TC|RD|RA| Z | RCODE | - // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - // | QDCOUNT | - // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - // | ANCOUNT | - // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - // | NSCOUNT | - // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - // | ARCOUNT | - // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - // As we only support one request at a time at present, we can simplify - // some of this header - iRequestId = millis(); // generate a random ID - uint16_t twoByteBuffer; - - // FIXME We should also check that there's enough space available to write to, rather - // FIXME than assume there's enough space (as the code does at present) - iUdp.write((uint8_t*)&iRequestId, sizeof(iRequestId)); - - twoByteBuffer = htons(QUERY_FLAG | OPCODE_STANDARD_QUERY | RECURSION_DESIRED_FLAG); - iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer)); - - twoByteBuffer = htons(1); // One question record - iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer)); - - twoByteBuffer = 0; // Zero answer records - iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer)); - - iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer)); - // and zero additional records - iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer)); - - // Build question - const char* start =aName; - const char* end =start; - uint8_t len; - // Run through the name being requested - while (*end) - { - // Find out how long this section of the name is - end = start; - while (*end && (*end != '.') ) - { - end++; - } - - if (end-start > 0) - { - // Write out the size of this section - len = end-start; - iUdp.write(&len, sizeof(len)); - // And then write out the section - iUdp.write((uint8_t*)start, end-start); - } - start = end+1; - } - - // We've got to the end of the question name, so - // terminate it with a zero-length section - len = 0; - iUdp.write(&len, sizeof(len)); - // Finally the type and class of question - twoByteBuffer = htons(TYPE_A); - iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer)); - - twoByteBuffer = htons(CLASS_IN); // Internet class of question - iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer)); - // Success! Everything buffered okay - return 1; -} - - -uint16_t DNSClient::ProcessResponse(uint16_t aTimeout, IPAddress& aAddress) -{ - uint32_t startTime = millis(); - - // Wait for a response packet - while(iUdp.parsePacket() <= 0) - { - if((millis() - startTime) > aTimeout) - return TIMED_OUT; - delay(50); - } - - // We've had a reply! - // Read the UDP header - uint8_t header[DNS_HEADER_SIZE]; // Enough space to reuse for the DNS header - // Check that it's a response from the right server and the right port - if ( (iDNSServer != iUdp.remoteIP()) || - (iUdp.remotePort() != DNS_PORT) ) - { - // It's not from who we expected - return INVALID_SERVER; - } - - // Read through the rest of the response - if (iUdp.available() < DNS_HEADER_SIZE) - { - return TRUNCATED; - } - iUdp.read(header, DNS_HEADER_SIZE); - - uint16_t header_flags = htons(*((uint16_t*)&header[2])); - // Check that it's a response to this request - if ( ( iRequestId != (*((uint16_t*)&header[0])) ) || - ((header_flags & QUERY_RESPONSE_MASK) != (uint16_t)RESPONSE_FLAG) ) - { - // Mark the entire packet as read - iUdp.flush(); - return INVALID_RESPONSE; - } - // Check for any errors in the response (or in our request) - // although we don't do anything to get round these - if ( (header_flags & TRUNCATION_FLAG) || (header_flags & RESP_MASK) ) - { - // Mark the entire packet as read - iUdp.flush(); - return -5; //INVALID_RESPONSE; - } - - // And make sure we've got (at least) one answer - uint16_t answerCount = htons(*((uint16_t*)&header[6])); - if (answerCount == 0 ) - { - // Mark the entire packet as read - iUdp.flush(); - return -6; //INVALID_RESPONSE; - } - - // Skip over any questions - for (uint16_t i =0; i < htons(*((uint16_t*)&header[4])); i++) - { - // Skip over the name - uint8_t len; - do - { - iUdp.read(&len, sizeof(len)); - if (len > 0) - { - // Don't need to actually read the data out for the string, just - // advance ptr to beyond it - while(len--) - { - iUdp.read(); // we don't care about the returned byte - } - } - } while (len != 0); - - // Now jump over the type and class - for (int i =0; i < 4; i++) - { - iUdp.read(); // we don't care about the returned byte - } - } - - // Now we're up to the bit we're interested in, the answer - // There might be more than one answer (although we'll just use the first - // type A answer) and some authority and additional resource records but - // we're going to ignore all of them. - - for (uint16_t i =0; i < answerCount; i++) - { - // Skip the name - uint8_t len; - do - { - iUdp.read(&len, sizeof(len)); - if ((len & LABEL_COMPRESSION_MASK) == 0) - { - // It's just a normal label - if (len > 0) - { - // And it's got a length - // Don't need to actually read the data out for the string, - // just advance ptr to beyond it - while(len--) - { - iUdp.read(); // we don't care about the returned byte - } - } - } - else - { - // This is a pointer to a somewhere else in the message for the - // rest of the name. We don't care about the name, and RFC1035 - // says that a name is either a sequence of labels ended with a - // 0 length octet or a pointer or a sequence of labels ending in - // a pointer. Either way, when we get here we're at the end of - // the name - // Skip over the pointer - iUdp.read(); // we don't care about the returned byte - // And set len so that we drop out of the name loop - len = 0; - } - } while (len != 0); - - // Check the type and class - uint16_t answerType; - uint16_t answerClass; - iUdp.read((uint8_t*)&answerType, sizeof(answerType)); - iUdp.read((uint8_t*)&answerClass, sizeof(answerClass)); - - // Ignore the Time-To-Live as we don't do any caching - for (int i =0; i < TTL_SIZE; i++) - { - iUdp.read(); // we don't care about the returned byte - } - - // And read out the length of this answer - // Don't need header_flags anymore, so we can reuse it here - iUdp.read((uint8_t*)&header_flags, sizeof(header_flags)); - - if ( (htons(answerType) == TYPE_A) && (htons(answerClass) == CLASS_IN) ) - { - if (htons(header_flags) != 4) - { - // It's a weird size - // Mark the entire packet as read - iUdp.flush(); - return -9;//INVALID_RESPONSE; - } - iUdp.read(aAddress.raw_address(), 4); - return SUCCESS; - } - else - { - // This isn't an answer type we're after, move onto the next one - for (uint16_t i =0; i < htons(header_flags); i++) - { - iUdp.read(); // we don't care about the returned byte - } - } - } - - // Mark the entire packet as read - iUdp.flush(); - - // If we get here then we haven't found an answer - return -10;//INVALID_RESPONSE; -} - diff --git a/libraries/UIPEthernet/src/Dns.h b/libraries/UIPEthernet/src/Dns.h deleted file mode 100644 index 4913ca8..0000000 --- a/libraries/UIPEthernet/src/Dns.h +++ /dev/null @@ -1,41 +0,0 @@ -// Arduino DNS client for Enc28J60-based Ethernet shield -// (c) Copyright 2009-2010 MCQN Ltd. -// Released under Apache License, version 2.0 - -#ifndef DNSClient_h -#define DNSClient_h - -#include - -class DNSClient -{ -public: - // ctor - void begin(const IPAddress& aDNSServer); - - /** Convert a numeric IP address string into a four-byte IP address. - @param aIPAddrString IP address to convert - @param aResult IPAddress structure to store the returned IP address - @result 1 if aIPAddrString was successfully converted to an IP address, - else error code - */ - int inet_aton(const char *aIPAddrString, IPAddress& aResult); - - /** Resolve the given hostname to an IP address. - @param aHostname Name to be resolved - @param aResult IPAddress structure to store the returned IP address - @result 1 if aIPAddrString was successfully converted to an IP address, - else error code - */ - int getHostByName(const char* aHostname, IPAddress& aResult); - -protected: - uint16_t BuildRequest(const char* aName); - uint16_t ProcessResponse(uint16_t aTimeout, IPAddress& aAddress); - - IPAddress iDNSServer; - uint16_t iRequestId; - UIPUDP iUdp; -}; - -#endif diff --git a/libraries/UIPEthernet/src/UIPClient.cpp b/libraries/UIPEthernet/src/UIPClient.cpp deleted file mode 100644 index 73daaba..0000000 --- a/libraries/UIPEthernet/src/UIPClient.cpp +++ /dev/null @@ -1,533 +0,0 @@ -/* - UIPClient.cpp - Arduino implementation of a uIP wrapper class. - Copyright (c) 2013 Norbert Truchsess - All rights reserved. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - */ - -extern "C" -{ -#import "utility/uip-conf.h" -#import "utility/uip.h" -#import "utility/uip_arp.h" -#import "string.h" -} -#include "UIPEthernet.h" -#include "UIPClient.h" -#include "Dns.h" - -#ifdef UIPETHERNET_DEBUG_CLIENT -#include "HardwareSerial.h" -#endif - -#define UIP_TCP_PHYH_LEN UIP_LLH_LEN+UIP_IPTCPH_LEN - -uip_userdata_t UIPClient::all_data[UIP_CONNS]; - -UIPClient::UIPClient() : - data(NULL) -{ -} - -UIPClient::UIPClient(uip_userdata_t* conn_data) : - data(conn_data) -{ -} - -int -UIPClient::connect(IPAddress ip, uint16_t port) -{ - uip_ipaddr_t ipaddr; - uip_ip_addr(ipaddr, ip); - struct uip_conn* conn = uip_connect(&ipaddr, htons(port)); - if (conn) - { - while((conn->tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) - { - UIPEthernet.tick(); - if ((conn->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) - { - data = (uip_userdata_t*) conn->appstate; -#ifdef UIPETHERNET_DEBUG_CLIENT - - Serial.print(F("connected, state: ")); - Serial.print(data->state); - Serial.print(F(", first packet in: ")); - Serial.println(data->packets_in[0]); -#endif - return 1; - } - } - } - return 0; -} - -int -UIPClient::connect(const char *host, uint16_t port) -{ - // Look up the host first - int ret = 0; -#if UIP_UDP - DNSClient dns; - IPAddress remote_addr; - - dns.begin(UIPEthernet.dnsServerIP()); - ret = dns.getHostByName(host, remote_addr); - if (ret == 1) { - return connect(remote_addr, port); - } -#endif - return ret; -} - -void -UIPClient::stop() -{ - if (data) - { - _flushBlocks(&data->packets_in[0]); - if (data->state & UIP_CLIENT_CLOSED) - { - data->state = 0; - } - else - { - data->state |= UIP_CLIENT_CLOSE; - } - } - data = NULL; - UIPEthernet.tick(); -} - -uint8_t -UIPClient::connected() -{ - return (data && (data->packets_in[0] != NOBLOCK || (data->state & UIP_CLIENT_CONNECTED))) ? 1 : 0; -} - -bool -UIPClient::operator==(const UIPClient& rhs) -{ - return data && rhs.data && (data == rhs.data); -} - -UIPClient::operator bool() -{ - UIPEthernet.tick(); - return data && (!(data->state & UIP_CLIENT_CLOSED) || data->packets_in[0] != NOBLOCK); -} - -size_t -UIPClient::write(uint8_t c) -{ - return _write(data, &c, 1); -} - -size_t -UIPClient::write(const uint8_t *buf, size_t size) -{ - return _write(data, buf, size); -} - -size_t -UIPClient::_write(uip_userdata_t* u, const uint8_t *buf, size_t size) -{ - int remain = size; - uint16_t written; -#if UIP_ATTEMPTS_ON_WRITE > 0 - uint16_t attempts = UIP_ATTEMPTS_ON_WRITE; -#endif - repeat: - UIPEthernet.tick(); - if (u && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_CLOSED))) - { - memhandle* p = _currentBlock(&u->packets_out[0]); - if (*p == NOBLOCK) - { -newpacket: - *p = UIPEthernet.network.allocBlock(UIP_SOCKET_DATALEN); - if (*p == NOBLOCK) - { -#if UIP_ATTEMPTS_ON_WRITE > 0 - if ((--attempts)>0) -#endif -#if UIP_ATTEMPTS_ON_WRITE != 0 - goto repeat; -#endif - goto ready; - } - u->out_pos = 0; - } -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.print(F("UIPClient.write: writePacket(")); - Serial.print(*p); - Serial.print(F(") pos: ")); - Serial.print(u->out_pos); - Serial.print(F(", buf[")); - Serial.print(size-remain); - Serial.print(F("-")); - Serial.print(remain); - Serial.print(F("]: '")); - Serial.write((uint8_t*)buf+size-remain,remain); - Serial.println(F("'")); -#endif - written = UIPEthernet.network.writePacket(*p,u->out_pos,(uint8_t*)buf+size-remain,remain); - remain -= written; - u->out_pos+=written; - if (remain > 0) - { - if (p==&u->packets_out[UIP_SOCKET_NUMPACKETS-1]) - { -#if UIP_ATTEMPTS_ON_WRITE > 0 - if ((--attempts)>0) -#endif -#if UIP_ATTEMPTS_ON_WRITE != 0 - goto repeat; -#endif - goto ready; - } - p++; - goto newpacket; - } -ready: - return size-remain; - } - return -1; -} - -int -UIPClient::available() -{ - if (*this) - return _available(data); - return 0; -} - -int -UIPClient::_available(uip_userdata_t *u) -{ - memhandle* p = &u->packets_in[0]; - if (*p == NOBLOCK) - return 0; - int len = 0; - for(memhandle* end = p+UIP_SOCKET_NUMPACKETS; p < end; p++) - { - if(*p == NOBLOCK) - break; - len += UIPEthernet.network.blockSize(*p); - } - return len; -} - -int -UIPClient::read(uint8_t *buf, size_t size) -{ - if (*this) - { - int remain = size; - memhandle* p = &data->packets_in[0]; - if (*p == NOBLOCK) - return 0; - int read; - do - { - read = UIPEthernet.network.readPacket(*p,0,buf+size-remain,remain); - if (read == UIPEthernet.network.blockSize(*p)) - { - remain -= read; - _eatBlock(p); - if (uip_stopped(&uip_conns[data->state & UIP_CLIENT_SOCKETS]) && !(data->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_CLOSED))) - data->state |= UIP_CLIENT_RESTART; - if (*p == NOBLOCK) - { - if (data->state & UIP_CLIENT_CLOSED) - { - data->state = 0; - data = NULL; - } - return size-remain; - } - } - else - { - UIPEthernet.network.resizeBlock(*p,read); - break; - } - } - while(remain > 0); - return size; - } - return -1; -} - -int -UIPClient::read() -{ - uint8_t c; - if (read(&c,1) < 0) - return -1; - return c; -} - -int -UIPClient::peek() -{ - if (*this) - { - memhandle p = data->packets_in[0]; - if (p != NOBLOCK) - { - uint8_t c; - UIPEthernet.network.readPacket(p,0,&c,1); - return c; - } - } - return -1; -} - -void -UIPClient::flush() -{ - if (*this) - { - _flushBlocks(&data->packets_in[0]); - } -} - -void -uipclient_appcall(void) -{ - UIPClient::uip_callback(); -} - -void -UIPClient::uip_callback() -{ - uip_userdata_t *u = (uip_userdata_t*)uip_conn->appstate; - if (!u && uip_connected()) - { -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.println(F("UIPClient uip_connected")); -#endif - u = (uip_userdata_t*) _allocateData(); - if (u) - { - uip_conn->appstate = u; -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.print(F("UIPClient allocated state: ")); - Serial.println(u->state); -#endif - } -#ifdef UIPETHERNET_DEBUG_CLIENT - else - Serial.println(F("UIPClient allocation failed")); -#endif - } - if (u) - { - if (uip_newdata()) - { -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.print(F("UIPClient uip_newdata, uip_len:")); - Serial.println(uip_len); -#endif - if (uip_len && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_CLOSED))) - { - memhandle newPacket = UIPEthernet.network.allocBlock(uip_len); - if (newPacket != NOBLOCK) - { - memhandle* p = _currentBlock(&u->packets_in[0]); - //if it's not the first packet - if (*p != NOBLOCK) - { - uint8_t slot = p - &u->packets_in[0]; - if (slot < UIP_SOCKET_NUMPACKETS-1) - p++; - //if this is the last slot stop this connection - if (slot >= UIP_SOCKET_NUMPACKETS-2) - { - uip_stop(); - //if there's no free slot left omit loosing this packet and (again) stop this connection - if (slot == UIP_SOCKET_NUMPACKETS-1) - goto reject_newdata; - } - } - UIPEthernet.network.copyPacket(newPacket,0,UIPEthernet.in_packet,((uint8_t*)uip_appdata)-uip_buf,uip_len); - *p = newPacket; - goto finish_newdata; - } -reject_newdata: - UIPEthernet.packetstate &= ~UIPETHERNET_FREEPACKET; - uip_stop(); - } - } -finish_newdata: - if (u->state & UIP_CLIENT_RESTART) - { - u->state &= ~UIP_CLIENT_RESTART; - uip_restart(); - } - // If the connection has been closed, save received but unread data. - if (uip_closed() || uip_timedout()) - { -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.println(F("UIPClient uip_closed")); -#endif - // drop outgoing packets not sent yet: - _flushBlocks(&u->packets_out[0]); - if (u->packets_in[0] != NOBLOCK) - { - ((uip_userdata_closed_t *)u)->lport = uip_conn->lport; - u->state |= UIP_CLIENT_CLOSED; - } - else - u->state = 0; - // disassociate appdata. - uip_conn->appstate = NULL; - goto nodata; - } - if (uip_acked()) - { -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.println(F("UIPClient uip_acked")); -#endif - _eatBlock(&u->packets_out[0]); - } - if (uip_poll() || uip_rexmit()) - { -#ifdef UIPETHERNET_DEBUG_CLIENT - //Serial.println(F("UIPClient uip_poll")); -#endif - memhandle p = u->packets_out[0]; - if (p != NOBLOCK) - { - if (u->packets_out[1] == NOBLOCK) - { - uip_len = u->out_pos; - if (uip_len > 0) - { - UIPEthernet.network.resizeBlock(p,0,uip_len); - } - } - else - uip_len = UIPEthernet.network.blockSize(p); - if (uip_len > 0) - { - UIPEthernet.uip_hdrlen = ((uint8_t*)uip_appdata)-uip_buf; - UIPEthernet.uip_packet = UIPEthernet.network.allocBlock(UIPEthernet.uip_hdrlen+uip_len); - if (UIPEthernet.uip_packet != NOBLOCK) - { - UIPEthernet.network.copyPacket(UIPEthernet.uip_packet,UIPEthernet.uip_hdrlen,p,0,uip_len); - UIPEthernet.packetstate |= UIPETHERNET_SENDPACKET; - uip_send(uip_appdata,uip_len); - } - return; - } - } - } - // don't close connection unless all outgoing packets are sent - if (u->state & UIP_CLIENT_CLOSE) - { -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.print(F("UIPClient state UIP_CLIENT_CLOSE")); -#endif - if (u->packets_out[0] == NOBLOCK) - { -#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.print(F("UIPClient state UIP_CLIENT_CLOSE -> free userdata")); -#endif - u->state = 0; - uip_conn->appstate = NULL; - uip_close(); - } - else - uip_stop(); - } - } -nodata: - UIPEthernet.uip_packet = NOBLOCK; - uip_len=0; -} - -uip_userdata_t * -UIPClient::_allocateData() -{ - for ( uint8_t sock = 0; sock < UIP_CONNS; sock++ ) - { - uip_userdata_t* data = &UIPClient::all_data[sock]; - if (!data->state) - { - data->state = sock | UIP_CLIENT_CONNECTED; - memset(&data->packets_in[0],0,sizeof(uip_userdata_t)-sizeof(data->state)); - return data; - } - } - return NULL; -} - -memhandle* -UIPClient::_currentBlock(memhandle* block) -{ - for(memhandle* end = block+UIP_SOCKET_NUMPACKETS-1; block < end; block++) - if(*(block+1) == NOBLOCK) - break; - return block; -} - -void -UIPClient::_eatBlock(memhandle* block) -{ -#ifdef UIPETHERNET_DEBUG_CLIENT - memhandle* start = block; - Serial.print(F("eatblock(")); - Serial.print(*block); - Serial.print("): "); - for (uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS; i++) - { - Serial.print(start[i]); - Serial.print(" "); - } - Serial.print("-> "); -#endif - memhandle* end = block+(UIP_SOCKET_NUMPACKETS-1); - UIPEthernet.network.freeBlock(*block); - while(block < end) - *block = *((block++)+1); - *end = NOBLOCK; -#ifdef UIPETHERNET_DEBUG_CLIENT - for (uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS; i++) - { - Serial.print(start[i]); - Serial.print(F(" ")); - } - Serial.println(); -#endif -} - -void -UIPClient::_flushBlocks(memhandle* block) -{ - for(memhandle* end = block+UIP_SOCKET_NUMPACKETS; block < end; block++) - { - if(*block != NOBLOCK) - { - UIPEthernet.network.freeBlock(*block); - *block = NOBLOCK; - } - else - break; - } -} - diff --git a/libraries/UIPEthernet/src/UIPClient.h b/libraries/UIPEthernet/src/UIPClient.h deleted file mode 100644 index 0d8beab..0000000 --- a/libraries/UIPEthernet/src/UIPClient.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - UIPClient.h - Arduino implementation of a uIP wrapper class. - Copyright (c) 2013 Norbert Truchsess - All rights reserved. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - */ - -#ifndef UIPCLIENT_H -#define UIPCLIENT_H - -#include "ethernet_comp.h" -#import "Client.h" -#import "utility/mempool.h" - -extern "C" { - #import "utility/uip.h" -} - -#define UIP_SOCKET_DATALEN UIP_TCP_MSS -//#define UIP_SOCKET_NUMPACKETS UIP_RECEIVE_WINDOW/UIP_TCP_MSS+1 -#ifndef UIP_SOCKET_NUMPACKETS -#define UIP_SOCKET_NUMPACKETS 5 -#endif - -#define UIP_CLIENT_CONNECTED 0x10 -#define UIP_CLIENT_CLOSE 0x20 -#define UIP_CLIENT_CLOSED 0x40 -#define UIP_CLIENT_RESTART 0x80 -#define UIP_CLIENT_STATEFLAGS (UIP_CLIENT_CONNECTED | UIP_CLIENT_CLOSE | UIP_CLIENT_CLOSED | UIP_CLIENT_RESTART) -#define UIP_CLIENT_SOCKETS ~UIP_CLIENT_STATEFLAGS - -typedef uint8_t uip_socket_ptr; - -typedef struct { - uint8_t state; - memhandle packets_in[UIP_SOCKET_NUMPACKETS]; - uint16_t lport; /**< The local TCP port, in network byte order. */ -} uip_userdata_closed_t; - -typedef struct { - uint8_t state; - memhandle packets_in[UIP_SOCKET_NUMPACKETS]; - memhandle packets_out[UIP_SOCKET_NUMPACKETS]; - memaddress out_pos; -} uip_userdata_t; - -class UIPClient : public Client { - -public: - UIPClient(); - int connect(IPAddress ip, uint16_t port); - int connect(const char *host, uint16_t port); - int read(uint8_t *buf, size_t size); - void stop(); - uint8_t connected(); - operator bool(); - virtual bool operator==(const EthernetClient&); - virtual bool operator!=(const EthernetClient& rhs) { return !this->operator==(rhs); }; - - size_t write(uint8_t); - size_t write(const uint8_t *buf, size_t size); - int available(); - int read(); - int peek(); - void flush(); - -private: - UIPClient(struct uip_conn *_conn); - UIPClient(uip_userdata_t* conn_data); - - uip_userdata_t* data; - - static uip_userdata_t all_data[UIP_CONNS]; - static uip_userdata_t* _allocateData(); - static uip_userdata_t* _getData(struct uip_conn * conn); - - static size_t _write(uip_userdata_t *,const uint8_t *buf, size_t size); - static int _available(uip_userdata_t *); - - static memhandle * _currentBlock(memhandle* blocks); - static void _eatBlock(memhandle* blocks); - static void _flushBlocks(memhandle* blocks); - - friend class UIPEthernetClass; - friend class UIPServer; - - friend void uipclient_appcall(void); - - static void uip_callback(); -}; - -#endif diff --git a/libraries/UIPEthernet/src/UIPEthernet.cpp b/libraries/UIPEthernet/src/UIPEthernet.cpp deleted file mode 100644 index ca59e93..0000000 --- a/libraries/UIPEthernet/src/UIPEthernet.cpp +++ /dev/null @@ -1,433 +0,0 @@ -/* - UIPEthernet.cpp - Arduino implementation of a uIP wrapper class. - Copyright (c) 2013 Norbert Truchsess - All rights reserved. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - */ - -#include -#include "UIPEthernet.h" -#include "utility/Enc28J60Network.h" - -#if(defined UIPETHERNET_DEBUG || defined UIPETHERNET_DEBUG_CHKSUM) -#include "HardwareSerial.h" -#endif - -extern "C" -{ -#include "utility/uip-conf.h" -#include "utility/uip.h" -#include "utility/uip_arp.h" -#include "utility/uip_timer.h" -} - -#define ETH_HDR ((struct uip_eth_hdr *)&uip_buf[0]) - -// Because uIP isn't encapsulated within a class we have to use global -// variables, so we can only have one TCP/IP stack per program. - -UIPEthernetClass::UIPEthernetClass() : - in_packet(NOBLOCK), - uip_packet(NOBLOCK), - uip_hdrlen(0), - packetstate(0), - _dhcp(NULL) -{ -} - -int -UIPEthernetClass::begin(const uint8_t* mac) -{ - static DhcpClass s_dhcp; - _dhcp = &s_dhcp; - - // Initialise the basic info - init(mac); - - // Now try to get our config info from a DHCP server - int ret = _dhcp->beginWithDHCP((uint8_t*)mac); - if(ret == 1) - { - // We've successfully found a DHCP server and got our configuration info, so set things - // accordingly - configure(_dhcp->getLocalIp(),_dhcp->getDnsServerIp(),_dhcp->getGatewayIp(),_dhcp->getSubnetMask()); - } - return ret; -} - -void -UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip) -{ - IPAddress dns = ip; - dns[3] = 1; - begin(mac, ip, dns); -} - -void -UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns) -{ - IPAddress gateway = ip; - gateway[3] = 1; - begin(mac, ip, dns, gateway); -} - -void -UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway) -{ - IPAddress subnet(255, 255, 255, 0); - begin(mac, ip, dns, gateway, subnet); -} - -void -UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet) -{ - init(mac); - configure(ip,dns,gateway,subnet); -} - -int UIPEthernetClass::maintain(){ - tick(); - int rc = DHCP_CHECK_NONE; - if(_dhcp != NULL){ - //we have a pointer to dhcp, use it - rc = _dhcp->checkLease(); - switch ( rc ){ - case DHCP_CHECK_NONE: - //nothing done - break; - case DHCP_CHECK_RENEW_OK: - case DHCP_CHECK_REBIND_OK: - //we might have got a new IP. - configure(_dhcp->getLocalIp(),_dhcp->getDnsServerIp(),_dhcp->getGatewayIp(),_dhcp->getSubnetMask()); - break; - default: - //this is actually a error, it will retry though - break; - } - } - return rc; -} - -IPAddress UIPEthernetClass::localIP() -{ - IPAddress ret; - uip_ipaddr_t a; - uip_gethostaddr(a); - return ip_addr_uip(a); -} - -IPAddress UIPEthernetClass::subnetMask() -{ - IPAddress ret; - uip_ipaddr_t a; - uip_getnetmask(a); - return ip_addr_uip(a); -} - -IPAddress UIPEthernetClass::gatewayIP() -{ - IPAddress ret; - uip_ipaddr_t a; - uip_getdraddr(a); - return ip_addr_uip(a); -} - -IPAddress UIPEthernetClass::dnsServerIP() -{ - return _dnsServerAddress; -} - -void -UIPEthernetClass::tick() -{ - if (in_packet == NOBLOCK) - { - in_packet = network.receivePacket(); -#ifdef UIPETHERNET_DEBUG - if (in_packet != NOBLOCK) - { - Serial.print(F("--------------\nreceivePacket: ")); - Serial.println(in_packet); - } -#endif - } - if (in_packet != NOBLOCK) - { - packetstate = UIPETHERNET_FREEPACKET; - uip_len = network.blockSize(in_packet); - if (uip_len > 0) - { - network.readPacket(in_packet,0,(uint8_t*)uip_buf,UIP_BUFSIZE); - if (ETH_HDR ->type == HTONS(UIP_ETHTYPE_IP)) - { - uip_packet = in_packet; -#ifdef UIPETHERNET_DEBUG - Serial.print(F("readPacket type IP, uip_len: ")); - Serial.println(uip_len); -#endif - uip_arp_ipin(); - uip_input(); - if (uip_len > 0) - { - uip_arp_out(); - network_send(); - } - } - else if (ETH_HDR ->type == HTONS(UIP_ETHTYPE_ARP)) - { -#ifdef UIPETHERNET_DEBUG - Serial.print(F("readPacket type ARP, uip_len: ")); - Serial.println(uip_len); -#endif - uip_arp_arpin(); - if (uip_len > 0) - { - network_send(); - } - } - } - if (in_packet != NOBLOCK && (packetstate & UIPETHERNET_FREEPACKET)) - { -#ifdef UIPETHERNET_DEBUG - Serial.print(F("freeing packet: ")); - Serial.println(in_packet); -#endif - network.freePacket(); - in_packet = NOBLOCK; - } - } - - if (uip_timer_expired(&periodic_timer)) - { - uip_timer_restart(&periodic_timer); - for (int i = 0; i < UIP_CONNS; i++) - { - uip_periodic(i); - // If the above function invocation resulted in data that - // should be sent out on the network, the global variable - // uip_len is set to a value > 0. - if (uip_len > 0) - { - uip_arp_out(); - network_send(); - } - } - -#if UIP_UDP - for (int i = 0; i < UIP_UDP_CONNS; i++) - { - uip_udp_periodic(i); - // If the above function invocation resulted in data that - // should be sent out on the network, the global variable - // uip_len is set to a value > 0. */ - if (uip_len > 0) - { - network_send(); - } - } -#endif /* UIP_UDP */ - } -} - -boolean UIPEthernetClass::network_send() -{ - if (packetstate & UIPETHERNET_SENDPACKET) - { -#ifdef UIPETHERNET_DEBUG - Serial.print(F("network_send uip_packet: ")); - Serial.print(uip_packet); - Serial.print(F(", hdrlen: ")); - Serial.println(uip_hdrlen); -#endif - network.writePacket(uip_packet,0,uip_buf,uip_hdrlen); - goto sendandfree; - } - uip_packet = network.allocBlock(uip_len); - if (uip_packet != NOBLOCK) - { -#ifdef UIPETHERNET_DEBUG - Serial.print(F("network_send uip_buf (uip_len): ")); - Serial.print(uip_len); - Serial.print(F(", packet: ")); - Serial.println(uip_packet); -#endif - network.writePacket(uip_packet,0,uip_buf,uip_len); - goto sendandfree; - } - return false; -sendandfree: - network.sendPacket(uip_packet); - network.freeBlock(uip_packet); - uip_packet = NOBLOCK; - return true; -} - -void UIPEthernetClass::init(const uint8_t* mac) { - uip_timer_set(&this->periodic_timer, CLOCK_SECOND / 4); - - network.init((uint8_t*)mac); - uip_seteth_addr(mac); - - uip_init(); -} - -void UIPEthernetClass::configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet) { - uip_ipaddr_t ipaddr; - - uip_ip_addr(ipaddr, ip); - uip_sethostaddr(ipaddr); - - uip_ip_addr(ipaddr, gateway); - uip_setdraddr(ipaddr); - - uip_ip_addr(ipaddr, subnet); - uip_setnetmask(ipaddr); - - _dnsServerAddress = dns; -} - -UIPEthernetClass UIPEthernet; - -/*---------------------------------------------------------------------------*/ -uint16_t -UIPEthernetClass::chksum(uint16_t sum, const uint8_t *data, uint16_t len) -{ - uint16_t t; - const uint8_t *dataptr; - const uint8_t *last_byte; - - dataptr = data; - last_byte = data + len - 1; - - while(dataptr < last_byte) { /* At least two more bytes */ - t = (dataptr[0] << 8) + dataptr[1]; - sum += t; - if(sum < t) { - sum++; /* carry */ - } - dataptr += 2; - } - - if(dataptr == last_byte) { - t = (dataptr[0] << 8) + 0; - sum += t; - if(sum < t) { - sum++; /* carry */ - } - } - - /* Return sum in host byte order. */ - return sum; -} - -/*---------------------------------------------------------------------------*/ - -uint16_t -UIPEthernetClass::ipchksum(void) -{ - uint16_t sum; - - sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN); - return (sum == 0) ? 0xffff : htons(sum); -} - -/*---------------------------------------------------------------------------*/ -uint16_t -UIPEthernetClass::upper_layer_chksum(uint8_t proto) -{ - uint16_t upper_layer_len; - uint16_t sum; - -#if UIP_CONF_IPV6 - upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]); -#else /* UIP_CONF_IPV6 */ - upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN; -#endif /* UIP_CONF_IPV6 */ - - /* First sum pseudoheader. */ - - /* IP protocol and length fields. This addition cannot carry. */ - sum = upper_layer_len + proto; - /* Sum IP source and destination addresses. */ - sum = chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t)); - - uint8_t upper_layer_memlen; - switch(proto) - { - case UIP_PROTO_ICMP: - case UIP_PROTO_ICMP6: - upper_layer_memlen = upper_layer_len; - break; - case UIP_PROTO_TCP: - upper_layer_memlen = (BUF->tcpoffset >> 4) << 2; - break; -#if UIP_UDP - case UIP_PROTO_UDP: - upper_layer_memlen = UIP_UDPH_LEN; - break; -#endif - } - sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], upper_layer_memlen); -#ifdef UIPETHERNET_DEBUG_CHKSUM - Serial.print(F("chksum uip_buf[")); - Serial.print(UIP_IPH_LEN + UIP_LLH_LEN); - Serial.print(F("-")); - Serial.print(UIP_IPH_LEN + UIP_LLH_LEN + upper_layer_memlen); - Serial.print(F("]: ")); - Serial.println(htons(sum),HEX); -#endif - if (upper_layer_memlen < upper_layer_len) - { - sum = network.chksum( - sum, - uip_packet, - UIP_IPH_LEN + UIP_LLH_LEN + upper_layer_memlen, - upper_layer_len - upper_layer_memlen - ); -#ifdef UIPETHERNET_DEBUG_CHKSUM - Serial.print(F("chksum uip_packet(")); - Serial.print(uip_packet); - Serial.print(F(")[")); - Serial.print(UIP_IPH_LEN + UIP_LLH_LEN + upper_layer_memlen); - Serial.print(F("-")); - Serial.print(UIP_IPH_LEN + UIP_LLH_LEN + upper_layer_len); - Serial.print(F"]: ")); - Serial.println(htons(sum),HEX); -#endif - } - return (sum == 0) ? 0xffff : htons(sum); -} - -uint16_t -uip_ipchksum(void) -{ - return UIPEthernet.ipchksum(); -} - -uint16_t -uip_tcpchksum(void) -{ - uint16_t sum = UIPEthernet.upper_layer_chksum(UIP_PROTO_TCP); - return sum; -} - -#if UIP_UDP -uint16_t -uip_udpchksum(void) -{ - uint16_t sum = UIPEthernet.upper_layer_chksum(UIP_PROTO_UDP); - return sum; -} -#endif diff --git a/libraries/UIPEthernet/src/UIPEthernet.h b/libraries/UIPEthernet/src/UIPEthernet.h deleted file mode 100644 index 94502f1..0000000 --- a/libraries/UIPEthernet/src/UIPEthernet.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - UIPEthernet.h - Arduino implementation of a uIP wrapper class. - Copyright (c) 2013 Norbert Truchsess - All rights reserved. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - */ - -#ifndef UIPETHERNET_H -#define UIPETHERNET_H - -#include "ethernet_comp.h" -#include -#include "Dhcp.h" -#include "IPAddress.h" -#include "utility/Enc28J60Network.h" -#include "UIPClient.h" -#include "UIPServer.h" -#include "UIPUdp.h" - -extern "C" -{ -#include "utility/uip_timer.h" -#include "utility/uip.h" -} - -//#define UIPETHERNET_DEBUG -//#define UIPETHERNET_DEBUG_CHKSUM -//#define UIPETHERNET_DEBUG_UDP -//#define UIPETHERNET_DEBUG_CLIENT - -#define UIPETHERNET_FREEPACKET 1 -#define UIPETHERNET_SENDPACKET 2 -#define UIPETHERNET_BUFFERREAD 4 - -#define uip_ip_addr(addr, ip) do { \ - ((u16_t *)(addr))[0] = HTONS(((ip[0]) << 8) | (ip[1])); \ - ((u16_t *)(addr))[1] = HTONS(((ip[2]) << 8) | (ip[3])); \ - } while(0) - -#define ip_addr_uip(a) IPAddress(a[0] & 0xFF, a[0] >> 8 , a[1] & 0xFF, a[1] >> 8) //TODO this is not IPV6 capable - -#define uip_seteth_addr(eaddr) do {uip_ethaddr.addr[0] = eaddr[0]; \ - uip_ethaddr.addr[1] = eaddr[1];\ - uip_ethaddr.addr[2] = eaddr[2];\ - uip_ethaddr.addr[3] = eaddr[3];\ - uip_ethaddr.addr[4] = eaddr[4];\ - uip_ethaddr.addr[5] = eaddr[5];} while(0) - -#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) - -class UIPEthernetClass -{ -public: - UIPEthernetClass(); - - int begin(const uint8_t* mac); - void begin(const uint8_t* mac, IPAddress ip); - void begin(const uint8_t* mac, IPAddress ip, IPAddress dns); - void begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway); - void begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet); - - // maintain() must be called at regular intervals to process the incoming serial - // data and issue IP events to the sketch. It does not return until all IP - // events have been processed. Renews dhcp-lease if required. - int maintain(); - - IPAddress localIP(); - IPAddress subnetMask(); - IPAddress gatewayIP(); - IPAddress dnsServerIP(); - -private: - IPAddress _dnsServerAddress; - DhcpClass* _dhcp; - - struct uip_timer periodic_timer; - - memhandle in_packet; - memhandle uip_packet; - uint8_t uip_hdrlen; - uint8_t packetstate; - - Enc28J60Network network; - - void init(const uint8_t* mac); - void configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet); - - void tick(); - - boolean network_send(); - - friend class UIPServer; - - friend class UIPClient; - - friend class UIPUDP; - - static uint16_t chksum(uint16_t sum, const uint8_t* data, uint16_t len); - static uint16_t ipchksum(void); - uint16_t upper_layer_chksum(uint8_t proto); - - friend uint16_t uip_ipchksum(void); - friend uint16_t uip_tcpchksum(void); - friend uint16_t uip_udpchksum(void); - -#if UIP_CONF_IPV6 - uint16_t uip_icmp6chksum(void); -#endif /* UIP_CONF_IPV6 */ -}; - -extern UIPEthernetClass UIPEthernet; - -#endif diff --git a/libraries/UIPEthernet/src/UIPServer.cpp b/libraries/UIPEthernet/src/UIPServer.cpp deleted file mode 100644 index 12ff72f..0000000 --- a/libraries/UIPEthernet/src/UIPServer.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - UIPServer.cpp - Arduino implementation of a uIP wrapper class. - Copyright (c) 2013 Norbert Truchsess - All rights reserved. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - */ -#include "UIPEthernet.h" -#include "UIPServer.h" -extern "C" { - #include "utility/uip-conf.h" -} - -UIPServer::UIPServer(uint16_t port) : _port(htons(port)) -{ -} - -UIPClient UIPServer::available() -{ - UIPEthernet.tick(); - for ( uip_userdata_t* data = &UIPClient::all_data[0]; data < &UIPClient::all_data[UIP_CONNS]; data++ ) - { - if (data->packets_in[0] != NOBLOCK - && (((data->state & UIP_CLIENT_CONNECTED) && uip_conns[data->state & UIP_CLIENT_SOCKETS].lport ==_port) - || ((data->state & UIP_CLIENT_CLOSED) && ((uip_userdata_closed_t *)data)->lport == _port))) - return UIPClient(data); - } - return UIPClient(); -} - -void UIPServer::begin() -{ - uip_listen(_port); - UIPEthernet.tick(); -} - -size_t UIPServer::write(uint8_t c) -{ - return write(&c,1); -} - -size_t UIPServer::write(const uint8_t *buf, size_t size) -{ - size_t ret = 0; - for ( uip_userdata_t* data = &UIPClient::all_data[0]; data < &UIPClient::all_data[UIP_CONNS]; data++ ) - { - if ((data->state & UIP_CLIENT_CONNECTED) && uip_conns[data->state & UIP_CLIENT_SOCKETS].lport ==_port) - ret += UIPClient::_write(data,buf,size); - } - return ret; -} - diff --git a/libraries/UIPEthernet/src/UIPServer.h b/libraries/UIPEthernet/src/UIPServer.h deleted file mode 100644 index 64bdade..0000000 --- a/libraries/UIPEthernet/src/UIPServer.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - UIPServer.h - Arduino implementation of a uIP wrapper class. - Copyright (c) 2013 Norbert Truchsess - All rights reserved. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - */ -#ifndef UIPSERVER_H -#define UIPSERVER_H - -#include "ethernet_comp.h" -#import "Server.h" -#import "UIPClient.h" - -class UIPServer : Server { - -public: - UIPServer(uint16_t); - UIPClient available(); - void begin(); - size_t write(uint8_t); - size_t write(const uint8_t *buf, size_t size); - using Print::write; - -private: - uint16_t _port; -}; - -#endif diff --git a/libraries/UIPEthernet/src/UIPUdp.cpp b/libraries/UIPEthernet/src/UIPUdp.cpp deleted file mode 100644 index d1cb7b1..0000000 --- a/libraries/UIPEthernet/src/UIPUdp.cpp +++ /dev/null @@ -1,424 +0,0 @@ -/* - UIPUdp.cpp - Arduino implementation of a uIP wrapper class. - Copyright (c) 2013 Norbert Truchsess - All rights reserved. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - */ - -#include "UIPEthernet.h" -#include "UIPUdp.h" -#include "Dns.h" - -#ifdef UIPETHERNET_DEBUG_UDP -#include "HardwareSerial.h" -#endif - -extern "C" { -#include "utility/uip-conf.h" -#include "utility/uip.h" -#include "utility/uip_arp.h" -} - -#if UIP_UDP -#define UIP_ARPHDRSIZE 42 -#define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN]) - -// Constructor -UIPUDP::UIPUDP() : - _uip_udp_conn(NULL) -{ - memset(&appdata,0,sizeof(appdata)); -} - -// initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use -uint8_t -UIPUDP::begin(uint16_t port) -{ - if (!_uip_udp_conn) - { - _uip_udp_conn = uip_udp_new(NULL, 0); - } - if (_uip_udp_conn) - { - uip_udp_bind(_uip_udp_conn,htons(port)); - _uip_udp_conn->appstate = &appdata; - return 1; - } - return 0; -} - -// Finish with the UDP socket -void -UIPUDP::stop() -{ - if (_uip_udp_conn) - { - flush(); - uip_udp_remove(_uip_udp_conn); - _uip_udp_conn->appstate = NULL; - _uip_udp_conn=NULL; - if (appdata.packet_in != NOBLOCK) - { - UIPEthernet.network.freeBlock(appdata.packet_in); - appdata.packet_in = NOBLOCK; - } - uint8_t i = 0; - memhandle* packet = &appdata.packets_in[0]; - while (*packet != NOBLOCK && i < UIP_UDP_NUMPACKETS) - { - UIPEthernet.network.freeBlock(*packet); - *packet++ = NOBLOCK; - i++; - } - if (appdata.packet_out != NOBLOCK) - { - UIPEthernet.network.freeBlock(appdata.packet_out); - appdata.packet_out = NOBLOCK; - } - } -} - -// Sending UDP packets - -// Start building up a packet to send to the remote host specific in ip and port -// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port -int -UIPUDP::beginPacket(IPAddress ip, uint16_t port) -{ - UIPEthernet.tick(); - if (ip && port) - { - uip_ipaddr_t ripaddr; - uip_ip_addr(&ripaddr, ip); -#ifdef UIPETHERNET_DEBUG_UDP - Serial.print(F("udp beginPacket, ")); -#endif - if (_uip_udp_conn) - { - _uip_udp_conn->rport = htons(port); - uip_ipaddr_copy(_uip_udp_conn->ripaddr, &ripaddr); - } - else - { - _uip_udp_conn = uip_udp_new(&ripaddr,htons(port)); - if (_uip_udp_conn) - { -#ifdef UIPETHERNET_DEBUG_UDP - Serial.print(F("new connection, ")); -#endif - _uip_udp_conn->appstate = &appdata; - } - else - { -#ifdef UIPETHERNET_DEBUG_UDP - Serial.println(F("failed to allocate new connection")); -#endif - return 0; - } - } -#ifdef UIPETHERNET_DEBUG_UDP - Serial.print(F("rip: ")); - Serial.print(ip); - Serial.print(F(", port: ")); - Serial.println(port); -#endif - } - if (_uip_udp_conn) - { - if (appdata.packet_out == NOBLOCK) - { - appdata.packet_out = UIPEthernet.network.allocBlock(UIP_UDP_MAXPACKETSIZE); - appdata.out_pos = UIP_UDP_PHYH_LEN; - if (appdata.packet_out != NOBLOCK) - return 1; -#ifdef UIPETHERNET_DEBUG_UDP - else - Serial.println(F("failed to allocate memory for packet")); -#endif - } -#ifdef UIPETHERNET_DEBUG_UDP - else - Serial.println(F("previous packet on that connection not sent yet")); -#endif - } - return 0; -} - -// Start building up a packet to send to the remote host specific in host and port -// Returns 1 if successful, 0 if there was a problem resolving the hostname or port -int -UIPUDP::beginPacket(const char *host, uint16_t port) -{ - // Look up the host first - int ret = 0; - DNSClient dns; - IPAddress remote_addr; - - dns.begin(UIPEthernet.dnsServerIP()); - ret = dns.getHostByName(host, remote_addr); - if (ret == 1) { - return beginPacket(remote_addr, port); - } else { - return ret; - } -} - -// Finish off this packet and send it -// Returns 1 if the packet was sent successfully, 0 if there was an error -int -UIPUDP::endPacket() -{ - if (_uip_udp_conn && appdata.packet_out != NOBLOCK) - { - appdata.send = true; - UIPEthernet.network.resizeBlock(appdata.packet_out,0,appdata.out_pos); - uip_udp_periodic_conn(_uip_udp_conn); - if (uip_len > 0) - { - UIPEthernet.network_send(); - return 1; - } - } - return 0; -} - -// Write a single byte into the packet -size_t -UIPUDP::write(uint8_t c) -{ - return write(&c,1); -} - -// Write size bytes from buffer into the packet -size_t -UIPUDP::write(const uint8_t *buffer, size_t size) -{ - if (appdata.packet_out != NOBLOCK) - { - size_t ret = UIPEthernet.network.writePacket(appdata.packet_out,appdata.out_pos,(uint8_t*)buffer,size); - appdata.out_pos += ret; - return ret; - } - return 0; -} - -// Start processing the next available incoming packet -// Returns the size of the packet in bytes, or 0 if no packets are available -int -UIPUDP::parsePacket() -{ - UIPEthernet.tick(); - if (appdata.packet_in != NOBLOCK) - { -#ifdef UIPETHERNET_DEBUG_UDP - Serial.print(F("udp parsePacket freeing previous packet: ")); - Serial.println(appdata.packet_in); -#endif; - UIPEthernet.network.freeBlock(appdata.packet_in); - } - memhandle *packet = &appdata.packets_in[0]; - appdata.packet_in = *packet; - if (appdata.packet_in != NOBLOCK) - { -#ifdef UIPETHERNET_DEBUG_UDP - Serial.print(F("udp parsePacket received packet: ")); - Serial.print(appdata.packet_in); -#endif - if (UIP_UDP_NUMPACKETS > 1) - { - uint8_t i = 1; - memhandle* p = packet+1; -freeloop: - *packet = *p; - if (*packet == NOBLOCK) - goto freeready; - packet++; - if (i < UIP_UDP_NUMPACKETS-1) - { - i++; - p++; - goto freeloop; - } - } - *packet = NOBLOCK; -freeready: - int size = UIPEthernet.network.blockSize(appdata.packet_in); -#ifdef UIPETHERNET_DEBUG_UDP - Serial.print(F(", size: ")); - Serial.println(size); -#endif - return size; - } - return 0; -} - -// Number of bytes remaining in the current packet -int -UIPUDP::available() -{ - UIPEthernet.tick(); - if (appdata.packet_in != NOBLOCK) - { - return UIPEthernet.network.blockSize(appdata.packet_in); - } - return 0; -} - -// Read a single byte from the current packet -int -UIPUDP::read() -{ - unsigned char c; - if (read(&c,1) > 0) - { - return c; - } - return -1; -} - -// Read up to len bytes from the current packet and place them into buffer -// Returns the number of bytes read, or 0 if none are available -int -UIPUDP::read(unsigned char* buffer, size_t len) -{ - UIPEthernet.tick(); - if (appdata.packet_in != NOBLOCK) - { - int read = UIPEthernet.network.readPacket(appdata.packet_in,0,buffer,len); - UIPEthernet.network.resizeBlock(appdata.packet_in,read); - return read; - } - return 0; -} - -// Return the next byte from the current packet without moving on to the next byte -int -UIPUDP::peek() -{ - UIPEthernet.tick(); - if (appdata.packet_in != NOBLOCK) - { - unsigned char c; - if (UIPEthernet.network.readPacket(appdata.packet_in,0,&c,1) == 1) - return c; - } - return -1; -} - -// Finish reading the current packet -void -UIPUDP::flush() -{ - UIPEthernet.tick(); - if (appdata.packet_in != NOBLOCK) - { - UIPEthernet.network.freeBlock(appdata.packet_in); - appdata.packet_in = NOBLOCK; - } -} - -// Return the IP address of the host who sent the current incoming packet -IPAddress -UIPUDP::remoteIP() -{ - return _uip_udp_conn ? ip_addr_uip(_uip_udp_conn->ripaddr) : IPAddress(); -} - -// Return the port of the host who sent the current incoming packet -uint16_t -UIPUDP::remotePort() -{ - return _uip_udp_conn ? ntohs(_uip_udp_conn->rport) : 0; -} - -// uIP callback function - -void -uipudp_appcall(void) { - UIPUDP::uip_callback(); -} - -void -UIPUDP::uip_callback() { - if (appdata_t *data = (appdata_t *)(uip_udp_conn->appstate)) - { - if (uip_newdata()) - { - uip_udp_conn->rport = UDPBUF->srcport; - uip_ipaddr_copy(uip_udp_conn->ripaddr,UDPBUF->srcipaddr); - memhandle *packet = &data->packets_in[0]; - uint8_t i = 0; - do - { - if (*packet == NOBLOCK) - { - *packet = UIPEthernet.network.allocBlock(ntohs(UDPBUF->udplen)-UIP_UDPH_LEN); - //if we are unable to allocate memory the packet is dropped. udp doesn't guarantee packet delivery - if (*packet != NOBLOCK) - { - //discard Linklevel and IP and udp-header and any trailing bytes: - UIPEthernet.network.copyPacket(*packet,0,UIPEthernet.in_packet,UIP_UDP_PHYH_LEN,UIPEthernet.network.blockSize(*packet)); - #ifdef UIPETHERNET_DEBUG_UDP - Serial.print(F("udp, uip_newdata received packet: ")); - Serial.print(*packet); - Serial.print(F(", slot: ")); - Serial.print(i); - Serial.print(F(", size: ")); - Serial.println(UIPEthernet.network.blockSize(*packet)); - #endif - break; - } - } - packet++; - i++; - } - while (i < UIP_UDP_NUMPACKETS); - } - if (uip_poll() && data->send) - { - //set uip_slen (uip private) by calling uip_udp_send -#ifdef UIPETHERNET_DEBUG_UDP - Serial.print(F("udp, uip_poll preparing packet to send: ")); - Serial.print(data->packet_out); - Serial.print(F(", size: ")); - Serial.println(UIPEthernet.network.blockSize(data->packet_out)); -#endif - UIPEthernet.uip_packet = data->packet_out; - data->packet_out = NOBLOCK; - UIPEthernet.uip_hdrlen = UIP_UDP_PHYH_LEN; - UIPEthernet.packetstate |= UIPETHERNET_SENDPACKET; - uip_udp_send(data->out_pos - (UIP_UDP_PHYH_LEN)); - uip_process(UIP_UDP_SEND_CONN); //generate udp + ip headers - uip_arp_out(); //add arp - if (uip_len == UIP_ARPHDRSIZE) - { - UIPEthernet.packetstate &= ~UIPETHERNET_SENDPACKET; -#ifdef UIPETHERNET_DEBUG_UDP - Serial.println(F("udp, uip_poll results in ARP-packet")); -#endif - } - else - //arp found ethaddr for ip (otherwise packet is replaced by arp-request) - { - data->send = false; -#ifdef UIPETHERNET_DEBUG_UDP - Serial.print(F("udp, uip_packet to send: ")); - Serial.println(UIPEthernet.uip_packet); -#endif - } - } - } -} -#endif diff --git a/libraries/UIPEthernet/src/UIPUdp.h b/libraries/UIPEthernet/src/UIPUdp.h deleted file mode 100644 index c965ffa..0000000 --- a/libraries/UIPEthernet/src/UIPUdp.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - UIPUdp.h - Arduino implementation of a uIP wrapper class. - Copyright (c) 2013 Norbert Truchsess - All rights reserved. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - */ - -#ifndef UIPUDP_H -#define UIPUDP_H - -#include "ethernet_comp.h" -#include "Arduino.h" -#include -#include "utility/mempool.h" -extern "C" { - #include "utility/uip.h"; -} - -#define UIP_UDP_MAXDATALEN 1500 -#define UIP_UDP_PHYH_LEN UIP_LLH_LEN+UIP_IPUDPH_LEN -#define UIP_UDP_MAXPACKETSIZE UIP_UDP_MAXDATALEN+UIP_UDP_PHYH_LEN -#ifndef UIP_UDP_NUMPACKETS -#define UIP_UDP_NUMPACKETS 5 -#endif - -class UIPUDP : public UDP -{ - -private: - struct uip_udp_conn *_uip_udp_conn; - - struct appdata_t - { - memaddress out_pos; - memhandle packets_in[UIP_UDP_NUMPACKETS]; - memhandle packet_in; - memhandle packet_out; - boolean send; - } appdata; - -public: - UIPUDP(); // Constructor - uint8_t - begin(uint16_t);// initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use - void - stop(); // Finish with the UDP socket - - // Sending UDP packets - - // Start building up a packet to send to the remote host specific in ip and port - // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port - int - beginPacket(IPAddress ip, uint16_t port); - // Start building up a packet to send to the remote host specific in host and port - // Returns 1 if successful, 0 if there was a problem resolving the hostname or port - int - beginPacket(const char *host, uint16_t port); - // Finish off this packet and send it - // Returns 1 if the packet was sent successfully, 0 if there was an error - int - endPacket(); - // Write a single byte into the packet - size_t - write(uint8_t); - // Write size bytes from buffer into the packet - size_t - write(const uint8_t *buffer, size_t size); - - using Print::write; - - // Start processing the next available incoming packet - // Returns the size of the packet in bytes, or 0 if no packets are available - int - parsePacket(); - // Number of bytes remaining in the current packet - int - available(); - // Read a single byte from the current packet - int - read(); - // Read up to len bytes from the current packet and place them into buffer - // Returns the number of bytes read, or 0 if none are available - int - read(unsigned char* buffer, size_t len); - // Read up to len characters from the current packet and place them into buffer - // Returns the number of characters read, or 0 if none are available - int - read(char* buffer, size_t len) - { - return read((unsigned char*) buffer, len); - } - ; - // Return the next byte from the current packet without moving on to the next byte - int - peek(); - void - flush(); // Finish reading the current packet - - // Return the IP address of the host who sent the current incoming packet - IPAddress - remoteIP(); - - // Return the port of the host who sent the current incoming packet - uint16_t - remotePort(); - -private: - - friend void uipudp_appcall(void); - - static void uip_callback(); -}; - -#endif diff --git a/libraries/UIPEthernet/src/ethernet_comp.h b/libraries/UIPEthernet/src/ethernet_comp.h deleted file mode 100644 index 4cec2ab..0000000 --- a/libraries/UIPEthernet/src/ethernet_comp.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef ETHERNET_COMP_H -#define ETHERNET_COMP_H - -#define Ethernet UIPEthernet -#define EthernetClient UIPClient -#define EthernetServer UIPServer -#define EthernetUDP UIPUDP - -#endif diff --git a/libraries/UIPEthernet/src/utility/Enc28J60Network.h b/libraries/UIPEthernet/src/utility/Enc28J60Network.h deleted file mode 100644 index 461ec59..0000000 --- a/libraries/UIPEthernet/src/utility/Enc28J60Network.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - Enc28J60Network.h - UIPEthernet network driver for Microchip ENC28J60 Ethernet Interface. - - Copyright (c) 2013 Norbert Truchsess - All rights reserved. - - inspired by enc28j60.c file from the AVRlib library by Pascal Stang. - For AVRlib See http://www.procyonengineering.com/ - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - */ - -#ifndef ENC28J60NETWORK_H_ -#define ENC28J60NETWORK_H_ - -#include "mempool.h" - -#define ENC28J60_CONTROL_CS SS // this is pin 10 on Uno and pin 53 on Mega256 - -#if defined(ARDUINO_ARCH_AVR) -// AVR-specific code -#define SPI_MOSI MOSI -#define SPI_MISO MISO -#define SPI_SCK SCK -#define SPI_SS SS -#define ENC28J60_USE_SPILIB 0 -#elif defined(ARDUINO_ARCH_SAM) -#define ENC28J60_USE_SPILIB 1 -#endif - -#define UIP_RECEIVEBUFFERHANDLE 0xff - -//#define ENC28J60DEBUG - -/* - * Empfangen von ip-header, arp etc... - * wenn tcp/udp -> tcp/udp-callback -> assign new packet to connection - */ - -class Enc28J60Network : public MemoryPool -{ - -private: - uint16_t nextPacketPtr; - uint8_t bank; - - struct memblock receivePkt; - - uint8_t readOp(uint8_t op, uint8_t address); - void writeOp(uint8_t op, uint8_t address, uint8_t data); - uint16_t setReadPtr(memhandle handle, memaddress position, uint16_t len); - void setERXRDPT(); - void readBuffer(uint16_t len, uint8_t* data); - void writeBuffer(uint16_t len, uint8_t* data); - uint8_t readByte(uint16_t addr); - void writeByte(uint16_t addr, uint8_t data); - void setBank(uint8_t address); - uint8_t readReg(uint8_t address); - void writeReg(uint8_t address, uint8_t data); - void writeRegPair(uint8_t address, uint16_t data); - void phyWrite(uint8_t address, uint16_t data); - void clkout(uint8_t clk); - uint8_t getrev(void); - -protected: - void memblock_mv_cb(memaddress dest, memaddress src, memaddress size); - -public: - Enc28J60Network(); - void init(uint8_t* macaddr); - memhandle receivePacket(); - void freePacket(); - memaddress blockSize(memhandle handle); - void sendPacket(memhandle handle); - uint16_t readPacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len); - uint16_t writePacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len); - void copyPacket(memhandle dest, memaddress dest_pos, memhandle src, memaddress src_pos, uint16_t len); - uint16_t chksum(uint16_t sum, memhandle handle, memaddress pos, uint16_t len); -}; - -#endif /* ENC28J60NETWORK_H_ */ diff --git a/libraries/UIPEthernet/src/utility/mempool_conf.h b/libraries/UIPEthernet/src/utility/mempool_conf.h deleted file mode 100644 index bd5a726..0000000 --- a/libraries/UIPEthernet/src/utility/mempool_conf.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef MEMPOOLCONF_H -#define MEMPOOLCONF_H -#include "uipethernet-conf.h" -extern "C" { - #include "uipopt.h" -} -#include - -typedef uint16_t memaddress; -typedef uint8_t memhandle; - -#if UIP_SOCKET_NUMPACKETS and UIP_CONNS -#define NUM_TCP_MEMBLOCKS (UIP_SOCKET_NUMPACKETS*2)*UIP_CONNS -#else -#define NUM_TCP_MEMBLOCKS 0 -#endif - -#if UIP_UDP and UIP_UDP_NUMPACKETS and UIP_UDP_CONNS -#define NUM_UDP_MEMBLOCKS (UIP_UDP_NUMPACKETS+1)*UIP_UDP_CONNS -#else -#define NUM_UDP_MEMBLOCKS 0 -#endif - -#define NUM_MEMBLOCKS (NUM_TCP_MEMBLOCKS+NUM_UDP_MEMBLOCKS) - -#define MEMBLOCK_MV - -#endif diff --git a/libraries/UIPEthernet/src/utility/uip-neighbor.c b/libraries/UIPEthernet/src/utility/uip-neighbor.c deleted file mode 100644 index 739c03e..0000000 --- a/libraries/UIPEthernet/src/utility/uip-neighbor.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack - * - * $Id: uip-neighbor.c,v 1.2 2006/06/12 08:00:30 adam Exp $ - */ - -/** - * \file - * Database of link-local neighbors, used by IPv6 code and - * to be used by a future ARP code rewrite. - * \author - * Adam Dunkels - */ - -#include "uip-neighbor.h" - -#include - -#define MAX_TIME 128 - -#ifdef UIP_NEIGHBOR_CONF_ENTRIES -#define ENTRIES UIP_NEIGHBOR_CONF_ENTRIES -#else /* UIP_NEIGHBOR_CONF_ENTRIES */ -#define ENTRIES 8 -#endif /* UIP_NEIGHBOR_CONF_ENTRIES */ - -struct neighbor_entry { - uip_ipaddr_t ipaddr; - struct uip_neighbor_addr addr; - u8_t time; -}; -static struct neighbor_entry entries[ENTRIES]; - -/*---------------------------------------------------------------------------*/ -void -uip_neighbor_init(void) -{ - int i; - - for(i = 0; i < ENTRIES; ++i) { - entries[i].time = MAX_TIME; - } -} -/*---------------------------------------------------------------------------*/ -void -uip_neighbor_periodic(void) -{ - int i; - - for(i = 0; i < ENTRIES; ++i) { - if(entries[i].time < MAX_TIME) { - entries[i].time++; - } - } -} -/*---------------------------------------------------------------------------*/ -void -uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr) -{ - int i, oldest; - u8_t oldest_time; - - printf("Adding neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n", - addr->addr.addr[0], addr->addr.addr[1], addr->addr.addr[2], addr->addr.addr[3], - addr->addr.addr[4], addr->addr.addr[5]); - - /* Find the first unused entry or the oldest used entry. */ - oldest_time = 0; - oldest = 0; - for(i = 0; i < ENTRIES; ++i) { - if(entries[i].time == MAX_TIME) { - oldest = i; - break; - } - if(uip_ipaddr_cmp(entries[i].ipaddr, addr)) { - oldest = i; - break; - } - if(entries[i].time > oldest_time) { - oldest = i; - oldest_time = entries[i].time; - } - } - - /* Use the oldest or first free entry (either pointed to by the - "oldest" variable). */ - entries[oldest].time = 0; - uip_ipaddr_copy(entries[oldest].ipaddr, ipaddr); - memcpy(&entries[oldest].addr, addr, sizeof(struct uip_neighbor_addr)); -} -/*---------------------------------------------------------------------------*/ -static struct neighbor_entry * -find_entry(uip_ipaddr_t ipaddr) -{ - int i; - - for(i = 0; i < ENTRIES; ++i) { - if(uip_ipaddr_cmp(entries[i].ipaddr, ipaddr)) { - return &entries[i]; - } - } - return NULL; -} -/*---------------------------------------------------------------------------*/ -void -uip_neighbor_update(uip_ipaddr_t ipaddr) -{ - struct neighbor_entry *e; - - e = find_entry(ipaddr); - if(e != NULL) { - e->time = 0; - } -} -/*---------------------------------------------------------------------------*/ -struct uip_neighbor_addr * -uip_neighbor_lookup(uip_ipaddr_t ipaddr) -{ - struct neighbor_entry *e; - - e = find_entry(ipaddr); - if(e != NULL) { - /* printf("Lookup neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n", - e->addr.addr.addr[0], e->addr.addr.addr[1], e->addr.addr.addr[2], e->addr.addr.addr[3], - e->addr.addr.addr[4], e->addr.addr.addr[5]);*/ - - return &e->addr; - } - return NULL; -} -/*---------------------------------------------------------------------------*/ diff --git a/libraries/UIPEthernet/src/utility/uip-neighbor.h b/libraries/UIPEthernet/src/utility/uip-neighbor.h deleted file mode 100644 index d3b351c..0000000 --- a/libraries/UIPEthernet/src/utility/uip-neighbor.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the uIP TCP/IP stack - * - * $Id: uip-neighbor.h,v 1.2 2006/06/12 08:00:30 adam Exp $ - */ - -/** - * \file - * Header file for database of link-local neighbors, used by - * IPv6 code and to be used by future ARP code. - * \author - * Adam Dunkels - */ - -#ifndef __UIP_NEIGHBOR_H__ -#define __UIP_NEIGHBOR_H__ - -#include "uip.h" - -struct uip_neighbor_addr { -#if UIP_NEIGHBOR_CONF_ADDRTYPE - UIP_NEIGHBOR_CONF_ADDRTYPE addr; -#else - struct uip_eth_addr addr; -#endif -}; - -void uip_neighbor_init(void); -void uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr); -void uip_neighbor_update(uip_ipaddr_t ipaddr); -struct uip_neighbor_addr *uip_neighbor_lookup(uip_ipaddr_t ipaddr); -void uip_neighbor_periodic(void); - -#endif /* __UIP-NEIGHBOR_H__ */ diff --git a/libraries/UIPEthernet/src/utility/uipethernet-conf.h b/libraries/UIPEthernet/src/utility/uipethernet-conf.h deleted file mode 100644 index 733e26e..0000000 --- a/libraries/UIPEthernet/src/utility/uipethernet-conf.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef UIPETHERNET_CONF_H -#define UIPETHERNET_CONF_H - -/* for TCP */ -#define UIP_SOCKET_NUMPACKETS 5 -#define UIP_CONF_MAX_CONNECTIONS 4 - -/* for UDP */ -#define UIP_CONF_UDP 0//1 -#define UIP_CONF_BROADCAST 0//1 -#define UIP_CONF_UDP_CONNS 0//4 -#define UIP_UDP_NUMPACKETS 0//5 - -/* number of attempts on write before returning number of bytes sent so far - * set to -1 to block until connection is closed by timeout */ -#define UIP_ATTEMPTS_ON_WRITE -1 - -#endif diff --git a/libraries/UIPEthernet/src/utility/Enc28J60Network.cpp b/libraries/UIPEthernet/utility/Enc28J60Network.cpp similarity index 80% rename from libraries/UIPEthernet/src/utility/Enc28J60Network.cpp rename to libraries/UIPEthernet/utility/Enc28J60Network.cpp index 2670a6f..fbef88d 100644 --- a/libraries/UIPEthernet/src/utility/Enc28J60Network.cpp +++ b/libraries/UIPEthernet/utility/Enc28J60Network.cpp @@ -1,5 +1,5 @@ /* - Enc28J60Network.h + Enc28J60NetworkClass.h UIPEthernet network driver for Microchip ENC28J60 Ethernet Interface. Copyright (c) 2013 Norbert Truchsess @@ -25,19 +25,8 @@ #include "Enc28J60Network.h" #include "Arduino.h" -#if ENC28J60_USE_SPILIB -#include -#endif - extern "C" { - #if defined(ARDUINO_ARCH_AVR) - // AVR-specific code - #include - #elif defined(ARDUINO_ARCH_SAM) - // SAM-specific code - #else - // generic, non-platform specific code - #endif +#include #include "enc28j60.h" #include "uip.h" } @@ -51,57 +40,40 @@ extern "C" { // set CS to 1 = passive #define CSPASSIVE digitalWrite(ENC28J60_CONTROL_CS, HIGH) // -#if defined(ARDUINO_ARCH_AVR) #define waitspi() while(!(SPSR&(1<begin+dest_pos,src->begin+src_pos,len); + enc28J60_mempool_block_move_callback(dest->begin+dest_pos,src->begin+src_pos,len); // Move the RX read pointer to the start of the next received packet // This frees the memory we just read out setERXRDPT(); } void -Enc28J60Network::memblock_mv_cb(uint16_t dest, uint16_t src, uint16_t len) +enc28J60_mempool_block_move_callback(memaddress dest, memaddress src, memaddress len) { +//void +//Enc28J60Network::memblock_mv_cb(uint16_t dest, uint16_t src, uint16_t len) +//{ //as ENC28J60 DMA is unable to copy single bytes: if (len == 1) { - writeByte(dest,readByte(src)); + Enc28J60Network::writeByte(dest,Enc28J60Network::readByte(src)); } else { @@ -390,11 +349,11 @@ Enc28J60Network::memblock_mv_cb(uint16_t dest, uint16_t src, uint16_t len) prevent a never ending DMA operation which would overwrite the entire 8-Kbyte buffer. */ - writeRegPair(EDMASTL, src); - writeRegPair(EDMADSTL, dest); + Enc28J60Network::writeRegPair(EDMASTL, src); + Enc28J60Network::writeRegPair(EDMADSTL, dest); if ((src <= RXSTOP_INIT)&& (len > RXSTOP_INIT))len -= (RXSTOP_INIT-RXSTART_INIT); - writeRegPair(EDMANDL, len); + Enc28J60Network::writeRegPair(EDMANDL, len); /* 2. If an interrupt at the end of the copy process is @@ -402,13 +361,13 @@ Enc28J60Network::memblock_mv_cb(uint16_t dest, uint16_t src, uint16_t len) clear EIR.DMAIF. 3. Verify that ECON1.CSUMEN is clear. */ - writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_CSUMEN); + Enc28J60Network::writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_CSUMEN); /* 4. Start the DMA copy by setting ECON1.DMAST. */ - writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST); + Enc28J60Network::writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST); // wait until runnig DMA is completed - while (readOp(ENC28J60_READ_CTRL_REG, ECON1) & ECON1_DMAST); + while (Enc28J60Network::readOp(ENC28J60_READ_CTRL_REG, ECON1) & ECON1_DMAST); } } @@ -423,20 +382,6 @@ Enc28J60Network::readOp(uint8_t op, uint8_t address) { CSACTIVE; // issue read command -#if ENC28J60_USE_SPILIB - SPI.transfer(op | (address & ADDR_MASK)); - // read data - if(address & 0x80) - { - // do dummy read if needed (for mac and mii, see datasheet page 29) - SPI.transfer(0x00); - } - uint8_t c = SPI.transfer(0x00); - // release CS - CSPASSIVE; - return(c); -#else - // issue read command SPDR = op | (address & ADDR_MASK); waitspi(); // read data @@ -451,7 +396,6 @@ Enc28J60Network::readOp(uint8_t op, uint8_t address) // release CS CSPASSIVE; return(SPDR); -#endif } void @@ -459,18 +403,11 @@ Enc28J60Network::writeOp(uint8_t op, uint8_t address, uint8_t data) { CSACTIVE; // issue write command -#if ENC28J60_USE_SPILIB - SPI.transfer(op | (address & ADDR_MASK)); - // write data - SPI.transfer(data); -#else - // issue write command SPDR = op | (address & ADDR_MASK); waitspi(); // write data SPDR = data; waitspi(); -#endif CSPASSIVE; } @@ -479,23 +416,15 @@ Enc28J60Network::readBuffer(uint16_t len, uint8_t* data) { CSACTIVE; // issue read command -#if ENC28J60_USE_SPILIB - SPI.transfer(ENC28J60_READ_BUF_MEM); -#else SPDR = ENC28J60_READ_BUF_MEM; waitspi(); -#endif while(len) { len--; // read data -#if ENC28J60_USE_SPILIB - *data = SPI.transfer(0x00); -#else SPDR = 0x00; waitspi(); *data = SPDR; -#endif data++; } //*data='\0'; @@ -507,24 +436,15 @@ Enc28J60Network::writeBuffer(uint16_t len, uint8_t* data) { CSACTIVE; // issue write command -#if ENC28J60_USE_SPILIB - SPI.transfer(ENC28J60_WRITE_BUF_MEM); -#else SPDR = ENC28J60_WRITE_BUF_MEM; waitspi(); -#endif while(len) { len--; // write data -#if ENC28J60_USE_SPILIB - SPI.transfer(*data); - data++; -#else SPDR = *data; data++; waitspi(); -#endif } CSPASSIVE; } @@ -583,6 +503,19 @@ Enc28J60Network::phyWrite(uint8_t address, uint16_t data) } } +uint16_t +Enc28J60Network::phyRead(uint8_t address) +{ + writeReg(MIREGADR,address); + writeReg(MICMD, MICMD_MIIRD); + // wait until the PHY read completes + while(readReg(MISTAT) & MISTAT_BUSY){ + delayMicroseconds(15); + } //and MIRDH + writeReg(MICMD, 0); + return (readReg(MIRDL) | readReg(MIRDH) << 8); +} + void Enc28J60Network::clkout(uint8_t clk) { @@ -604,40 +537,27 @@ Enc28J60Network::chksum(uint16_t sum, memhandle handle, memaddress pos, uint16_t len = setReadPtr(handle, pos, len)-1; CSACTIVE; // issue read command -#if ENC28J60_USE_SPILIB - SPI.transfer(ENC28J60_READ_BUF_MEM); -#else SPDR = ENC28J60_READ_BUF_MEM; waitspi(); -#endif uint16_t i; for (i = 0; i < len; i+=2) { // read data -#if ENC28J60_USE_SPILIB - t = SPI.transfer(0x00) << 8; - t += SPI.transfer(0x00); -#else SPDR = 0x00; waitspi(); t = SPDR << 8; SPDR = 0x00; waitspi(); t += SPDR; -#endif sum += t; if(sum < t) { sum++; /* carry */ } } if(i == len) { -#if ENC28J60_USE_SPILIB - t = (SPI.transfer(0x00) << 8) + 0; -#else SPDR = 0x00; waitspi(); t = (SPDR << 8) + 0; -#endif sum += t; if(sum < t) { sum++; /* carry */ @@ -648,3 +568,30 @@ Enc28J60Network::chksum(uint16_t sum, memhandle handle, memaddress pos, uint16_t /* Return sum in host byte order. */ return sum; } + +void +Enc28J60Network::powerOff() +{ + writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_RXEN); + delay(50); + writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_VRPS); + delay(50); + writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PWRSV); +} + +void +Enc28J60Network::powerOn() +{ + writeOp(ENC28J60_BIT_FIELD_CLR, ECON2, ECON2_PWRSV); + delay(50); + writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); + delay(50); +} + +bool +Enc28J60Network::linkStatus() +{ + return (phyRead(PHSTAT2) & 0x0400) > 0; +} + +Enc28J60Network Enc28J60; diff --git a/libraries/UIPEthernet/utility/Enc28J60Network.h b/libraries/UIPEthernet/utility/Enc28J60Network.h new file mode 100644 index 0000000..7346e47 --- /dev/null +++ b/libraries/UIPEthernet/utility/Enc28J60Network.h @@ -0,0 +1,91 @@ +/* + Enc28J60NetworkClass.h + UIPEthernet network driver for Microchip ENC28J60 Ethernet Interface. + + Copyright (c) 2013 Norbert Truchsess + All rights reserved. + + inspired by enc28j60.c file from the AVRlib library by Pascal Stang. + For AVRlib See http://www.procyonengineering.com/ + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#ifndef Enc28J60Network_H_ +#define Enc28J60Network_H_ + +#include "mempool.h" + +#define ENC28J60_CONTROL_CS SS +#define SPI_MOSI MOSI +#define SPI_MISO MISO +#define SPI_SCK SCK +#define SPI_SS SS + +#define UIP_RECEIVEBUFFERHANDLE 0xff + +//#define ENC28J60DEBUG + +/* + * Empfangen von ip-header, arp etc... + * wenn tcp/udp -> tcp/udp-callback -> assign new packet to connection + */ + +class Enc28J60Network : public MemoryPool +{ + +private: + static uint16_t nextPacketPtr; + static uint8_t bank; + + static struct memblock receivePkt; + + static uint8_t readOp(uint8_t op, uint8_t address); + static void writeOp(uint8_t op, uint8_t address, uint8_t data); + static uint16_t setReadPtr(memhandle handle, memaddress position, uint16_t len); + static void setERXRDPT(); + static void readBuffer(uint16_t len, uint8_t* data); + static void writeBuffer(uint16_t len, uint8_t* data); + static uint8_t readByte(uint16_t addr); + static void writeByte(uint16_t addr, uint8_t data); + static void setBank(uint8_t address); + static uint8_t readReg(uint8_t address); + static void writeReg(uint8_t address, uint8_t data); + static void writeRegPair(uint8_t address, uint16_t data); + static void phyWrite(uint8_t address, uint16_t data); + static uint16_t phyRead(uint8_t address); + static void clkout(uint8_t clk); + + friend void enc28J60_mempool_block_move_callback(memaddress,memaddress,memaddress); + +public: + + uint8_t getrev(void); + void powerOn(); + void powerOff(); + bool linkStatus(); + + static void init(uint8_t* macaddr); + static memhandle receivePacket(); + static void freePacket(); + static memaddress blockSize(memhandle handle); + static void sendPacket(memhandle handle); + static uint16_t readPacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len); + static uint16_t writePacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len); + static void copyPacket(memhandle dest, memaddress dest_pos, memhandle src, memaddress src_pos, uint16_t len); + static uint16_t chksum(uint16_t sum, memhandle handle, memaddress pos, uint16_t len); +}; + +extern Enc28J60Network Enc28J60; +#endif /* Enc28J60NetworkClass_H_ */ diff --git a/libraries/UIPEthernet/src/utility/clock-arch.c b/libraries/UIPEthernet/utility/clock-arch.c similarity index 100% rename from libraries/UIPEthernet/src/utility/clock-arch.c rename to libraries/UIPEthernet/utility/clock-arch.c diff --git a/libraries/UIPEthernet/src/utility/clock-arch.h b/libraries/UIPEthernet/utility/clock-arch.h similarity index 100% rename from libraries/UIPEthernet/src/utility/clock-arch.h rename to libraries/UIPEthernet/utility/clock-arch.h diff --git a/libraries/UIPEthernet/src/utility/enc28j60.h b/libraries/UIPEthernet/utility/enc28j60.h similarity index 100% rename from libraries/UIPEthernet/src/utility/enc28j60.h rename to libraries/UIPEthernet/utility/enc28j60.h diff --git a/libraries/UIPEthernet/src/utility/mempool.cpp b/libraries/UIPEthernet/utility/mempool.cpp similarity index 86% rename from libraries/UIPEthernet/src/utility/mempool.cpp rename to libraries/UIPEthernet/utility/mempool.cpp index 01f17fb..c2f7abf 100644 --- a/libraries/UIPEthernet/src/utility/mempool.cpp +++ b/libraries/UIPEthernet/utility/mempool.cpp @@ -22,13 +22,15 @@ #define POOLOFFSET 1 -MemoryPool::MemoryPool(memaddress start, memaddress size) +struct memblock MemoryPool::blocks[MEMPOOL_NUM_MEMBLOCKS+1]; + +void +MemoryPool::init() { memset(&blocks[0], 0, sizeof(blocks)); - blocks[POOLSTART].begin = start; + blocks[POOLSTART].begin = MEMPOOL_STARTADDRESS; blocks[POOLSTART].size = 0; blocks[POOLSTART].nextblock = NOBLOCK; - poolsize = size; } memhandle @@ -37,12 +39,12 @@ MemoryPool::allocBlock(memaddress size) memblock* best = NULL; memhandle cur = POOLSTART; memblock* block = &blocks[POOLSTART]; - memaddress bestsize = poolsize + 1; + memaddress bestsize = MEMPOOL_SIZE + 1; do { memhandle next = block->nextblock; - memaddress freesize = ( next == NOBLOCK ? blocks[POOLSTART].begin + poolsize : blocks[next].begin) - block->begin - block->size; + memaddress freesize = ( next == NOBLOCK ? blocks[POOLSTART].begin + MEMPOOL_SIZE : blocks[next].begin) - block->begin - block->size; if (freesize == size) { best = &blocks[cur]; @@ -77,14 +79,14 @@ MemoryPool::allocBlock(memaddress size) memaddress* src = &nextblock->begin; if (dest != *src) { -#ifdef MEMBLOCK_MV - memblock_mv_cb(dest,*src,nextblock->size); +#ifdef MEMPOOL_MEMBLOCK_MV + MEMPOOL_MEMBLOCK_MV(dest,*src,nextblock->size); #endif *src = dest; } block = nextblock; } - if (blocks[POOLSTART].begin + poolsize - block->begin - block->size >= size) + if (blocks[POOLSTART].begin + MEMPOOL_SIZE - block->begin - block->size >= size) best = block; else goto notfound; @@ -93,7 +95,7 @@ MemoryPool::allocBlock(memaddress size) found: { block = &blocks[POOLOFFSET]; - for (cur = POOLOFFSET; cur < NUM_MEMBLOCKS + POOLOFFSET; cur++) + for (cur = POOLOFFSET; cur < MEMPOOL_NUM_MEMBLOCKS + POOLOFFSET; cur++) { if (block->size) { @@ -118,6 +120,8 @@ MemoryPool::allocBlock(memaddress size) void MemoryPool::freeBlock(memhandle handle) { + if (handle == NOBLOCK) + return; memblock *b = &blocks[POOLSTART]; do diff --git a/libraries/UIPEthernet/src/utility/mempool.h b/libraries/UIPEthernet/utility/mempool.h similarity index 59% rename from libraries/UIPEthernet/src/utility/mempool.h rename to libraries/UIPEthernet/utility/mempool.h index ea79473..2a1db21 100644 --- a/libraries/UIPEthernet/src/utility/mempool.h +++ b/libraries/UIPEthernet/utility/mempool.h @@ -27,18 +27,6 @@ #include "mempool_conf.h" -//#ifdef MEMBLOCK_MV -//#define memblock_mv_cb(dest,src,size) MEMBLOCK_MV(dest,src,size) -//#endif - -#ifdef MEMBLOCK_ALLOC -#define memblock_alloc_cb(address,size) MEMBLOCK_ALLOC(address,size) -#endif - -#ifdef MEMBLOCK_FREE -#define memblock_free_cb(address,size) MEMBLOCK_FREE(address,size) -#endif - struct memblock { memaddress begin; @@ -53,19 +41,14 @@ class MemoryPool #endif protected: - memaddress poolsize; - struct memblock blocks[NUM_MEMBLOCKS+1]; -#ifdef MEMBLOCK_MV - virtual void memblock_mv_cb(memaddress dest, memaddress src, memaddress size) = 0; -#endif + static struct memblock blocks[MEMPOOL_NUM_MEMBLOCKS+1]; public: - MemoryPool(memaddress start, memaddress size); - memhandle - allocBlock(memaddress); - void freeBlock(memhandle); - void resizeBlock(memhandle handle, memaddress position); - void resizeBlock(memhandle handle, memaddress position, memaddress size); - memaddress blockSize(memhandle); + static void init(); + static memhandle allocBlock(memaddress); + static void freeBlock(memhandle); + static void resizeBlock(memhandle handle, memaddress position); + static void resizeBlock(memhandle handle, memaddress position, memaddress size); + static memaddress blockSize(memhandle); }; #endif diff --git a/libraries/UIPEthernet/utility/mempool_conf.h b/libraries/UIPEthernet/utility/mempool_conf.h new file mode 100644 index 0000000..9615f92 --- /dev/null +++ b/libraries/UIPEthernet/utility/mempool_conf.h @@ -0,0 +1,34 @@ +#ifndef MEMPOOLCONF_H +#define MEMPOOLCONF_H +#include "uipethernet-conf.h" +extern "C" { + #include "uipopt.h" + #include "enc28j60.h" +} +#include + +typedef uint16_t memaddress; +typedef uint8_t memhandle; + +#if UIP_SOCKET_NUMPACKETS and UIP_CONNS +#define NUM_TCP_MEMBLOCKS (UIP_SOCKET_NUMPACKETS*2)*UIP_CONNS +#else +#define NUM_TCP_MEMBLOCKS 0 +#endif + +#if UIP_UDP and UIP_UDP_CONNS +#define NUM_UDP_MEMBLOCKS 3*UIP_UDP_CONNS +#else +#define NUM_UDP_MEMBLOCKS 0 +#endif + +#define MEMPOOL_NUM_MEMBLOCKS (NUM_TCP_MEMBLOCKS+NUM_UDP_MEMBLOCKS) + +#define MEMPOOL_STARTADDRESS TXSTART_INIT+1 +#define MEMPOOL_SIZE TXSTOP_INIT-TXSTART_INIT + +void enc28J60_mempool_block_move_callback(memaddress,memaddress,memaddress); + +#define MEMPOOL_MEMBLOCK_MV(dest,src,size) enc28J60_mempool_block_move_callback(dest,src,size) + +#endif diff --git a/libraries/UIPEthernet/src/utility/uip-conf.h b/libraries/UIPEthernet/utility/uip-conf.h similarity index 100% rename from libraries/UIPEthernet/src/utility/uip-conf.h rename to libraries/UIPEthernet/utility/uip-conf.h diff --git a/libraries/UIPEthernet/src/utility/uip.c b/libraries/UIPEthernet/utility/uip.c similarity index 100% rename from libraries/UIPEthernet/src/utility/uip.c rename to libraries/UIPEthernet/utility/uip.c diff --git a/libraries/UIPEthernet/src/utility/uip.h b/libraries/UIPEthernet/utility/uip.h similarity index 100% rename from libraries/UIPEthernet/src/utility/uip.h rename to libraries/UIPEthernet/utility/uip.h diff --git a/libraries/UIPEthernet/src/utility/uip_arch.h b/libraries/UIPEthernet/utility/uip_arch.h similarity index 100% rename from libraries/UIPEthernet/src/utility/uip_arch.h rename to libraries/UIPEthernet/utility/uip_arch.h diff --git a/libraries/UIPEthernet/src/utility/uip_arp.c b/libraries/UIPEthernet/utility/uip_arp.c similarity index 100% rename from libraries/UIPEthernet/src/utility/uip_arp.c rename to libraries/UIPEthernet/utility/uip_arp.c diff --git a/libraries/UIPEthernet/src/utility/uip_arp.h b/libraries/UIPEthernet/utility/uip_arp.h similarity index 100% rename from libraries/UIPEthernet/src/utility/uip_arp.h rename to libraries/UIPEthernet/utility/uip_arp.h diff --git a/libraries/UIPEthernet/src/utility/uip_clock.h b/libraries/UIPEthernet/utility/uip_clock.h similarity index 100% rename from libraries/UIPEthernet/src/utility/uip_clock.h rename to libraries/UIPEthernet/utility/uip_clock.h diff --git a/libraries/UIPEthernet/src/utility/uip_debug.cpp b/libraries/UIPEthernet/utility/uip_debug.cpp similarity index 100% rename from libraries/UIPEthernet/src/utility/uip_debug.cpp rename to libraries/UIPEthernet/utility/uip_debug.cpp diff --git a/libraries/UIPEthernet/src/utility/uip_debug.h b/libraries/UIPEthernet/utility/uip_debug.h similarity index 100% rename from libraries/UIPEthernet/src/utility/uip_debug.h rename to libraries/UIPEthernet/utility/uip_debug.h diff --git a/libraries/UIPEthernet/src/utility/uip_timer.c b/libraries/UIPEthernet/utility/uip_timer.c similarity index 100% rename from libraries/UIPEthernet/src/utility/uip_timer.c rename to libraries/UIPEthernet/utility/uip_timer.c diff --git a/libraries/UIPEthernet/src/utility/uip_timer.h b/libraries/UIPEthernet/utility/uip_timer.h similarity index 100% rename from libraries/UIPEthernet/src/utility/uip_timer.h rename to libraries/UIPEthernet/utility/uip_timer.h diff --git a/libraries/UIPEthernet/utility/uipethernet-conf.h b/libraries/UIPEthernet/utility/uipethernet-conf.h new file mode 100644 index 0000000..016e0e3 --- /dev/null +++ b/libraries/UIPEthernet/utility/uipethernet-conf.h @@ -0,0 +1,21 @@ +#ifndef UIPETHERNET_CONF_H +#define UIPETHERNET_CONF_H + +/* for TCP */ +#define UIP_SOCKET_NUMPACKETS 5 +#define UIP_CONF_MAX_CONNECTIONS 4 + +/* for UDP */ +#define UIP_CONF_UDP 0 +#define UIP_CONF_BROADCAST 1 +#define UIP_CONF_UDP_CONNS 4 + +/* number of attempts on write before returning number of bytes sent so far + * set to -1 to block until connection is closed by timeout */ +#define UIP_ATTEMPTS_ON_WRITE -1 + +/* timeout after which UIPClient::connect gives up. The timeout is specified in seconds. + * if set to a number <= 0 connect will timeout when uIP does (which might be longer than you expect...) */ +#define UIP_CONNECT_TIMEOUT -1 + +#endif diff --git a/libraries/UIPEthernet/src/utility/uipopt.h b/libraries/UIPEthernet/utility/uipopt.h similarity index 100% rename from libraries/UIPEthernet/src/utility/uipopt.h rename to libraries/UIPEthernet/utility/uipopt.h diff --git a/libraries/UIPEthernet/src/utility/util.h b/libraries/UIPEthernet/utility/util.h similarity index 100% rename from libraries/UIPEthernet/src/utility/util.h rename to libraries/UIPEthernet/utility/util.h