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

Dependents:   mBuino_ENC28_MQTT Nucleo_Web_ENC28J60 Nucleo_Web_ENC28J60_ADC Serial_over_Ethernet ... more

Library for ENC28J60 Ethernet modules.

/media/uploads/hudakz/enc28j60_module01.jpg

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

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

Usage:

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

Example programs:

Import programWebSwitch_ENC28J60

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

Import programHTTPServer_Echo_ENC28J60

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

Import programTcpServer_ENC28J60

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

Import programTcpClient_ENC28J60

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

Import programUdpServer_ENC28J60

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

Import programUdpClient_ENC28J60

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

Import programMQTT_Hello_ENC28J60

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

Files at this revision

API Documentation at this revision

Comitter:
hudakz
Date:
Sun Mar 08 20:26:56 2015 +0000
Parent:
3:5b17e4656dd0
Child:
5:59a504be7998
Commit message:
Version 1.09 (fixed leaking client-data caused by race-condition on remote close)

Changed in this revision

Dhcp.cpp Show annotated file Show diff for this revision Revisions of this file
Dns.cpp Show annotated file Show diff for this revision Revisions of this file
Dns.h Show annotated file Show diff for this revision Revisions of this file
Readme.txt Show annotated file Show diff for this revision Revisions of this file
UIPClient.cpp Show annotated file Show diff for this revision Revisions of this file
UIPClient.h Show annotated file Show diff for this revision Revisions of this file
UIPEthernet.cpp Show annotated file Show diff for this revision Revisions of this file
UIPEthernet.h Show annotated file Show diff for this revision Revisions of this file
UIPServer.cpp Show annotated file Show diff for this revision Revisions of this file
UIPServer.h Show annotated file Show diff for this revision Revisions of this file
UIPUdp.cpp Show annotated file Show diff for this revision Revisions of this file
UIPUdp.h Show annotated file Show diff for this revision Revisions of this file
Udp.h Show annotated file Show diff for this revision Revisions of this file
ethernet_comp.h Show annotated file Show diff for this revision Revisions of this file
keywords.txt Show annotated file Show diff for this revision Revisions of this file
utility/Client.h Show annotated file Show diff for this revision Revisions of this file
utility/Enc28J60Network.cpp Show annotated file Show diff for this revision Revisions of this file
utility/Enc28J60Network.h Show annotated file Show diff for this revision Revisions of this file
utility/Server.h Show annotated file Show diff for this revision Revisions of this file
utility/Udp.h Show diff for this revision Revisions of this file
utility/clock-arch.c Show annotated file Show diff for this revision Revisions of this file
utility/enc28j60.h Show annotated file Show diff for this revision Revisions of this file
utility/mempool.cpp Show annotated file Show diff for this revision Revisions of this file
utility/mempool.h Show annotated file Show diff for this revision Revisions of this file
utility/mempool_conf.h Show annotated file Show diff for this revision Revisions of this file
utility/millis.cpp Show annotated file Show diff for this revision Revisions of this file
utility/millis.h Show annotated file Show diff for this revision Revisions of this file
utility/uip-conf.h Show annotated file Show diff for this revision Revisions of this file
utility/uip-neighbor.c Show diff for this revision Revisions of this file
utility/uip-neighbor.h Show diff for this revision Revisions of this file
utility/uip.c Show annotated file Show diff for this revision Revisions of this file
utility/uip.h Show annotated file Show diff for this revision Revisions of this file
utility/uip_clock.cpp Show diff for this revision Revisions of this file
utility/uip_debug.h Show annotated file Show diff for this revision Revisions of this file
utility/uipethernet-conf.h Show annotated file Show diff for this revision Revisions of this file
utility/util.h Show annotated file Show diff for this revision Revisions of this file
--- a/Dhcp.cpp	Sat Dec 20 11:10:40 2014 +0000
+++ b/Dhcp.cpp	Sun Mar 08 20:26:56 2015 +0000
@@ -3,8 +3,8 @@
 #include <string.h>
 #include <stdlib.h>
 #include "Dhcp.h"
-#include  "utility/util.h"
-#include  "utility/uip_clock.h"
+#include "utility/util.h"
+#include "utility/millis.h"
 
 /**
  * @brief
@@ -62,19 +62,19 @@
 
     int             result = 0;
 
-    unsigned long   startTime = clock_time();
+    unsigned long   startTime = millis();
 
     while(_dhcp_state != STATE_DHCP_LEASED) {
         if(_dhcp_state == STATE_DHCP_START) {
             _dhcpTransactionId++;
 
-            send_DHCP_MESSAGE(DHCP_DISCOVER, ((clock_time() - startTime) / 1000));
+            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, ((clock_time() - startTime) / 1000));
+            send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime) / 1000));
             _dhcp_state = STATE_DHCP_REQUEST;
         }
         else
@@ -86,7 +86,7 @@
                 // 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, ((clock_time() - startTime) / 1000));
+                send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime) / 1000));
                 _dhcp_state = STATE_DHCP_REQUEST;
             }
         }
@@ -129,7 +129,7 @@
             _dhcp_state = STATE_DHCP_START;
         }
 
-        if(result != 1 && ((clock_time() - startTime) > _timeout))
+        if(result != 1 && ((millis() - startTime) > _timeout))
             break;
     }
 
@@ -279,14 +279,14 @@
     uint8_t         type = 0;
     uint8_t         opt_len = 0;
 
-    unsigned long   startTime = clock_time();
+    unsigned long   startTime = millis();
 
     while(_dhcpUdpSocket.parsePacket() <= 0) {
-        if((clock_time() - startTime) > responseTimeout) {
+        if((millis() - startTime) > responseTimeout) {
             return 255;
         }
 
-        wait(0.050);
+        wait_ms(50);
     }
 
     // start reading in the packet
@@ -412,7 +412,7 @@
 int DhcpClass::checkLease(void) {
 
     //this uses a signed / unsigned trick to deal with millis overflow
-    unsigned long   now = clock_time();
+    unsigned long   now = millis();
     signed long     snow = (long)now;
     int             rc = DHCP_CHECK_NONE;
     if(_lastCheck != 0) {
--- a/Dns.cpp	Sat Dec 20 11:10:40 2014 +0000
+++ b/Dns.cpp	Sun Mar 08 20:26:56 2015 +0000
@@ -1,15 +1,15 @@
-// mbed DNS client for Enc28J60-based Ethernet shield
+// Arduino DNS client for Enc28J60-based Ethernet shield
 // (c) Copyright 2009-2010 MCQN Ltd.
 // Released under Apache License, version 2.0
-#include  "utility/Udp.h"
-#include  "utility/util.h"
+#include "Udp.h"
+#include "utility/util.h"
+#include "utility/millis.h"
 
 #include "Dns.h"
 #include <string.h>
 //#include <stdlib.h>
 
-#include "mbed.h"
-#include  "utility/uip_clock.h"
+#include <mbed.h>
 
 #define SOCKET_NONE 255
 // Various flags and header field values for a DNS message
@@ -44,11 +44,11 @@
 
 // Possible return codes from ProcessResponse
 
-#define SUCCESS             1
-#define TIMED_OUT           - 1
-#define INVALID_SERVER      - 2
-#define TRUNCATED           - 3
-#define INVALID_RESPONSE    - 4
+#define SUCCESS              1
+#define TIMED_OUT           -1
+#define INVALID_SERVER      -2
+#define TRUNCATED           -3
+#define INVALID_RESPONSE    -4
 
 /**
  * @brief
@@ -56,6 +56,7 @@
  * @param
  * @retval
  */
+
 void DNSClient::begin(const IPAddress& aDNSServer) {
     iDNSServer = aDNSServer;
     iRequestId = 0;
@@ -147,7 +148,7 @@
     }
 
     // Find a socket to use
-    if(iUdp.begin(1024 + (clock_time() & 0xF)) == 1) {
+    if(iUdp.begin(1024 + (millis() & 0xF)) == 1) {
 
         // Try up to three times
         int retries = 0;
@@ -213,7 +214,7 @@
     //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     // As we only support one request at a time at present, we can simplify
     // some of this header
-    iRequestId = clock_time();          // generate a random ID
+    iRequestId = millis();              // generate a random ID
     uint16_t    twoByteBuffer;
 
     // FIXME We should also check that there's enough space available to write to, rather
@@ -285,12 +286,12 @@
  * @retval
  */
 uint16_t DNSClient::ProcessResponse(uint16_t aTimeout, IPAddress& aAddress) {
-    uint32_t    startTime = clock_time();
+    uint32_t    startTime = millis();
 
     // Wait for a response packet
 
     while(iUdp.parsePacket() <= 0) {
-        if((clock_time() - startTime) > aTimeout)
+        if((millis() - startTime) > aTimeout)
             return TIMED_OUT;
         wait(0.050);
     }
@@ -451,4 +452,3 @@
     // If we get here then we haven't found an answer
     return -10; //INVALID_RESPONSE;
 }
-
--- a/Dns.h	Sat Dec 20 11:10:40 2014 +0000
+++ b/Dns.h	Sun Mar 08 20:26:56 2015 +0000
@@ -1,39 +1,41 @@
-// mbed 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 <UIPUdp.h>
-
-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
+// 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 <UIPUdp.h>
+
+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
--- a/Readme.txt	Sat Dec 20 11:10:40 2014 +0000
+++ b/Readme.txt	Sun Mar 08 20:26:56 2015 +0000
@@ -1,7 +1,7 @@
-This is UIPEthernet version 1.07
+This is UIPEthernet version 1.09
 
-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' and create one IUPEthernet object initialized with the SPI pins of your ENC28J60 board.
+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!
 
 UIPEthernet is written as a wrapper around the mature uIP Stack by Adam Dunkels, which provides the low-level implementation for all supported protocols. To overcome the memory-constrains (a 'regular' uIP-application does all processing in RAM) the ENC28J60 internal memory is used for all stream buffers (in and out). Only 400-600 Bytes of Arduinos RAM are used (depending on the number of concurrently open connections). As of Flash-memory a ATmega368-based Arduino is the minimum requirenment.
 
@@ -11,12 +11,28 @@
 
 This library was inspired by the SerialIP implementation by Adam Nielsen <malvineous@shikadi.net>, actually I took this code as a starting point, but in the latest versions there are very few lines left.
 
+This library was ported to mbed by Zoltan Hudak <hudakz@inbox.com>
+
 Installation
 ------------
 
-Import into your project as any other mbed library.
+To install the libraries, you need to place them into your "libraries" folder. You can find it within your Arduino IDE distribution within the "hardware" folder.
+
+    C:\> cd [path to Arduino distribution]\libraries
+    C:\> git clone https://github.com/ntruchsess/arduino_uip UIPEthernet
+
+Be sure to restart the IDE if it was running.
+
+On a Mac, you will want to create a folder named "libraries" in in the "Documents" -> "Arduino" folder within your home directory. Clone the project there (and restart the IDE, if it was running during this process).
 
-Additional information can be found on the mbed website: https://mbed.org/handbook/mbed-Compiler
+    $ 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/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.59 or checkout branch 'Arduino_1.5.x'
+
+Additional information can be found on the Arduino website: http://www.arduino.cc/en/Hacking/Libraries
 
 Documentation
 -------------
@@ -33,6 +49,9 @@
  - uIP API reference:
     http://www.sics.se/~adam/uip/uip-1.0-refman/
 
+ - Arduino forums
+    http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl
+
  - uIP homepage:
     http://www.sics.se/~adam/uip/index.php/Main_Page
 
@@ -41,6 +60,8 @@
 
 UIPEthernet.h
 UIPEthernet.cpp
+UIPUdp.h
+UIPClient.cpp
 
 Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
 All rights reserved.
@@ -50,8 +71,6 @@
 UIPServer.h
 UIPServer.cpp
 UIPClient.h
-UIPClient.cpp
-UIPUdp.h
 UIPUdp.cpp
 utility/mempool.h
 utility/mempool.cpp
@@ -203,8 +222,6 @@
 Copyright (c) 2010 Adam Nielsen <malvineous@shikadi.net>
 All rights reserved.
 
-Modified (ported to mbed) by Zoltan Hudak <hudakz@inbox.com>
-
 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
@@ -243,3 +260,23 @@
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
+--------------
+
+utility/millis.h
+utility/millis.cpp
+
+Copyright (c) 2015 Zoltan Hudak <hudakz@inbox.com>.
+All right 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 <http://www.gnu.org/licenses/>.
--- a/UIPClient.cpp	Sat Dec 20 11:10:40 2014 +0000
+++ b/UIPClient.cpp	Sun Mar 08 20:26:56 2015 +0000
@@ -3,6 +3,8 @@
  Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
  All rights reserved.
 
+ Modified (ported to mbed) by Zoltan Hudak <hudakz@inbox.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
@@ -18,9 +20,10 @@
  */
 extern "C"
 {
-#include  "utility/uip-conf.h"
-#include  "utility/uip.h"
-#include  "utility/uip_arp.h"
+#include "utility/uip-conf.h"
+#include "utility/uip.h"
+#include "utility/uip_arp.h"
+#include "utility/millis.h"
 #include "string.h"
 }
 #include "UIPEthernet.h"
@@ -32,7 +35,7 @@
 #endif
 #define UIP_TCP_PHYH_LEN    UIP_LLH_LEN + UIP_IPTCPH_LEN
 
-uip_userdata_closed_t* UIPClient::  closed_conns[UIP_CONNS];
+uip_userdata_t UIPClient::  all_data[UIP_CONNS];
 
 /**
  * @brief
@@ -41,20 +44,7 @@
  * @retval
  */
 UIPClient::UIPClient(void) :
-    _uip_conn(NULL),
-    data(NULL) {
-    UIPEthernet.set_uip_callback(&UIPClient::uip_callback);
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-UIPClient::UIPClient(struct uip_conn* conn) :
-    _uip_conn(conn),
-    data(conn ? (uip_userdata_t*)conn->appstate.user : NULL)
+    data(NULL)
 { }
 
 /**
@@ -63,9 +53,8 @@
  * @param
  * @retval
  */
-UIPClient::UIPClient(uip_userdata_closed_t* conn_data) :
-    _uip_conn(NULL),
-    data((uip_userdata_t*)conn_data)
+UIPClient::UIPClient(uip_userdata_t* conn_data) :
+    data(conn_data)
 { }
 
 /**
@@ -75,22 +64,36 @@
  * @retval
  */
 int UIPClient::connect(IPAddress ip, uint16_t port) {
+    stop();
+
     uip_ipaddr_t    ipaddr;
     uip_ip_addr(ipaddr, ip);
-    _uip_conn = uip_connect(&ipaddr, htons(port));
-    if(_uip_conn) {
-        while((_uip_conn->tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) {
+
+    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();
-            if((_uip_conn->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED)
-            {
+            if((conn->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
+                data = (uip_userdata_t*)conn->appstate;
 #ifdef UIPETHERNET_DEBUG_CLIENT
-                Serial.print("connected, state: ");
-                Serial.print(((uip_userdata_t*)_uip_conn->appstate.user)->state);
-                Serial.print(", first packet in: ");
-                Serial.println(((uip_userdata_t*)_uip_conn->appstate.user)->packets_in[0]);
+                Serial.print(F("connected, state: "));
+                Serial.print(data->state);
+                Serial.print(F(", first packet in: "));
+                Serial.println(data->packets_in[0]);
 #endif
                 return 1;
             }
+
+#if UIP_CONNECT_TIMEOUT > 0
+            if(((int32_t) (millis() - timeout)) > 0) {
+                conn->tcpstateflags = UIP_CLOSED;
+                break;
+            }
+#endif
         }
     }
 
@@ -111,7 +114,7 @@
     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);
@@ -127,29 +130,32 @@
  * @retval
  */
 void UIPClient::stop(void) {
-    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) {
-            uip_userdata_closed_t **     cc = &UIPClient::closed_conns[0];
-            for(uint8_t i = 0; i < UIP_CONNS; i++) {
-                if(*cc == (void*)data) {
-                    *cc = NULL;
-                    break;
-                }
-
-                cc++;
-            }
-
-            free(data);
+        if(data->state & UIP_CLIENT_REMOTECLOSED) {
+            data->state = 0;
         }
         else {
             data->state |= UIP_CLIENT_CLOSE;
         }
 
-        data = NULL;
+#ifdef UIPETHERNET_DEBUG_CLIENT
+        Serial.println(F("after stop()"));
+        _dumpAllData();
+#endif
     }
 
-    _uip_conn = NULL;
+#ifdef UIPETHERNET_DEBUG_CLIENT
+    else {
+        Serial.println(F("stop(), data: NULL"));
+    }
+#endif
+    data = NULL;
     UIPEthernet.tick();
 }
 
@@ -160,7 +166,7 @@
  * @retval
  */
 uint8_t UIPClient::connected(void) {
-    return((_uip_conn && (_uip_conn->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) || available() > 0) ? 1 : 0;
+    return(data && (data->packets_in[0] != NOBLOCK || (data->state & UIP_CLIENT_CONNECTED))) ? 1 : 0;
 }
 
 /**
@@ -170,7 +176,7 @@
  * @retval
  */
 bool UIPClient::operator==(const UIPClient& rhs) {
-    return _uip_conn && rhs._uip_conn && _uip_conn == rhs._uip_conn;
+    return data && rhs.data && (data == rhs.data);
 }
 
 /**
@@ -181,8 +187,7 @@
  */
 UIPClient::operator bool(void) {
     UIPEthernet.tick();
-    return(data || (_uip_conn && (data = (uip_userdata_t*)_uip_conn->appstate.user)))
-&&  (!(data->state & UIP_CLIENT_CLOSED) || data->packets_in[0] != NOBLOCK);
+    return data && (!(data->state & UIP_CLIENT_REMOTECLOSED) || data->packets_in[0] != NOBLOCK);
 }
 
 /**
@@ -192,7 +197,7 @@
  * @retval
  */
 size_t UIPClient::write(uint8_t c) {
-    return _write(_uip_conn, &c, 1);
+    return _write(data, &c, 1);
 }
 
 /**
@@ -202,7 +207,7 @@
  * @retval
  */
 size_t UIPClient::write(const uint8_t* buf, size_t size) {
-    return _write(_uip_conn, buf, size);
+    return _write(data, buf, size);
 }
 
 /**
@@ -211,21 +216,20 @@
  * @param
  * @retval
  */
-size_t UIPClient::_write(struct uip_conn* conn, const uint8_t* buf, size_t size) {
-    uip_userdata_t*     u;
-    int                 remain = size;
-    uint16_t            written;
+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;
+    uint16_t    attempts = UIP_ATTEMPTS_ON_WRITE;
 #endif
     repeat : UIPEthernet.tick();
-    if(conn && (u = (uip_userdata_t*)conn->appstate.user) && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_CLOSED))) {
-        memhandle*  p = _currentBlock(&u->packets_out[0]);
-        if(*p == NOBLOCK)
+    if(u && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED))) {
+        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] = UIPEthernet.network.allocBlock(UIP_SOCKET_DATALEN);
+            if(u->packets_out[p] == NOBLOCK)
             {
 #if UIP_ATTEMPTS_ON_WRITE > 0
                 if((--attempts) > 0)
@@ -240,23 +244,29 @@
         }
 
 #ifdef UIPETHERNET_DEBUG_CLIENT
-        Serial.print("UIPClient.write: writePacket(");
-        Serial.print(*p);
-        Serial.print(") pos: ");
+        Serial.print(F("UIPClient.write: writePacket("));
+        Serial.print(u->packets_out[p]);
+        Serial.print(F(") pos: "));
         Serial.print(u->out_pos);
-        Serial.print(", buf[");
+        Serial.print(F(", buf["));
         Serial.print(size - remain);
-        Serial.print("-");
+        Serial.print(F("-"));
         Serial.print(remain);
-        Serial.print("]: '");
+        Serial.print(F("]: '"));
         Serial.write((uint8_t*)buf + size - remain, remain);
-        Serial.println("'");
+        Serial.println(F("'"));
 #endif
-        written = UIPEthernet.network.writePacket(*p, u->out_pos, (uint8_t*)buf + size - remain, remain);
+        written = UIPEthernet.network.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)
@@ -272,6 +282,9 @@
         }
 
 ready:
+#if UIP_CLIENT_TIMER >= 0
+        u->timer = millis() + UIP_CLIENT_TIMER;
+#endif
         return size - remain;
     }
 
@@ -287,7 +300,7 @@
 int UIPClient::available(void) {
     if(*this)
         return _available(data);
-    return -1;
+    return 0;
 }
 
 /**
@@ -297,15 +310,9 @@
  * @retval
  */
 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);
+    for(uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS; i++) {
+        len += UIPEthernet.network.blockSize(u->packets_in[i]);
     }
 
     return len;
@@ -319,25 +326,33 @@
  */
 int 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 = UIPEthernet.network.readPacket(data->packets_in[0], 0, buf + size - remain, remain);
+            if(read == UIPEthernet.network.blockSize(data->packets_in[0])) {
                 remain -= read;
-                _eatBlock(p);
-                if(_uip_conn && uip_stopped(_uip_conn) && !(data->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_CLOSED)))
-                    data->state |= UIP_CLIENT_RESTART;
-                if(*p == NOBLOCK)
+                _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(data->packets_in[0] == NOBLOCK) {
+                    if(data->state & UIP_CLIENT_REMOTECLOSED) {
+                        data->state = 0;
+                        data = NULL;
+                    }
+
                     return size - remain;
+                }
             }
             else {
-                UIPEthernet.network.resizeBlock(*p, read);
+                UIPEthernet.network.resizeBlock(data->packets_in[0], read);
                 break;
             }
         } while(remain > 0);
@@ -368,10 +383,9 @@
  */
 int UIPClient::peek(void) {
     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);
+            UIPEthernet.network.readPacket(data->packets_in[0], 0, &c, 1);
             return c;
         }
     }
@@ -397,67 +411,58 @@
  * @param
  * @retval
  */
-void UIPClient::uip_callback(uip_tcp_appstate_t* s) {
-    uip_userdata_t*     u = (uip_userdata_t*)s->user;
+void uipclient_appcall(void) {
+    uint16_t            send_len = 0;
+    uip_userdata_t*     u = (uip_userdata_t*)uip_conn->appstate;
     if(!u && uip_connected())
     {
 #ifdef UIPETHERNET_DEBUG_CLIENT
-        Serial.println("UIPClient uip_connected");
+        Serial.println(F("UIPClient uip_connected"));
+        UIPClient::_dumpAllData();
 #endif
-        // We want to store some data in our connections, so allocate some space
+        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, BIN);
+#endif
+        }
 
-        // for it.  The connection_data struct is defined in a separate .h file,
-        // due to the way the Arduino IDE works.  (typedefs come after function
-        // definitions.)
-        u = (uip_userdata_t*)malloc(sizeof(uip_userdata_t));
-        if(u) {
-            memset(u, 0, sizeof(uip_userdata_t));
-            s->user = u;
-        }
+#ifdef UIPETHERNET_DEBUG_CLIENT
+        else
+            Serial.println(F("UIPClient allocation failed"));
+#endif
     }
 
     if(u) {
         if(uip_newdata())
         {
 #ifdef UIPETHERNET_DEBUG_CLIENT
-            Serial.print("UIPClient uip_newdata, uip_len:");
+            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;
+            if(uip_len && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED))) {
+                for(uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS; i++) {
+                    if(u->packets_in[i] == NOBLOCK) {
+                        u->packets_in[i] = UIPEthernet.network.allocBlock(uip_len);
+                        if(u->packets_in[i] != NOBLOCK) {
+                            UIPEthernet.network.copyPacket
+                                (
+                                    u->packets_in[i],
+                                    0,
+                                    UIPEthernetClass::in_packet,
+                                    ((uint8_t*)uip_appdata) - uip_buf,
+                                    uip_len
+                                );
+                            if(i == UIP_SOCKET_NUMPACKETS - 1)
+                                uip_stop();
+                            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();
             }
         }
@@ -472,66 +477,67 @@
         if(uip_closed() || uip_timedout())
         {
 #ifdef UIPETHERNET_DEBUG_CLIENT
-            Serial.println("UIPClient uip_closed");
+            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 **     closed_conn_data = &UIPClient::closed_conns[0];
-                for(uip_socket_ptr i = 0; i < UIP_CONNS; i++) {
-                    if(!*closed_conn_data) {
-                        *closed_conn_data = (uip_userdata_closed_t*)u;
-                        (*closed_conn_data)->lport = uip_conn->lport;
-                        break;
-                    }
-
-                    closed_conn_data++;
-                }
+                ((uip_userdata_closed_t*)u)->lport = uip_conn->lport;
+                u->state |= UIP_CLIENT_REMOTECLOSED;
             }
-
-            u->state |= UIP_CLIENT_CLOSED;
+            else
+                u->state = 0;
 
             // disassociate appdata.
-            s->user = NULL;
-            goto nodata;
+#ifdef UIPETHERNET_DEBUG_CLIENT
+            Serial.println(F("after UIPClient uip_closed"));
+            UIPClient::_dumpAllData();
+#endif
+            uip_conn->appstate = NULL;
+            goto finish;
         }
 
         if(uip_acked())
         {
 #ifdef UIPETHERNET_DEBUG_CLIENT
-            Serial.println("UIPClient uip_acked");
+            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("UIPClient uip_poll");
+            //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);
+                    send_len = u->out_pos;
+                    if(send_len > 0) {
+                        UIPEthernet.network.resizeBlock(u->packets_out[0], 0, send_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);
+                    send_len = UIPEthernet.network.blockSize(u->packets_out[0]);
+                if(send_len > 0) {
+                    UIPEthernetClass::uip_hdrlen = ((uint8_t*)uip_appdata) - uip_buf;
+                    UIPEthernetClass::uip_packet = UIPEthernet.network.allocBlock(UIPEthernetClass::uip_hdrlen + send_len);
+                    if(UIPEthernetClass::uip_packet != NOBLOCK) {
+                        UIPEthernet.network.copyPacket
+                            (
+                                UIPEthernetClass::uip_packet,
+                                UIPEthernetClass::uip_hdrlen,
+                                u->packets_out[0],
+                                0,
+                                send_len
+                            );
+                        UIPEthernetClass::packetstate |= UIPETHERNET_SENDPACKET;
                     }
+                }
 
-                    return;
-                }
+                goto finish;
             }
         }
 
@@ -539,25 +545,30 @@
         if(u->state & UIP_CLIENT_CLOSE)
         {
 #ifdef UIPETHERNET_DEBUG_CLIENT
-            Serial.print("UIPClient state UIP_CLIENT_CLOSE");
-#endif
-            if(u->packets_out[0] == NOBLOCK)
-            {
-#ifdef UIPETHERNET_DEBUG_CLIENT
-                Serial.print("UIPClient state UIP_CLIENT_CLOSE -> free userdata");
+            Serial.println(F("UIPClient state UIP_CLIENT_CLOSE"));
+            UIPClient::_dumpAllData();
 #endif
-                free(u);
-                s->user = NULL;
+            if(u->packets_out[0] == NOBLOCK) {
+                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
+            else {
                 uip_stop();
+#ifdef UIPETHERNET_DEBUG_CLIENT
+                Serial.println(F("blocks outstanding transfer -> uip_stop()"));
+#endif
+            }
         }
     }
 
-nodata:
-    UIPEthernet.uip_packet = NOBLOCK;
-    uip_len = 0;
+finish:
+    uip_send(uip_appdata, send_len);
+    uip_len = send_len;
 }
 
 /**
@@ -566,11 +577,32 @@
  * @param
  * @retval
  */
-memhandle* UIPClient::_currentBlock(memhandle* block) {
-    for(memhandle * end = block + UIP_SOCKET_NUMPACKETS - 1; block < end; block++)
-        if(*(block + 1) == NOBLOCK)
-            break;
-    return block;
+uip_userdata_t* UIPClient::_allocateData(void) {
+    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;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+uint8_t UIPClient::_currentBlock(memhandle* block) {
+    for(uint8_t i = 1; i < UIP_SOCKET_NUMPACKETS; i++) {
+        if(block[i] == NOBLOCK)
+            return i - 1;
+    }
+
+    return UIP_SOCKET_NUMPACKETS - 1;
 }
 
 /**
@@ -583,26 +615,26 @@
 {
 #ifdef UIPETHERNET_DEBUG_CLIENT
     memhandle*  start = block;
-    Serial.print("eatblock(");
+    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
+    UIPEthernet.network.freeBlock(block[0]);
+    for(uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS - 1; i++) {
+        block[i] = block[i + 1];
+    }
 
-    memhandle*  end = block + (UIP_SOCKET_NUMPACKETS - 1);
-    UIPEthernet.network.freeBlock(*block);
-    while(block < end)
-        *block = *((block++) + 1);
-    *end = NOBLOCK;
+    block[UIP_SOCKET_NUMPACKETS - 1] = NOBLOCK;
 #ifdef UIPETHERNET_DEBUG_CLIENT
     for(uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS; i++) {
         Serial.print(start[i]);
-        Serial.print(" ");
+        Serial.print(F(" "));
     }
 
     Serial.println();
@@ -616,13 +648,48 @@
  * @retval
  */
 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;
+    for(uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS; i++) {
+        UIPEthernet.network.freeBlock(block[i]);
+        block[i] = NOBLOCK;
     }
 }
 
+#ifdef UIPETHERNET_DEBUG_CLIENT
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void UIPClient::_dumpAllData(void) {
+    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
--- a/UIPClient.h	Sat Dec 20 11:10:40 2014 +0000
+++ b/UIPClient.h	Sun Mar 08 20:26:56 2015 +0000
@@ -16,83 +16,97 @@
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
+
 #ifndef UIPCLIENT_H
-    #define UIPCLIENT_H
+#define UIPCLIENT_H
 
-    #include "ethernet_comp.h"
-    #include "Client.h"
-    #include  "utility/mempool.h"
+#include "ethernet_comp.h"
+//#include "Print.h"
+#include "Client.h"
+#include "utility/mempool.h"
+
+extern "C" {
+  #include "utility/uip.h"
+}
 
-extern "C"
-{
-    #include  "utility/uip.h"
-}
-    #define UIP_SOCKET_DATALEN  UIP_TCP_MSS
+#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
 
-    #ifndef UIP_SOCKET_NUMPACKETS
-        #define UIP_SOCKET_NUMPACKETS   5
-    #endif
-    #define UIP_CLIENT_CLOSE    1
-    #define UIP_CLIENT_CLOSED   2
-    #define UIP_CLIENT_RESTART  4
+#define UIP_CLIENT_CONNECTED 0x10
+#define UIP_CLIENT_CLOSE 0x20
+#define UIP_CLIENT_REMOTECLOSED 0x40
+#define UIP_CLIENT_RESTART 0x80
+#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;
 
-typedef struct
-{
-    uint8_t     state;
-    memhandle   packets_in[UIP_SOCKET_NUMPACKETS];
-    uint16_t    lport;  /**< The local TCP port, in network byte order. */
+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;
+typedef struct {
+  uint8_t state;
+  memhandle packets_in[UIP_SOCKET_NUMPACKETS];
+  memhandle packets_out[UIP_SOCKET_NUMPACKETS];
+  memaddress out_pos;
+#if UIP_CLIENT_TIMER >= 0
+  unsigned long timer;
+#endif
 } uip_userdata_t;
 
-class UIPClient :
-    public Client
-{
+class UIPClient : public Client {
+
 public:
-    UIPClient(void);
-    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(void);
-    uint8_t                 connected(void);
-    operator                bool(void);
-    virtual bool operator   ==(const EthernetClient& );
-    virtual bool operator   !=(const EthernetClient& rhs)   { return !this->operator ==(rhs); };
+  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(void);
-    int                     read(void);
-    int                     peek(void);
-    void                    flush(void);
+  size_t write(uint8_t);
+  size_t write(const uint8_t *buf, size_t size);
+  int available();
+  int read();
+  int peek();
+  void flush();
+
+//  using Print::write;
+
 private:
-    UIPClient(struct uip_conn* _conn);
-    UIPClient(uip_userdata_closed_t* closed_conn);
+  UIPClient(struct uip_conn *_conn);
+  UIPClient(uip_userdata_t* conn_data);
+
+  uip_userdata_t* data;
 
-    struct uip_conn*                _uip_conn;
+  static uip_userdata_t all_data[UIP_CONNS];
+  static uip_userdata_t* _allocateData();
 
-    uip_userdata_t*                 data;
-
-    static uip_userdata_closed_t*   closed_conns[UIP_CONNS];
+  static size_t _write(uip_userdata_t *,const uint8_t *buf, size_t size);
+  static int _available(uip_userdata_t *);
 
-    static size_t                   _write(struct uip_conn* , const uint8_t* buf, size_t size);
-    static int                      _available(uip_userdata_t* );
+  static uint8_t _currentBlock(memhandle* blocks);
+  static void _eatBlock(memhandle* blocks);
+  static void _flushBlocks(memhandle* blocks);
+
+#ifdef UIPETHERNET_DEBUG_CLIENT
+  static void _dumpAllData();
+#endif
 
-    static memhandle*               _currentBlock(memhandle* blocks);
-    static void                     _eatBlock(memhandle* blocks);
-    static void                     _flushBlocks(memhandle* blocks);
+  friend class UIPEthernetClass;
+  friend class UIPServer;
 
-    friend class                    UIPEthernetClass;
-    friend class                    UIPServer;
-    static void                     uip_callback(uip_tcp_appstate_t* s);
+  friend void uipclient_appcall(void);
+
 };
+
 #endif
--- a/UIPEthernet.cpp	Sat Dec 20 11:10:40 2014 +0000
+++ b/UIPEthernet.cpp	Sun Mar 08 20:26:56 2015 +0000
@@ -1,591 +1,621 @@
-/*
- UIPEthernet.cpp - Arduino implementation of a uIP wrapper class.
- Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
- All rights reserved.
-
- Modified (ported to mbed) by Zoltan Hudak <hudakz@inbox.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 <http://www.gnu.org/licenses/>.
-  */
-#pragma once
-#include <mbed.h>
-#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(PinName mosi, PinName miso, PinName sck, PinName cs) :
-    network(mosi, miso, sck, cs),
-    fn_uip_cb(NULL),
-    fn_uip_udp_cb(NULL),
-    in_packet(NOBLOCK),
-    uip_packet(NOBLOCK),
-    uip_hdrlen(0),
-    packetstate(0),
-    _dhcp(NULL)
-{ }
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-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;
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip) {
-    IPAddress   dns = ip;
-    dns[3] = 1;
-    begin(mac, ip, dns);
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns) {
-    IPAddress   gateway = ip;
-    gateway[3] = 1;
-    begin(mac, ip, dns, gateway);
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-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);
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet) {
-    init(mac);
-    configure(ip, dns, gateway, subnet);
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-int UIPEthernetClass::maintain(void) {
-    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;
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-IPAddress UIPEthernetClass::localIP(void) {
-    IPAddress       ret;
-    uip_ipaddr_t    a;
-    uip_gethostaddr(a);
-    return ip_addr_uip(a);
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-IPAddress UIPEthernetClass::subnetMask(void) {
-    IPAddress       ret;
-    uip_ipaddr_t    a;
-    uip_getnetmask(a);
-    return ip_addr_uip(a);
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-IPAddress UIPEthernetClass::gatewayIP(void) {
-    IPAddress       ret;
-    uip_ipaddr_t    a;
-    uip_getdraddr(a);
-    return ip_addr_uip(a);
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-IPAddress UIPEthernetClass::dnsServerIP(void) {
-    return _dnsServerAddress;
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void UIPEthernetClass::tick(void) {
-    if(in_packet == NOBLOCK) {
-        in_packet = network.receivePacket();
-#ifdef UIPETHERNET_DEBUG
-        if(in_packet != NOBLOCK) {
-            Serial.print("--------------\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("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("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("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 */
-    }
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-bool UIPEthernetClass::network_send(void) {
-    if(packetstate & UIPETHERNET_SENDPACKET)
-    {
-#ifdef UIPETHERNET_DEBUG
-        Serial.print("network_send uip_packet: ");
-        Serial.print(uip_packet);
-        Serial.print(", 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("network_send uip_buf (uip_len): ");
-        Serial.print(uip_len);
-        Serial.print(", 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;
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-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();
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-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;
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void UIPEthernetClass::set_uip_callback(fn_uip_cb_t fn) {
-    this->fn_uip_cb = fn;
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void UIPEthernetClass::uip_callback(void) {
-    struct uipethernet_state*   s = &(uip_conn->appstate);
-
-    if(this->fn_uip_cb) {
-
-        // The sketch wants to handle all uIP events itself, using uIP functions.
-        this->fn_uip_cb(s); //->p, &s->user);
-    }
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void UIPEthernetClass::set_uip_udp_callback(fn_uip_udp_cb_t fn) {
-    this->fn_uip_udp_cb = fn;
-}
-
-#if UIP_UDP
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void UIPEthernetClass::uip_udp_callback(void) {
-    struct uipudp_state*    s = &(uip_udp_conn->appstate);
-
-    if(this->fn_uip_udp_cb) {
-
-        // The sketch wants to handle all uIP events itself, using uIP functions.
-        this->fn_uip_udp_cb(s); //->p, &s->user);
-    }
-}
-#endif
-//UIPEthernetClass UIPEthernet;
-
-// uIP callback function
-void uipethernet_appcall(void) {
-    UIPEthernet.uip_callback();
-}
-
-#if UIP_UDP
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void uipudp_appcall(void) {
-    UIPEthernet.uip_udp_callback();
-}
-#endif
-
-/*---------------------------------------------------------------------------*/
-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("chksum uip_buf[");
-    Serial.print(UIP_IPH_LEN + UIP_LLH_LEN);
-    Serial.print("-");
-    Serial.print(UIP_IPH_LEN + UIP_LLH_LEN + upper_layer_memlen);
-    Serial.print("]: ");
-    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("chksum uip_packet(");
-        Serial.print(uip_packet);
-        Serial.print(")[");
-        Serial.print(UIP_IPH_LEN + UIP_LLH_LEN + upper_layer_memlen);
-        Serial.print("-");
-        Serial.print(UIP_IPH_LEN + UIP_LLH_LEN + upper_layer_len);
-        Serial.print("]: ");
-        Serial.println(htons(sum), HEX);
-#endif
-    }
-
-    return(sum == 0) ? 0xffff : htons(sum);
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-uint16_t uip_ipchksum(void) {
-    return UIPEthernet.ipchksum();
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-uint16_t uip_tcpchksum(void) {
-    uint16_t    sum = UIPEthernet.upper_layer_chksum(UIP_PROTO_TCP);
-    return sum;
-}
-
-#if UIP_UDP
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-uint16_t uip_udpchksum(void) {
-    uint16_t    sum = UIPEthernet.upper_layer_chksum(UIP_PROTO_UDP);
-    return sum;
-}
-#endif
-
-
-
+/*
+ UIPEthernet.cpp - Arduino implementation of a uIP wrapper class.
+ Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
+ All rights reserved.
+
+ Modified (ported to mbed) by Zoltan Hudak <hudakz@inbox.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 <http://www.gnu.org/licenses/>.
+  */
+#include <mbed.h>
+#include "UIPEthernet.h"
+#include "utility/Enc28J60Network.h"
+
+#if (defined UIPETHERNET_DEBUG || defined UIPETHERNET_DEBUG_CHKSUM)
+    #include "HardwareSerial.h"
+#endif
+#include "UIPUdp.h"
+
+extern "C"
+{
+#include "utility/uip-conf.h"
+#include "utility/uip.h"
+#include "utility/uip_arp.h"
+#include "utility/uip_timer.h"
+#include "utility/millis.h"
+}
+#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);
+
+unsigned long UIPEthernetClass::    periodic_timer;
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void 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) {
+        UIPEthernet.network.writeByte(dest, UIPEthernet.network.readByte(src));
+    }
+    else {
+
+        // calculate address of last byte
+        len += src - 1;
+
+        /*  1. Appropriately program the EDMAST, EDMAND
+       and EDMADST register pairs. The EDMAST
+       registers should point to the first byte to copy
+       from, the EDMAND registers should point to the
+       last byte to copy and the EDMADST registers
+       should point to the first byte in the destination
+       range. The destination range will always be
+       linear, never wrapping at any values except from
+       8191 to 0 (the 8-Kbyte memory boundary).
+       Extreme care should be taken when
+       programming the start and end pointers to
+       prevent a never ending DMA operation which
+       would overwrite the entire 8-Kbyte buffer.
+       */
+        UIPEthernet.network.writeRegPair(EDMASTL, src);
+        UIPEthernet.network.writeRegPair(EDMADSTL, dest);
+
+        if((src <= RXSTOP_INIT) && (len > RXSTOP_INIT))
+            len -= (RXSTOP_INIT - RXSTART_INIT);
+        UIPEthernet.network.writeRegPair(EDMANDL, len);
+
+        /*
+       2. If an interrupt at the end of the copy process is
+       desired, set EIE.DMAIE and EIE.INTIE and
+       clear EIR.DMAIF.
+
+       3. Verify that ECON1.CSUMEN is clear. */
+        UIPEthernet.network.writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_CSUMEN);
+
+        /* 4. Start the DMA copy by setting ECON1.DMAST. */
+        UIPEthernet.network.writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST);
+
+        // wait until runnig DMA is completed
+        while(UIPEthernet.network.readOp(ENC28J60_READ_CTRL_REG, ECON1) & ECON1_DMAST);
+    }
+}
+
+// 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(PinName mosi, PinName miso, PinName sck, PinName cs) :
+    network(mosi, miso, sck, cs) {
+    millis_start();
+}
+
+#if UIP_UDP
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+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;
+}
+#endif
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip) {
+    IPAddress   dns = ip;
+    dns[3] = 1;
+    begin(mac, ip, dns);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns) {
+    IPAddress   gateway = ip;
+    gateway[3] = 1;
+    begin(mac, ip, dns, gateway);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+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);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet) {
+    init(mac);
+    configure(ip, dns, gateway, subnet);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+int UIPEthernetClass::maintain(void) {
+    tick();
+
+    int rc = DHCP_CHECK_NONE;
+#if UIP_UDP
+    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;
+#endif
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+IPAddress UIPEthernetClass::localIP(void) {
+    IPAddress       ret;
+    uip_ipaddr_t    a;
+    uip_gethostaddr(a);
+    return ip_addr_uip(a);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+IPAddress UIPEthernetClass::subnetMask(void) {
+    IPAddress       ret;
+    uip_ipaddr_t    a;
+    uip_getnetmask(a);
+    return ip_addr_uip(a);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+IPAddress UIPEthernetClass::gatewayIP(void) {
+    IPAddress       ret;
+    uip_ipaddr_t    a;
+    uip_getdraddr(a);
+    return ip_addr_uip(a);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+IPAddress UIPEthernetClass::dnsServerIP(void) {
+    return _dnsServerAddress;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void UIPEthernetClass::tick(void)
+{
+    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; //required for upper_layer_checksum of 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;
+        }
+    }
+    unsigned long   now = millis();
+
+#if UIP_CLIENT_TIMER >= 0
+    bool            periodic = (long)(now - periodic_timer) >= 0;
+    for(int i = 0; i < UIP_CONNS; i++)
+    {
+#else
+        if((long)(now - periodic_timer) >= 0) {
+            periodic_timer = now + UIP_PERIODIC_TIMER;
+
+            for(int i = 0; i < UIP_CONNS; i++)
+            {
+#endif
+                uip_conn = &uip_conns[i];
+#if UIP_CLIENT_TIMER >= 0
+                if(periodic)
+                {
+#endif
+                    uip_process(UIP_TIMER);
+#if UIP_CLIENT_TIMER >= 0
+                }
+                else {
+                    if((long)(now - ((uip_userdata_t*)uip_conn->appstate)->timer) >= 0)
+                        uip_process(UIP_POLL_REQUEST);
+                    else
+                        continue;
+                }
+#endif
+                // If the above function invocation resulted in data that
+
+                // should be sent out on the Enc28J60Network, the global variable
+                // uip_len is set to a value > 0.
+                if(uip_len > 0) {
+                    uip_arp_out();
+                    network_send();
+                }
+            }
+#if UIP_CLIENT_TIMER >= 0
+            if(periodic) {
+                periodic_timer = now + UIP_PERIODIC_TIMER;
+#endif
+#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 Enc28J60Network, the global variable
+                    // uip_len is set to a value > 0. */
+                    if(uip_len > 0) {
+                        UIPUDP::_send((uip_udp_userdata_t *) (uip_udp_conns[i].appstate));
+                    }
+                }
+#endif /* UIP_UDP */
+            }
+        }
+
+        /**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+        bool UIPEthernetClass::network_send(void) {
+            if(packetstate & UIPETHERNET_SENDPACKET)
+            {
+#ifdef UIPETHERNET_DEBUG
+                Serial.print(F("Enc28J60Network_send uip_packet: "));
+                Serial.print(uip_packet);
+                Serial.print(F(", hdrlen: "));
+                Serial.println(uip_hdrlen);
+#endif
+                UIPEthernet.network.writePacket(uip_packet, 0, uip_buf, uip_hdrlen);
+                packetstate &= ~UIPETHERNET_SENDPACKET;
+                goto sendandfree;
+            }
+
+            uip_packet = Enc28J60Network::allocBlock(uip_len);
+            if(uip_packet != NOBLOCK)
+            {
+#ifdef UIPETHERNET_DEBUG
+                Serial.print(F("Enc28J60Network_send uip_buf (uip_len): "));
+                Serial.print(uip_len);
+                Serial.print(F(", packet: "));
+                Serial.println(uip_packet);
+#endif
+                UIPEthernet.network.writePacket(uip_packet, 0, uip_buf, uip_len);
+                goto sendandfree;
+            }
+
+            return false;
+sendandfree:
+            network.sendPacket(uip_packet);
+            Enc28J60Network::freeBlock(uip_packet);
+            uip_packet = NOBLOCK;
+            return true;
+        }
+
+        /**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+        void UIPEthernetClass::init(const uint8_t* mac) {
+            periodic_timer = millis() + UIP_PERIODIC_TIMER;
+
+            network.init((uint8_t*)mac);
+            uip_seteth_addr(mac);
+
+            uip_init();
+            uip_arp_init();
+        }
+
+        /**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+        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
+#if UIP_UDP
+        UIPEthernetClass::upper_layer_chksum(uint8_t proto)
+#else
+        uip_tcpchksum (void)
+#endif
+        {
+            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. */
+#if UIP_UDP
+            sum = upper_layer_len + proto;
+#else
+            sum = upper_layer_len + UIP_PROTO_TCP;
+#endif
+            /* Sum IP source and destination addresses. */
+
+            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_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;
+            }
+#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);
+            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, UIPEthernetClass::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);
+        }
+
+        /**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+        uint16_t uip_ipchksum(void) {
+            return UIPEthernet.ipchksum();
+        }
+
+#if UIP_UDP
+        /**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+        uint16_t uip_tcpchksum(void) {
+            uint16_t    sum = UIPEthernet.upper_layer_chksum(UIP_PROTO_TCP);
+            return sum;
+        }
+
+        /**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+        uint16_t uip_udpchksum(void) {
+            uint16_t    sum = UIPEthernet.upper_layer_chksum(UIP_PROTO_UDP);
+            return sum;
+        }
+#endif
--- a/UIPEthernet.h	Sat Dec 20 11:10:40 2014 +0000
+++ b/UIPEthernet.h	Sun Mar 08 20:26:56 2015 +0000
@@ -1,140 +1,130 @@
-/*
- UIPEthernet.h - Arduino implementation of a uIP wrapper class.
- Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
- All rights reserved.
-
- Modified (ported to mbed) by Zoltan Hudak <hudakz@inbox.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 <http://www.gnu.org/licenses/>.
-  */
-#pragma once
-#ifndef UIPETHERNET_H
-    #define UIPETHERNET_H
-
-    #include "ethernet_comp.h"
-    #include <mbed.h>
-    #include "Dhcp.h"
-    #include  "utility/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)
-
-    typedef void (*fn_uip_cb_t) (uip_tcp_appstate_t * conn);
-
-typedef void (*fn_uip_udp_cb_t) (uip_udp_appstate_t * conn);
-
-    #define BUF ((struct uip_tcpip_hdr*) &uip_buf[UIP_LLH_LEN])
-
-class   UIPEthernetClass
-{
-public:
-    UIPEthernetClass(PinName mosi, PinName miso, PinName sck, PinName cs);
-
-    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(void);
-
-    IPAddress   localIP(void);
-    IPAddress   subnetMask(void);
-    IPAddress   gatewayIP(void);
-    IPAddress   dnsServerIP(void);
-
-    // Set a user function to handle raw uIP events as they happen.  The
-    // callback function can only use uIP functions, but it can also use uIP's
-    // protosockets.
-    void        set_uip_callback(fn_uip_cb_t fn);
-    void        set_uip_udp_callback(fn_uip_udp_cb_t fn);
-private:
-    IPAddress           _dnsServerAddress;
-    DhcpClass*          _dhcp;
-
-    struct uip_timer    periodic_timer;
-    fn_uip_cb_t         fn_uip_cb;
-    fn_uip_udp_cb_t     fn_uip_udp_cb;
-
-    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(void);
-    bool                network_send(void);
-    void                uip_callback(void);
-    friend void         uipethernet_appcall(void);
-    void                uip_udp_callback(void);
-    friend void         uipudp_appcall(void);
-    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
-
+/*
+ UIPEthernet.h - Arduino implementation of a uIP wrapper class.
+ Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
+ All rights reserved.
+
+ Modified (ported to mbed) by Zoltan Hudak <hudakz@inbox.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 <http://www.gnu.org/licenses/>.
+  */
+#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 <mbed.h>
+    #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_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:
+        Enc28J60Network network;
+
+        UIPEthernetClass(PinName mosi, PinName miso, PinName sck, PinName cs);
+
+        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(void);
+
+        IPAddress   localIP(void);
+        IPAddress   subnetMask(void);
+        IPAddress   gatewayIP(void);
+        IPAddress   dnsServerIP(void);
+    private:
+        static memhandle        in_packet;
+        static memhandle        uip_packet;
+        static uint8_t          uip_hdrlen;
+        static uint8_t          packetstate;
+
+        static IPAddress        _dnsServerAddress;
+        static DhcpClass*       _dhcp;
+
+        static unsigned long    periodic_timer;
+
+        void                    init(const uint8_t* mac);
+        static void             configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet);
+
+        void                    tick(void);
+
+        bool                    network_send(void);
+
+        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);
+    #if UIP_UDP
+        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 */
+    };
+
+extern UIPEthernetClass UIPEthernet;
+#endif
--- a/UIPServer.cpp	Sat Dec 20 11:10:40 2014 +0000
+++ b/UIPServer.cpp	Sun Mar 08 20:26:56 2015 +0000
@@ -1,109 +1,92 @@
-/*
- UIPServer.cpp - Arduino implementation of a uIP wrapper class.
- Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
- 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 <http://www.gnu.org/licenses/>.
-  */
-#include "UIPEthernet.h"
-#include "UIPServer.h"
-extern "C"
-{
-#include  "utility/uip-conf.h"
-}
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-UIPServer::UIPServer(uint16_t port) :
-    _port(htons(port)) {
-    UIPEthernet.set_uip_callback(&UIPClient::uip_callback);
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-UIPClient UIPServer::available(void) {
-    UIPEthernet.tick();
-
-    uip_userdata_t*     u;
-    for(uint8_t sock = 0; sock < UIP_CONNS; sock++) {
-        struct uip_conn*    conn = &uip_conns[sock];
-        if(conn->lport == _port && (u = (uip_userdata_t*)conn->appstate.user)) {
-            if(UIPClient::_available(u))
-                return UIPClient(conn);
-        }
-    }
-
-    uip_userdata_closed_t **     cc = &UIPClient::closed_conns[0];
-    for(uint8_t i = 0; i < UIP_CONNS; i++) {
-        if(*cc && (*cc)->lport == _port) {
-            if((*cc)->packets_in[0] == NOBLOCK) {
-                free(*cc);
-                *cc = NULL;
-            }
-            else
-                return UIPClient(*cc);
-        }
-
-        cc++;
-    }
-
-    return UIPClient();
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void UIPServer::begin(void) {
-    uip_listen(_port);
-    UIPEthernet.tick();
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-size_t UIPServer::write(uint8_t c) {
-    return write(&c, 1);
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-size_t UIPServer::write(const uint8_t* buf, size_t size) {
-    size_t  ret = 0;
-    for(int sock = 0; sock < UIP_CONNS; sock++) {
-        struct uip_conn*    conn = &uip_conns[sock];
-        if(conn->lport == _port && (conn->tcpstateflags != UIP_CLOSE))
-            ret = UIPClient::_write(conn, buf, size);
-    }
-
-    return ret;
-}
-
-
+/*
+ UIPServer.cpp - Arduino implementation of a uIP wrapper class.
+ Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
+ 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 <http://www.gnu.org/licenses/>.
+  */
+#include "UIPEthernet.h"
+#include "UIPServer.h"
+extern "C"
+{
+#include "utility/uip-conf.h"
+}
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+UIPServer::UIPServer(uint16_t port) :
+    _port(htons(port))
+{ }
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+UIPClient UIPServer::available(void) {
+    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_REMOTECLOSED) && ((uip_userdata_closed_t*)data)->lport == _port)
+            )
+        ) return UIPClient(data);
+    }
+
+    return UIPClient();
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void UIPServer::begin(void) {
+    uip_listen(_port);
+    UIPEthernet.tick();
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+size_t UIPServer::write(uint8_t c) {
+    return write(&c, 1);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+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;
+}
--- a/UIPServer.h	Sat Dec 20 11:10:40 2014 +0000
+++ b/UIPServer.h	Sun Mar 08 20:26:56 2015 +0000
@@ -1,43 +1,41 @@
-/*
- UIPServer.h - Arduino implementation of a uIP wrapper class.
- Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
- 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 <http://www.gnu.org/licenses/>.
-  */
-#ifndef UIPSERVER_H
-    #define UIPSERVER_H
-
-    #include "ethernet_comp.h"
-    #include  "utility/Server.h"
-    #include "UIPClient.h"
-
-class UIPServer :
-    Server
-{
-public:
-    UIPServer(uint16_t);
-    UIPClient   available(void);
-    void        begin(void);
-    size_t      write(uint8_t);
-    size_t      write(const uint8_t* buf, size_t size);
-
-//    using Print::write;
-
-private:
-    uint16_t    _port;
-};
-#endif
-
-
+/*
+ UIPServer.h - Arduino implementation of a uIP wrapper class.
+ Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
+ 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 <http://www.gnu.org/licenses/>.
+  */
+#ifndef UIPSERVER_H
+    #define UIPSERVER_H
+
+    #include "ethernet_comp.h"
+    #include "Server.h"
+    #include "UIPClient.h"
+
+class UIPServer :
+    public Server
+{
+public:
+    UIPServer(uint16_t);
+    UIPClient   available(void);
+    void        begin(void);
+    size_t      write(uint8_t);
+    size_t      write(const uint8_t* buf, size_t size);
+
+//  using Print::write;
+
+private:
+    uint16_t    _port;
+};
+#endif
--- a/UIPUdp.cpp	Sat Dec 20 11:10:40 2014 +0000
+++ b/UIPUdp.cpp	Sun Mar 08 20:26:56 2015 +0000
@@ -1,406 +1,359 @@
-/*
- UIPUdp.cpp - Arduino implementation of a uIP wrapper class.
- Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
- 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 <http://www.gnu.org/licenses/>.
- */
-#include "UIPEthernet.h"
-#include "UIPUdp.h"
-#include "Dns.h"
-
-#ifdef UIPETHERNET_DEBUG_UDP
-    #include "mbed.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(void) {
-    _uip_udp_conn = NULL;
-    memset(&appdata, 0, sizeof(appdata));
-    UIPEthernet.set_uip_udp_callback(&UIPUDP::uip_callback);
-}
-
-// 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.user = &appdata;
-        return 1;
-    }
-
-    return 0;
-}
-
-// Finish with the UDP socket
-void UIPUDP::stop(void) {
-    if(_uip_udp_conn) {
-        flush();
-        uip_udp_remove(_uip_udp_conn);
-        _uip_udp_conn->appstate.user = 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
-        pc.print("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
-                pc.print("new connection, ");
-    #endif
-                _uip_udp_conn->appstate.user = &appdata;
-            }
-            else
-            {
-    #ifdef UIPETHERNET_DEBUG_UDP
-                pc.println("failed to allocate new connection");
-    #endif
-                return 0;
-            }
-        }
-
-    #ifdef UIPETHERNET_DEBUG_UDP
-        pc.print("rip: ");
-        pc.print(ip);
-        pc.print(", port: ");
-        pc.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
-                pc.println("failed to allocate memory for packet");
-    #endif
-        }
-
-    #ifdef UIPETHERNET_DEBUG_UDP
-        else
-            pc.println("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(void) {
-    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(void) {
-    UIPEthernet.tick();
-    if(appdata.packet_in != NOBLOCK)
-    {
-    #ifdef UIPETHERNET_DEBUG_UDP
-        pc.print("udp parsePacket freeing previous packet: ");
-        pc.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
-        pc.print("udp parsePacket received packet: ");
-        pc.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
-        pc.print(", size: ");
-        pc.println(size);
-    #endif
-        return size;
-    }
-
-    return 0;
-}
-
-// Number of bytes remaining in the current packet
-int UIPUDP::available(void) {
-    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(void) {
-    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;
-}
-
-//int
-//UIPUDP::read(char* buffer, size_t len)
-//{
-//    return read((unsigned char*) buffer, size_t len)
-//}
-
-// Return the next byte from the current packet without moving on to the next byte
-int UIPUDP::peek(void) {
-    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(void) {
-    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(void) {
-    return appdata.ripaddr;
-}
-
-// Return the port of the host who sent the current incoming packet
-uint16_t UIPUDP::remotePort(void) {
-    return appdata.rport;
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void UIPUDP::uip_callback(uip_udp_appstate_t* s) {
-    if(appdata_t * data = (appdata_t*)s->user) {
-        if(uip_newdata()) {
-            data->rport = ntohs(UDPBUF->srcport);
-            data->ripaddr = ip_addr_uip(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
-                        pc.print("udp, uip_newdata received packet: ");
-                        pc.print(*packet);
-                        pc.print(", slot: ");
-                        pc.print(i);
-                        pc.print(", size: ");
-                        pc.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
-            pc.print("udp, uip_poll preparing packet to send: ");
-            pc.print(data->packet_out);
-            pc.print(", size: ");
-            pc.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
-                pc.println("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
-                pc.print("udp, uip_packet to send: ");
-                pc.println(UIPEthernet.uip_packet);
-    #endif
-            }
-        }
-    }
-}
-#endif
-
-
+/*
+ UIPUdp.cpp - Arduino implementation of a uIP wrapper class.
+ Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
+ 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 <http://www.gnu.org/licenses/>.
+ */
+#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(void) :
+    _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(void) {
+    if(_uip_udp_conn) {
+        uip_udp_remove(_uip_udp_conn);
+        _uip_udp_conn->appstate = NULL;
+        _uip_udp_conn = NULL;
+        UIPEthernet.network.freeBlock(appdata.packet_in);
+        UIPEthernet.network.freeBlock(appdata.packet_next);
+        UIPEthernet.network.freeBlock(appdata.packet_out);
+        memset(&appdata, 0, sizeof(appdata));
+    }
+}
+
+// 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(void) {
+    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) {
+            _send(&appdata);
+            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(void) {
+    UIPEthernet.tick();
+    #ifdef UIPETHERNET_DEBUG_UDP
+    if(appdata.packet_in != NOBLOCK) {
+        Serial.print(F("udp parsePacket freeing previous packet: "));
+        Serial.println(appdata.packet_in);
+    }
+    #endif
+    UIPEthernet.network.freeBlock(appdata.packet_in);
+
+    appdata.packet_in = appdata.packet_next;
+    appdata.packet_next = NOBLOCK;
+
+    #ifdef UIPETHERNET_DEBUG_UDP
+    if(appdata.packet_in != NOBLOCK) {
+        Serial.print(F("udp parsePacket received packet: "));
+        Serial.print(appdata.packet_in);
+    }
+    #endif
+
+    int size = UIPEthernet.network.blockSize(appdata.packet_in);
+    #ifdef UIPETHERNET_DEBUG_UDP
+    if(appdata.packet_in != NOBLOCK) {
+        Serial.print(F(", size: "));
+        Serial.println(size);
+    }
+    #endif
+    return size;
+}
+
+// Number of bytes remaining in the current packet
+int UIPUDP::available(void) {
+    UIPEthernet.tick();
+    return UIPEthernet.network.blockSize(appdata.packet_in);
+}
+
+// Read a single byte from the current packet
+int UIPUDP::read(void) {
+    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) {
+        memaddress  read = UIPEthernet.network.readPacket(appdata.packet_in, 0, buffer, len);
+        if(read == UIPEthernet.network.blockSize(appdata.packet_in)) {
+            UIPEthernet.network.freeBlock(appdata.packet_in);
+            appdata.packet_in = NOBLOCK;
+        }
+        else
+            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(void) {
+    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(void) {
+    UIPEthernet.tick();
+    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(void) {
+    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(void) {
+    return _uip_udp_conn ? ntohs(_uip_udp_conn->rport) : 0;
+}
+
+// uIP callback function
+void uipudp_appcall(void) {
+    if(uip_udp_userdata_t * data = (uip_udp_userdata_t *) (uip_udp_conn->appstate)) {
+        if(uip_newdata()) {
+            if(data->packet_next == NOBLOCK) {
+                uip_udp_conn->rport = UDPBUF->srcport;
+                uip_ipaddr_copy(uip_udp_conn->ripaddr, UDPBUF->srcipaddr);
+                data->packet_next = 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(data->packet_next != NOBLOCK) {
+
+                    //discard Linklevel and IP and udp-header and any trailing bytes:
+                    UIPEthernet.network.copyPacket
+                        (
+                            data->packet_next,
+                            0,
+                            UIPEthernetClass::in_packet,
+                            UIP_UDP_PHYH_LEN,
+                            UIPEthernet.network.blockSize(data->packet_next)
+                        );
+    #ifdef UIPETHERNET_DEBUG_UDP
+                    Serial.print(F("udp, uip_newdata received packet: "));
+                    Serial.print(data->packet_next);
+                    Serial.print(F(", size: "));
+                    Serial.println(UIPEthernet.network.blockSize(data->packet_next));
+    #endif
+                }
+            }
+        }
+
+        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
+            UIPEthernetClass::uip_packet = data->packet_out;
+            UIPEthernetClass::uip_hdrlen = UIP_UDP_PHYH_LEN;
+            uip_udp_send(data->out_pos - (UIP_UDP_PHYH_LEN));
+        }
+    }
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+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
+    }
+
+    UIPEthernet.network_send();
+}
+#endif
--- a/UIPUdp.h	Sat Dec 20 11:10:40 2014 +0000
+++ b/UIPUdp.h	Sun Mar 08 20:26:56 2015 +0000
@@ -3,6 +3,8 @@
  Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
  All rights reserved.
 
+ Modified (ported to mbed) by Zoltan Hudak <hudakz@inbox.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
@@ -20,35 +22,33 @@
     #define UIPUDP_H
 
     #include "ethernet_comp.h"
-    #include "mbed.h"
+    #include <mbed.h>
     #include <Udp.h>
-    #include  "utility/mempool.h"
+    #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;
+    bool        send;
+} uip_udp_userdata_t;
+
 class UIPUDP :
     public UDP
 {
 private:
     struct uip_udp_conn*    _uip_udp_conn;
 
-    struct appdata_t
-    {
-        uint16_t    rport;
-        IPAddress   ripaddr;
-        memaddress  out_pos;
-        memhandle   packets_in[UIP_UDP_NUMPACKETS];
-        memhandle   packet_in;
-        memhandle   packet_out;
-        bool        send;
-    } appdata;
+    uip_udp_userdata_t      appdata;
 public:
     UIPUDP(void);   // 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
@@ -73,7 +73,7 @@
     // Write size bytes from buffer into the packet
     size_t      write(const uint8_t* buffer, size_t size);
 
-    //    using Print::write;
+    //  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(void);
@@ -90,11 +90,11 @@
     // 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); };
+    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);
-
     void        flush(void);    // Finish reading the current packet
 
     // Return the IP address of the host who sent the current incoming packet
@@ -103,6 +103,9 @@
     // Return the port of the host who sent the current incoming packet
     uint16_t    remotePort(void);
 private:
-    static void uip_callback(uip_udp_appstate_t* s);
+    friend void     uipudp_appcall(void);
+
+    friend class    UIPEthernetClass;
+    static void     _send(uip_udp_userdata_t* data);
 };
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Udp.h	Sun Mar 08 20:26:56 2015 +0000
@@ -0,0 +1,96 @@
+/*
+ *  Udp.cpp: Library to send/receive UDP packets.
+ *
+ * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
+ * 1) UDP does not guarantee the order in which assembled UDP packets are received. This
+ * might not happen often in practice, but in larger network topologies, a UDP
+ * packet can be received out of sequence. 
+ * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
+ * aware of it. Again, this may not be a concern in practice on small local networks.
+ * For more information, see http://www.cafeaulait.org/course/week12/35.html
+ *
+ * MIT License:
+ * Copyright (c) 2008 Bjoern Hartmann
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * bjoern@cs.stanford.edu 12/30/2008
+ */
+#ifndef udp_h
+    #define udp_h
+
+    #include <mbed.h>
+    #include <IPAddress.h>
+
+//class UDP : public Stream {
+class   UDP
+{
+public:
+    virtual uint8_t     begin(uint16_t) = 0;    // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
+    virtual void        stop(void) = 0;         // 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
+    virtual int         beginPacket(IPAddress ip, uint16_t port) = 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
+    virtual int         beginPacket(const char* host, uint16_t port) = 0;
+
+    // Finish off this packet and send it
+    // Returns 1 if the packet was sent successfully, 0 if there was an error
+    virtual int         endPacket(void) = 0;
+
+    // Write a single byte into the packet
+    virtual size_t      write(uint8_t) = 0;
+
+    // Write size bytes from buffer into the packet
+    virtual size_t      write(const uint8_t* buffer, size_t size) = 0;
+
+    // Start processing the next available incoming packet
+    // Returns the size of the packet in bytes, or 0 if no packets are available
+    virtual int         parsePacket(void) = 0;
+
+    // Number of bytes remaining in the current packet
+    virtual int         available(void) = 0;
+
+    // Read a single byte from the current packet
+    virtual int         read(void) = 0;
+
+    // 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
+    virtual int         read(unsigned char* buffer, size_t len) = 0;
+
+    // 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
+    virtual int         read(char* buffer, size_t len) = 0;
+
+    // Return the next byte from the current packet without moving on to the next byte
+    virtual int         peek(void) = 0;
+    virtual void        flush(void) = 0;        // Finish reading the current packet
+
+    // Return the IP address of the host who sent the current incoming packet
+    virtual IPAddress   remoteIP(void) = 0;
+
+    // Return the port of the host who sent the current incoming packet
+    virtual uint16_t    remotePort(void) = 0;
+protected:
+    uint8_t*    rawIPAddress(IPAddress& addr)   { return addr.raw_address(); };
+};
+#endif
--- a/ethernet_comp.h	Sat Dec 20 11:10:40 2014 +0000
+++ b/ethernet_comp.h	Sun Mar 08 20:26:56 2015 +0000
@@ -1,7 +1,7 @@
 #ifndef ETHERNET_COMP_H
     #define ETHERNET_COMP_H
 
-//    #define Ethernet        UIPEthernet
+    //#define Ethernet UIPEthernet
     #define EthernetClient  UIPClient
     #define EthernetServer  UIPServer
     #define EthernetUDP     UIPUDP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/keywords.txt	Sun Mar 08 20:26:56 2015 +0000
@@ -0,0 +1,58 @@
+#######################################
+# Syntax Coloring Map for SerialIP
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+UIPEthernet KEYWORD1
+UIPServer KEYWORD1
+UIPClient KEYWORD1
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+PSOCK_BEGIN	KEYWORD2
+PSOCK_CLOSE	KEYWORD2
+PSOCK_END	KEYWORD2
+PSOCK_EXIT	KEYWORD2
+PSOCK_INIT	KEYWORD2
+PSOCK_READBUF	KEYWORD2
+PSOCK_READTO	KEYWORD2
+PSOCK_SEND	KEYWORD2
+PSOCK_SEND_STR	KEYWORD2
+
+uip_listen	KEYWORD2
+uip_unlisten	KEYWORD2
+uip_connect	KEYWORD2
+uip_outstanding	KEYWORD2
+uip_send	KEYWORD2
+uip_datalen	KEYWORD2
+uip_close	KEYWORD2
+uip_abort	KEYWORD2
+uip_stop	KEYWORD2
+uip_stopped	KEYWORD2
+uip_restart	KEYWORD2
+uip_acked	KEYWORD2
+uip_connected	KEYWORD2
+uip_closed	KEYWORD2
+uip_aborted	KEYWORD2
+uip_timedout	KEYWORD2
+uip_rexmit	KEYWORD2
+uip_poll	KEYWORD2
+uip_initialmss	KEYWORD2
+uip_mss	KEYWORD2
+uip_ipaddr	KEYWORD2
+uip_ipaddr_maskcmp	KEYWORD2
+uip_ipaddr_mask	KEYWORD2
+HTONS	KEYWORD2
+htons	KEYWORD2
+
+use_device	KEYWORD2
+set_uip_callback	KEYWORD2
+set_gateway	KEYWORD2
+
+#######################################
+# Constants (LITERAL1)
+#######################################
--- a/utility/Client.h	Sat Dec 20 11:10:40 2014 +0000
+++ b/utility/Client.h	Sun Mar 08 20:26:56 2015 +0000
@@ -1,48 +1,43 @@
-/*
-  Client.h - Base class that provides Client
-  Copyright (c) 2011 Adrian McEwen.  All right reserved.
-
-  Modified (ported to mbed) by Zoltan Hudak <hudakz@inbox.com>
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library 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
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-*/
-#ifndef client_h
-    #define client_h
-    //#include "Print.h"
-    //#include "Stream.h"
-    #include "IPAddress.h"
-
-//class Client : public Stream {
-class   Client
-{
-public:
-    virtual int         connect(IPAddress ip, uint16_t port) = 0;
-    virtual int         connect(const char* host, uint16_t port) = 0;
-    virtual size_t      write(uint8_t) = 0;
-    virtual size_t      write(const uint8_t* buf, size_t size) = 0;
-    virtual int         available(void) = 0;
-    virtual int         read(void) = 0;
-    virtual int         read(uint8_t* buf, size_t size) = 0;
-    virtual int         peek(void) = 0;
-    virtual void        flush(void) = 0;
-    virtual void        stop(void) = 0;
-    virtual uint8_t     connected(void) = 0;
-    virtual operator    bool(void) = 0;
-protected:
-    uint8_t*    rawIPAddress(IPAddress& addr)   { return addr.raw_address(); };
-};
-#endif
-
-
+/*
+  Client.h - Base class that provides Client
+  Copyright (c) 2011 Adrian McEwen.  All right reserved.
+
+  Modified (ported to mbed) by Zoltan Hudak <hudakz@inbox.com>
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+#ifndef client_h
+    #define client_h
+    #include "IPAddress.h"
+
+class   Client
+{
+public:
+    virtual int         connect(IPAddress ip, uint16_t port) = 0;
+    virtual int         connect(const char* host, uint16_t port) = 0;
+    virtual size_t      write(uint8_t) = 0;
+    virtual size_t      write(const uint8_t* buf, size_t size) = 0;
+    virtual int         available(void) = 0;
+    virtual int         read(void) = 0;
+    virtual int         read(uint8_t* buf, size_t size) = 0;
+    virtual int         peek(void) = 0;
+    virtual void        flush(void) = 0;
+    virtual void        stop(void) = 0;
+    virtual uint8_t     connected(void) = 0;
+    virtual operator    bool(void) = 0;
+protected:
+    uint8_t*    rawIPAddress(IPAddress& addr)   { return addr.raw_address(); };
+};
+#endif
--- a/utility/Enc28J60Network.cpp	Sat Dec 20 11:10:40 2014 +0000
+++ b/utility/Enc28J60Network.cpp	Sun Mar 08 20:26:56 2015 +0000
@@ -1,695 +1,733 @@
-/*
- Enc28J60Network.h
- UIPEthernet network driver for Microchip ENC28J60 Ethernet Interface.
-
- Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
- All rights reserved.
-
- based on enc28j60.c file from the AVRlib library by Pascal Stang.
- For AVRlib See http://www.procyonengineering.com/
-
- Modified (ported to mbed) by Zoltan Hudak <hudakz@inbox.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 <http://www.gnu.org/licenses/>.
- */
-#include "Enc28J60Network.h"
-#include "mbed.h"
-
-extern "C"
-{
-#include "enc28j60.h"
-#include "uip.h"
-}
-#define DMARUNNING      1
-#define DMANEWPACKET    2
-
-#define waitspi()       while(!(SPSR & (1 << SPIF)))
-    Enc28J60Network::Enc28J60Network(PinName mosi, PinName miso, PinName sclk, PinName cs) :
-    MemoryPool(TXSTART_INIT + 1, TXSTOP_INIT - TXSTART_INIT),
-
-    // 1 byte in between RX_STOP_INIT and pool to allow prepending of controlbyte
-    bank(0xff),
-    _spi(mosi, miso, sclk),
-    _cs(cs) { }
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void Enc28J60Network::init(uint8_t* macaddr) {
-
-    // initialize SPI interface
-
-    _spi.format(8, 0);          // 8bit, mode 0
-    _spi.frequency(7000000);    // 7MHz
-    wait(1);        // 1 second for stable state
-
-    // initialize I/O
-    _cs = 1;        // ss=0
-
-    // initialize SPI interface
-    // master mode and Fosc/2 clock:
-    //SPCR = (1<<SPE)|(1<<MSTR);
-    //SPSR |= (1<<SPI2X);
-    // perform system reset
-    writeOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
-    wait(0.020);    // 20ms
-
-    // check CLKRDY bit to see if reset is complete
-    // The CLKRDY does not work. See Rev. B4 Silicon Errata point. Just wait.
-    //while(!(readReg(ESTAT) & ESTAT_CLKRDY));
-    // do bank 0 stuff
-    // initialize receive buffer
-    // 16-bit transfers, must write low byte first
-    // set receive buffer start address
-    nextPacketPtr = RXSTART_INIT;
-
-    // Rx start
-    writeRegPair(ERXSTL, RXSTART_INIT);
-
-    // set receive pointer address
-    writeRegPair(ERXRDPTL, RXSTART_INIT);
-
-    // RX end
-    writeRegPair(ERXNDL, RXSTOP_INIT);
-
-    // TX start
-    //writeRegPair(ETXSTL, TXSTART_INIT);
-    // TX end
-    //writeRegPair(ETXNDL, TXSTOP_INIT);
-    // do bank 1 stuff, packet filter:
-    // For broadcast packets we allow only ARP packtets
-    // All other packets should be unicast only for our mac (MAADR)
-    //
-    // The pattern to match on is therefore
-    // Type     ETH.DST
-    // ARP      BROADCAST
-    // 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9
-    // in binary these poitions are:11 0000 0011 1111
-    // This is hex 303F->EPMM0=0x3f,EPMM1=0x30
-    //TODO define specific pattern to receive dhcp-broadcast packages instead of setting ERFCON_BCEN!
-    writeReg(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_PMEN | ERXFCON_BCEN);
-    writeRegPair(EPMM0, 0x303f);
-    writeRegPair(EPMCSL, 0xf7f9);
-
-    //
-    //
-    // do bank 2 stuff
-    // enable MAC receive
-    // and bring MAC out of reset (writes 0x00 to MACON2)
-    writeRegPair(MACON1, MACON1_MARXEN | MACON1_TXPAUS | MACON1_RXPAUS);
-
-    // enable automatic padding to 60bytes and CRC operations
-    writeOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN);
-
-    // set inter-frame gap (non-back-to-back)
-    writeRegPair(MAIPGL, 0x0C12);
-
-    // set inter-frame gap (back-to-back)
-    writeReg(MABBIPG, 0x12);
-
-    // Set the maximum packet size which the controller will accept
-    // Do not send packets longer than MAX_FRAMELEN:
-    writeRegPair(MAMXFLL, MAX_FRAMELEN);
-
-    // do bank 3 stuff
-    // write MAC address
-    // NOTE: MAC address in ENC28J60 is byte-backward
-    writeReg(MAADR5, macaddr[0]);
-    writeReg(MAADR4, macaddr[1]);
-    writeReg(MAADR3, macaddr[2]);
-    writeReg(MAADR2, macaddr[3]);
-    writeReg(MAADR1, macaddr[4]);
-    writeReg(MAADR0, macaddr[5]);
-
-    // no loopback of transmitted frames
-    phyWrite(PHCON2, PHCON2_HDLDIS);
-
-    // switch to bank 0
-    setBank(ECON1);
-
-    // enable interrutps
-    writeOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE | EIE_PKTIE);
-
-    // enable packet reception
-    writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
-    clkout(2);      // change clkout from 6.25MHz to 12.5MHz
-    wait(0.000060); // 60us
-
-    //Configure leds
-    phyWrite(PHLCON, 0x476);
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-memhandle Enc28J60Network::receivePacket(void) {
-    uint16_t    rxstat;
-    uint16_t    len;
-    // check if a packet has been received and buffered
-
-    //if( !(readReg(EIR) & EIR_PKTIF) ){
-    // The above does not work. See Rev. B4 Silicon Errata point 6.
-    if(readReg(EPKTCNT) != 0) {
-        uint16_t    readPtr = nextPacketPtr + 6;
-        // Set the read pointer to the start of the received packet
-
-        writeRegPair(ERDPTL, nextPacketPtr);
-
-        // read the next packet pointer
-        nextPacketPtr = readOp(ENC28J60_READ_BUF_MEM, 0);
-        nextPacketPtr |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
-
-        // read the packet length (see datasheet page 43)
-        len = readOp(ENC28J60_READ_BUF_MEM, 0);
-        len |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
-        len -= 4;   //remove the CRC count
-
-        // read the receive status (see datasheet page 43)
-        rxstat = readOp(ENC28J60_READ_BUF_MEM, 0);
-        rxstat |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
-
-        // decrement the packet counter indicate we are done with this packet
-        writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
-
-        // check CRC and symbol errors (see datasheet page 44, table 7-3):
-        // The ERXFCON.CRCEN is set by default. Normally we should not
-        // need to check this.
-        if((rxstat & 0x80) != 0) {
-            receivePkt.begin = readPtr;
-            receivePkt.size = len;
-            return UIP_RECEIVEBUFFERHANDLE;
-        }
-
-        // Move the RX read pointer to the start of the next received packet
-        // This frees the memory we just read out
-        setERXRDPT();
-    }
-
-    return(NOBLOCK);
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void Enc28J60Network::setERXRDPT(void) {
-    writeRegPair(ERXRDPTL, nextPacketPtr == RXSTART_INIT ? RXSTOP_INIT : nextPacketPtr - 1);
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-memaddress Enc28J60Network::blockSize(memhandle handle) {
-    return handle == UIP_RECEIVEBUFFERHANDLE ? receivePkt.size : blocks[handle].size;
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void Enc28J60Network::sendPacket(memhandle handle) {
-    memblock*   packet = &blocks[handle];
-    uint16_t    start = packet->begin - 1;
-    uint16_t    end = start + packet->size;
-
-    // backup data at control-byte position
-    uint8_t     data = readByte(start);
-    // write control-byte (if not 0 anyway)
-
-    if(data)
-        writeByte(start, 0);
-
-#ifdef ENC28J60DEBUG
-    pc.print("sendPacket(");
-    pc.print(handle);
-    pc.print(") [");
-    pc.print(start);
-    pc.print("-");
-    pc.print(end);
-    pc.println("]:");
-    for(uint16_t i = start; i <= end; i++) {
-        pc.print(readByte(i), HEX);
-        pc.print(" ");
-    }
-
-    pc.println();
-#endif
-    // TX start
-
-    writeRegPair(ETXSTL, start);
-
-    // Set the TXND pointer to correspond to the packet size given
-    writeRegPair(ETXNDL, end);
-
-    // send the contents of the transmit buffer onto the network
-    writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);
-
-    // Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12.
-    if((readReg(EIR) & EIR_TXERIF)) {
-        writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS);
-    }
-
-    //restore data on control-byte position
-    if(data)
-        writeByte(start, data);
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-uint16_t Enc28J60Network::setReadPtr(memhandle handle, memaddress position, uint16_t len) {
-    memblock*   packet = handle == UIP_RECEIVEBUFFERHANDLE ? &receivePkt : &blocks[handle];
-    memaddress  start = packet->begin + position;
-
-    writeRegPair(ERDPTL, start);
-
-    if(len > packet->size - position)
-        len = packet->size - position;
-    return len;
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-uint16_t Enc28J60Network::readPacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len) {
-    len = setReadPtr(handle, position, len);
-    readBuffer(len, buffer);
-    return len;
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-uint16_t Enc28J60Network::writePacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len) {
-    memblock*   packet = &blocks[handle];
-    uint16_t    start = packet->begin + position;
-
-    writeRegPair(EWRPTL, start);
-
-    if(len > packet->size - position)
-        len = packet->size - position;
-    writeBuffer(len, buffer);
-    return len;
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-uint8_t Enc28J60Network::readByte(uint16_t addr) {
-    uint8_t result;
-
-    writeRegPair(ERDPTL, addr);
-
-    _cs = 0;
-
-    // issue read command
-    _spi.write(ENC28J60_READ_BUF_MEM);
-
-    // read data
-    result = _spi.write(0x00);
-    _cs = 1;
-    return(result);
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void Enc28J60Network::writeByte(uint16_t addr, uint8_t data) {
-    writeRegPair(EWRPTL, addr);
-
-    _cs = 0;
-
-    // issue write command
-    _spi.write(ENC28J60_WRITE_BUF_MEM);
-
-    // write data
-    _spi.write(data);
-    _cs = 1;
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void Enc28J60Network::copyPacket
-(
-    memhandle   dest_pkt,
-    memaddress  dest_pos,
-    memhandle   src_pkt,
-    memaddress  src_pos,
-    uint16_t    len
-) {
-    memblock*   dest = &blocks[dest_pkt];
-    memblock*   src = src_pkt == UIP_RECEIVEBUFFERHANDLE ? &receivePkt : &blocks[src_pkt];
-    memblock_mv_cb(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();
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-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));
-    }
-    else {
-
-        // calculate address of last byte
-        len += src - 1;
-
-        /*  1. Appropriately program the EDMAST, EDMAND
-         and EDMADST register pairs. The EDMAST
-         registers should point to the first byte to copy
-         from, the EDMAND registers should point to the
-         last byte to copy and the EDMADST registers
-         should point to the first byte in the destination
-         range. The destination range will always be
-         linear, never wrapping at any values except from
-         8191 to 0 (the 8-Kbyte memory boundary).
-         Extreme care should be taken when
-         programming the start and end pointers to
-         prevent a never ending DMA operation which
-         would overwrite the entire 8-Kbyte buffer.
-         */
-        writeRegPair(EDMASTL, src);
-        writeRegPair(EDMADSTL, dest);
-
-        if((src <= RXSTOP_INIT) && (len > RXSTOP_INIT))
-            len -= (RXSTOP_INIT - RXSTART_INIT);
-        writeRegPair(EDMANDL, len);
-
-        /*
-         2. If an interrupt at the end of the copy process is
-         desired, set EIE.DMAIE and EIE.INTIE and
-         clear EIR.DMAIF.
-
-         3. Verify that ECON1.CSUMEN is clear. */
-        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);
-
-        // wait until runnig DMA is completed
-        while(readOp(ENC28J60_READ_CTRL_REG, ECON1) & ECON1_DMAST);
-    }
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void Enc28J60Network::freePacket(void) {
-    setERXRDPT();
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-uint8_t Enc28J60Network::readOp(uint8_t op, uint8_t address) {
-    uint8_t result;
-
-    _cs = 0;
-
-    // issue read command
-    _spi.write(op | (address & ADDR_MASK));
-
-    // read data
-    result = _spi.write(0x00);
-
-    // do dummy read if needed (for mac and mii, see datasheet page 29)
-    if(address & 0x80)
-        result = _spi.write(0x00);
-
-    // release CS
-    _cs = 1;
-    return(result);
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void Enc28J60Network::writeOp(uint8_t op, uint8_t address, uint8_t data) {
-    _cs = 0;
-
-    // issue write command
-    _spi.write(op | (address & ADDR_MASK));
-
-    // write data
-    _spi.write(data);
-    _cs = 1;
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void Enc28J60Network::readBuffer(uint16_t len, uint8_t* data) {
-    _cs = 0;
-
-    // issue read command
-    _spi.write(ENC28J60_READ_BUF_MEM);
-    while(len) {
-        len--;
-
-        // read data
-        *data = _spi.write(0x00);
-        data++;
-    }
-
-    *data = '\0';
-    _cs = 1;
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void Enc28J60Network::writeBuffer(uint16_t len, uint8_t* data) {
-    _cs = 0;
-
-    // issue write command
-    _spi.write(ENC28J60_WRITE_BUF_MEM);
-    while(len) {
-        len--;
-
-        // write data
-        _spi.write(*data);
-        data++;
-    }
-
-    _cs = 1;
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void Enc28J60Network::setBank(uint8_t address) {
-
-    // set the bank (if needed)
-
-    if((address & BANK_MASK) != bank) {
-
-        // set the bank
-        writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1 | ECON1_BSEL0));
-        writeOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK) >> 5);
-        bank = (address & BANK_MASK);
-    }
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-uint8_t Enc28J60Network::readReg(uint8_t address) {
-
-    // set the bank
-
-    setBank(address);
-
-    // do the read
-    return readOp(ENC28J60_READ_CTRL_REG, address);
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void Enc28J60Network::writeReg(uint8_t address, uint8_t data) {
-
-    // set the bank
-
-    setBank(address);
-
-    // do the write
-    writeOp(ENC28J60_WRITE_CTRL_REG, address, data);
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void Enc28J60Network::writeRegPair(uint8_t address, uint16_t data) {
-
-    // set the bank
-
-    setBank(address);
-
-    // do the write
-    writeOp(ENC28J60_WRITE_CTRL_REG, address, (data & 0xFF));
-    writeOp(ENC28J60_WRITE_CTRL_REG, address + 1, (data) >> 8);
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void Enc28J60Network::phyWrite(uint8_t address, uint16_t data) {
-
-    // set the PHY register address
-
-    writeReg(MIREGADR, address);
-
-    // write the PHY data
-    writeRegPair(MIWRL, data);
-
-    // wait until the PHY write completes
-    while(readReg(MISTAT) & MISTAT_BUSY) {
-        wait(0.000015);
-    }
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void Enc28J60Network::clkout(uint8_t clk) {
-
-    //setup clkout: 2 is 12.5MHz:
-
-    writeReg(ECOCON, clk & 0x7);
-}
-
-// read the revision of the chip:
-uint8_t Enc28J60Network::getRev(void) {
-    return(readReg(EREVID));
-}
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-uint16_t Enc28J60Network::chksum(uint16_t sum, memhandle handle, memaddress pos, uint16_t len) {
-    uint8_t     spdr;
-    uint16_t    t;
-    uint16_t    i;
-
-    len = setReadPtr(handle, pos, len) - 1;
-    _cs = 0;
-
-    // issue read command
-    spdr = _spi.write(ENC28J60_READ_BUF_MEM);
-    for(i = 0; i < len; i += 2) {
-
-        // read data
-        spdr = _spi.write(0x00);
-        t = spdr << 8;
-        spdr = _spi.write(0x00);
-        t += spdr;
-        sum += t;
-        if(sum < t) {
-            sum++;  /* carry */
-        }
-    }
-
-    if(i == len) {
-        spdr = _spi.write(0x00);
-        t = (spdr << 8) + 0;
-        sum += t;
-        if(sum < t) {
-            sum++;  /* carry */
-        }
-    }
-
-    _cs = 1;
-
-    /* Return sum in host byte order. */
-    return sum;
-}
-
+/*
+ Enc28J60Network.cpp
+ UIPEthernet network driver for Microchip ENC28J60 Ethernet Interface.
+
+ Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
+ All rights reserved.
+
+ based on enc28j60.c file from the AVRlib library by Pascal Stang.
+ For AVRlib See http://www.procyonengineering.com/
+
+ Modified (ported to mbed) by Zoltan Hudak <hudakz@inbox.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 <http://www.gnu.org/licenses/>.
+ */
+#include "Enc28J60Network.h"
+#include <mbed.h>
+
+extern "C"
+{
+#include "enc28j60.h"
+#include "uip.h"
+}
+#ifdef ENC28J60DEBUG
+    #include "HardwareSerial.h"
+#endif
+uint16_t Enc28J60Network::          nextPacketPtr;
+uint8_t Enc28J60Network::           bank = 0xff;
+
+struct memblock Enc28J60Network::   receivePkt;
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+Enc28J60Network::Enc28J60Network(PinName mosi, PinName miso, PinName sclk, PinName cs) :
+    MemoryPool(),
+    _spi(mosi, miso, sclk),
+    _cs(cs)
+{ }
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void Enc28J60Network::init(uint8_t* macaddr) {
+    MemoryPool::init();         // 1 byte in between RX_STOP_INIT and pool to allow prepending of controlbyte
+
+    // initialize SPI interface
+    _spi.format(8, 0);          // 8bit, mode 0
+    _spi.frequency(7000000);    // 7MHz
+    wait(1);                    // 1 second for stable state
+
+    // initialize I/O
+    _cs = 1;        // ss=0
+
+    // perform system reset
+    writeOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
+    wait_ms(50);
+
+    // check CLKRDY bit to see if reset is complete
+    // The CLKRDY does not work. See Rev. B4 Silicon Errata point. Just wait.
+    //while(!(readReg(ESTAT) & ESTAT_CLKRDY));
+    // do bank 0 stuff
+    // initialize receive buffer
+    // 16-bit transfers, must write low byte first
+    // set receive buffer start address
+    nextPacketPtr = RXSTART_INIT;
+
+    // Rx start
+    writeRegPair(ERXSTL, RXSTART_INIT);
+
+    // set receive pointer address
+    writeRegPair(ERXRDPTL, RXSTART_INIT);
+
+    // RX end
+    writeRegPair(ERXNDL, RXSTOP_INIT);
+
+    // TX start
+    //writeRegPair(ETXSTL, TXSTART_INIT);
+    // TX end
+    //writeRegPair(ETXNDL, TXSTOP_INIT);
+    // do bank 1 stuff, packet filter:
+    // For broadcast packets we allow only ARP packtets
+    // All other packets should be unicast only for our mac (MAADR)
+    //
+    // The pattern to match on is therefore
+    // Type     ETH.DST
+    // ARP      BROADCAST
+    // 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9
+    // in binary these poitions are:11 0000 0011 1111
+    // This is hex 303F->EPMM0=0x3f,EPMM1=0x30
+    //TODO define specific pattern to receive dhcp-broadcast packages instead of setting ERFCON_BCEN!
+    writeReg(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_PMEN | ERXFCON_BCEN);
+    writeRegPair(EPMM0, 0x303f);
+    writeRegPair(EPMCSL, 0xf7f9);
+
+    //
+    //
+    // do bank 2 stuff
+    // enable MAC receive
+    // and bring MAC out of reset (writes 0x00 to MACON2)
+    writeRegPair(MACON1, MACON1_MARXEN | MACON1_TXPAUS | MACON1_RXPAUS);
+
+    // enable automatic padding to 60bytes and CRC operations
+    writeOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN);
+
+    // set inter-frame gap (non-back-to-back)
+    writeRegPair(MAIPGL, 0x0C12);
+
+    // set inter-frame gap (back-to-back)
+    writeReg(MABBIPG, 0x12);
+
+    // Set the maximum packet size which the controller will accept
+    // Do not send packets longer than MAX_FRAMELEN:
+    writeRegPair(MAMXFLL, MAX_FRAMELEN);
+
+    // do bank 3 stuff
+    // write MAC address
+    // NOTE: MAC address in ENC28J60 is byte-backward
+    writeReg(MAADR5, macaddr[0]);
+    writeReg(MAADR4, macaddr[1]);
+    writeReg(MAADR3, macaddr[2]);
+    writeReg(MAADR2, macaddr[3]);
+    writeReg(MAADR1, macaddr[4]);
+    writeReg(MAADR0, macaddr[5]);
+
+    // no loopback of transmitted frames
+    phyWrite(PHCON2, PHCON2_HDLDIS);
+
+    // switch to bank 0
+    setBank(ECON1);
+
+    // enable interrutps
+    writeOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE | EIE_PKTIE);
+
+    // enable packet reception
+    writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
+
+    clkout(2);      // change clkout from 6.25MHz to 12.5MHz
+    wait_us(60);    // 60us
+
+    //Configure leds
+    phyWrite(PHLCON, 0x476);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+memhandle Enc28J60Network::receivePacket(void) {
+    uint8_t     rxstat;
+    uint16_t    len;
+    // check if a packet has been received and buffered
+
+    //if( !(readReg(EIR) & EIR_PKTIF) ){
+    // The above does not work. See Rev. B4 Silicon Errata point 6.
+    if(readReg(EPKTCNT) != 0) {
+        uint16_t    readPtr = nextPacketPtr +
+            6 > RXSTOP_INIT ? nextPacketPtr +
+            6 -
+            RXSTOP_INIT +
+            RXSTART_INIT : nextPacketPtr +
+            6;
+        // Set the read pointer to the start of the received packet
+
+        writeRegPair(ERDPTL, nextPacketPtr);
+
+        // read the next packet pointer
+        nextPacketPtr = readOp(ENC28J60_READ_BUF_MEM, 0);
+        nextPacketPtr |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
+
+        // read the packet length (see datasheet page 43)
+        len = readOp(ENC28J60_READ_BUF_MEM, 0);
+        len |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
+        len -= 4;   //remove the CRC count
+
+        // read the receive status (see datasheet page 43)
+        rxstat = readOp(ENC28J60_READ_BUF_MEM, 0);
+
+        //rxstat |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
+#ifdef ENC28J60DEBUG
+        Serial.print("receivePacket [");
+        Serial.print(readPtr, HEX);
+        Serial.print("-");
+        Serial.print((readPtr + len) % (RXSTOP_INIT + 1), HEX);
+        Serial.print("], next: ");
+        Serial.print(nextPacketPtr, HEX);
+        Serial.print(", stat: ");
+        Serial.print(rxstat, HEX);
+        Serial.print(", count: ");
+        Serial.print(readReg(EPKTCNT));
+        Serial.print(" -> ");
+        Serial.println((rxstat & 0x80) != 0 ? "OK" : "failed");
+#endif
+        // decrement the packet counter indicate we are done with this packet
+
+        writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
+
+        // check CRC and symbol errors (see datasheet page 44, table 7-3):
+        // The ERXFCON.CRCEN is set by default. Normally we should not
+        // need to check this.
+        if((rxstat & 0x80) != 0) {
+            receivePkt.begin = readPtr;
+            receivePkt.size = len;
+            return UIP_RECEIVEBUFFERHANDLE;
+        }
+
+        // Move the RX read pointer to the start of the next received packet
+        // This frees the memory we just read out
+        setERXRDPT();
+    }
+
+    return(NOBLOCK);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void Enc28J60Network::setERXRDPT(void) {
+    writeRegPair(ERXRDPTL, nextPacketPtr == RXSTART_INIT ? RXSTOP_INIT : nextPacketPtr - 1);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+memaddress Enc28J60Network::blockSize(memhandle handle) {
+    return handle == NOBLOCK ? 0 : handle == UIP_RECEIVEBUFFERHANDLE ? receivePkt.size : blocks[handle].size;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void Enc28J60Network::sendPacket(memhandle handle) {
+    memblock*   packet = &blocks[handle];
+    uint16_t    start = packet->begin - 1;
+    uint16_t    end = start + packet->size;
+
+    // backup data at control-byte position
+    uint8_t     data = readByte(start);
+    // write control-byte (if not 0 anyway)
+
+    if(data)
+        writeByte(start, 0);
+
+#ifdef ENC28J60DEBUG
+    Serial.print("sendPacket(");
+    Serial.print(handle);
+    Serial.print(") [");
+    Serial.print(start, HEX);
+    Serial.print("-");
+    Serial.print(end, HEX);
+    Serial.print("]: ");
+    for(uint16_t i = start; i <= end; i++) {
+        Serial.print(readByte(i), HEX);
+        Serial.print(" ");
+    }
+
+    Serial.println();
+#endif
+    // TX start
+
+    writeRegPair(ETXSTL, start);
+
+    // Set the TXND pointer to correspond to the packet size given
+    writeRegPair(ETXNDL, end);
+
+    // send the contents of the transmit buffer onto the network
+    writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);
+
+    // Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12.
+    if((readReg(EIR) & EIR_TXERIF)) {
+        writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS);
+    }
+
+    //restore data on control-byte position
+    if(data)
+        writeByte(start, data);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+uint16_t Enc28J60Network::setReadPtr(memhandle handle, memaddress position, uint16_t len) {
+    memblock*   packet = handle == UIP_RECEIVEBUFFERHANDLE ? &receivePkt : &blocks[handle];
+    memaddress  start = handle == UIP_RECEIVEBUFFERHANDLE
+    &&  packet->begin +
+        position > RXSTOP_INIT ? packet->begin +
+        position -
+        RXSTOP_INIT +
+        RXSTART_INIT : packet->begin +
+        position;
+
+    writeRegPair(ERDPTL, start);
+
+    if(len > packet->size - position)
+        len = packet->size - position;
+    return len;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+uint16_t Enc28J60Network::readPacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len) {
+    len = setReadPtr(handle, position, len);
+    readBuffer(len, buffer);
+    return len;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+uint16_t Enc28J60Network::writePacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len) {
+    memblock*   packet = &blocks[handle];
+    uint16_t    start = packet->begin + position;
+
+    writeRegPair(EWRPTL, start);
+
+    if(len > packet->size - position)
+        len = packet->size - position;
+    writeBuffer(len, buffer);
+    return len;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+uint8_t Enc28J60Network::readByte(uint16_t addr) {
+    uint8_t result;
+
+    writeRegPair(ERDPTL, addr);
+
+    _cs = 0;
+
+    // issue read command
+    _spi.write(ENC28J60_READ_BUF_MEM);
+
+    // read data
+    result = _spi.write(0x00);
+    _cs = 1;
+    return(result);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void Enc28J60Network::writeByte(uint16_t addr, uint8_t data) {
+    writeRegPair(EWRPTL, addr);
+
+    _cs = 0;
+
+    // issue write command
+    _spi.write(ENC28J60_WRITE_BUF_MEM);
+
+    // write data
+    _spi.write(data);
+    _cs = 1;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void Enc28J60Network::copyPacket
+(
+    memhandle   dest_pkt,
+    memaddress  dest_pos,
+    memhandle   src_pkt,
+    memaddress  src_pos,
+    uint16_t    len
+) {
+    memblock*   dest = &blocks[dest_pkt];
+    memblock*   src = src_pkt == UIP_RECEIVEBUFFERHANDLE ? &receivePkt : &blocks[src_pkt];
+    memaddress  start = src_pkt == UIP_RECEIVEBUFFERHANDLE
+    &&  src->begin +
+        src_pos > RXSTOP_INIT ? src->begin +
+        src_pos -
+        RXSTOP_INIT +
+        RXSTART_INIT : src->begin +
+        src_pos;
+    enc28J60_mempool_block_move_callback(dest->begin + dest_pos, start, len);
+
+    // Move the RX read pointer to the start of the next received packet
+    // This frees the memory we just read out
+    setERXRDPT();
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void Enc28J60Network::freePacket(void) {
+    setERXRDPT();
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+uint8_t Enc28J60Network::readOp(uint8_t op, uint8_t address) {
+    uint8_t result;
+
+    _cs = 0;
+
+    // issue read command
+    _spi.write(op | (address & ADDR_MASK));
+
+    // read data
+    result = _spi.write(0x00);
+
+    // do dummy read if needed (for mac and mii, see datasheet page 29)
+    if(address & 0x80)
+        result = _spi.write(0x00);
+
+    // release CS
+    _cs = 1;
+    return(result);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void Enc28J60Network::writeOp(uint8_t op, uint8_t address, uint8_t data) {
+    _cs = 0;
+
+    // issue write command
+    _spi.write(op | (address & ADDR_MASK));
+
+    // write data
+    _spi.write(data);
+    _cs = 1;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void Enc28J60Network::readBuffer(uint16_t len, uint8_t* data) {
+    _cs = 0;
+
+    // issue read command
+    _spi.write(ENC28J60_READ_BUF_MEM);
+    while(len) {
+        len--;
+
+        // read data
+        *data = _spi.write(0x00);
+        data++;
+    }
+
+    *data = '\0';
+    _cs = 1;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void Enc28J60Network::writeBuffer(uint16_t len, uint8_t* data) {
+    _cs = 0;
+
+    // issue write command
+    _spi.write(ENC28J60_WRITE_BUF_MEM);
+    while(len) {
+        len--;
+
+        // write data
+        _spi.write(*data);
+        data++;
+    }
+
+    _cs = 1;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void Enc28J60Network::setBank(uint8_t address) {
+
+    // set the bank (if needed)
+
+    if((address & BANK_MASK) != bank) {
+
+        // set the bank
+        writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1 | ECON1_BSEL0));
+        writeOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK) >> 5);
+        bank = (address & BANK_MASK);
+    }
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+uint8_t Enc28J60Network::readReg(uint8_t address) {
+
+    // set the bank
+
+    setBank(address);
+
+    // do the read
+    return readOp(ENC28J60_READ_CTRL_REG, address);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void Enc28J60Network::writeReg(uint8_t address, uint8_t data) {
+
+    // set the bank
+
+    setBank(address);
+
+    // do the write
+    writeOp(ENC28J60_WRITE_CTRL_REG, address, data);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void Enc28J60Network::writeRegPair(uint8_t address, uint16_t data) {
+
+    // set the bank
+
+    setBank(address);
+
+    // do the write
+    writeOp(ENC28J60_WRITE_CTRL_REG, address, (data & 0xFF));
+    writeOp(ENC28J60_WRITE_CTRL_REG, address + 1, (data) >> 8);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void Enc28J60Network::phyWrite(uint8_t address, uint16_t data) {
+
+    // set the PHY register address
+
+    writeReg(MIREGADR, address);
+
+    // write the PHY data
+    writeRegPair(MIWRL, data);
+
+    // wait until the PHY write completes
+    while(readReg(MISTAT) & MISTAT_BUSY) {
+        wait_us(15);
+    }
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+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) {
+        wait_us(15);
+    }   //and MIRDH
+
+    writeReg(MICMD, 0);
+    return(readReg(MIRDL) | readReg(MIRDH) << 8);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void Enc28J60Network::clkout(uint8_t clk) {
+
+    //setup clkout: 2 is 12.5MHz:
+
+    writeReg(ECOCON, clk & 0x7);
+}
+
+// read the revision of the chip:
+uint8_t Enc28J60Network::getrev(void) {
+    return(readReg(EREVID));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+uint16_t Enc28J60Network::chksum(uint16_t sum, memhandle handle, memaddress pos, uint16_t len) {
+    uint8_t     spdr;
+    uint16_t    t;
+    uint16_t    i;
+
+    len = setReadPtr(handle, pos, len) - 1;
+    _cs = 0;
+
+    // issue read command
+    spdr = _spi.write(ENC28J60_READ_BUF_MEM);
+    for(i = 0; i < len; i += 2) {
+
+        // read data
+        spdr = _spi.write(0x00);
+        t = spdr << 8;
+        spdr = _spi.write(0x00);
+        t += spdr;
+        sum += t;
+        if(sum < t) {
+            sum++;  /* carry */
+        }
+    }
+
+    if(i == len) {
+        spdr = _spi.write(0x00);
+        t = (spdr << 8) + 0;
+        sum += t;
+        if(sum < t) {
+            sum++;  /* carry */
+        }
+    }
+
+    _cs = 1;
+
+    /* Return sum in host byte order. */
+    return sum;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void Enc28J60Network::powerOff(void) {
+    writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_RXEN);
+    wait_ms(50);
+    writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_VRPS);
+    wait_ms(50);
+    writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PWRSV);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void Enc28J60Network::powerOn(void) {
+    writeOp(ENC28J60_BIT_FIELD_CLR, ECON2, ECON2_PWRSV);
+    wait_ms(50);
+    writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
+    wait_ms(50);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+bool Enc28J60Network::linkStatus(void) {
+    return(phyRead(PHSTAT2) & 0x0400) > 0;
+}
--- a/utility/Enc28J60Network.h	Sat Dec 20 11:10:40 2014 +0000
+++ b/utility/Enc28J60Network.h	Sun Mar 08 20:26:56 2015 +0000
@@ -1,81 +1,85 @@
-/*
- Enc28J60Network.h
- UIPEthernet network driver for Microchip ENC28J60 Ethernet Interface.
-
- Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
- All rights reserved.
-
- inspired by enc28j60.c file from the AVRlib library by Pascal Stang.
- For AVRlib See http://www.procyonengineering.com/
-
- Modified (ported to mbed) by Zoltan Hudak <hudakz@inbox.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 <http://www.gnu.org/licenses/>.
- */
-#ifndef ENC28J60NETWORK_H_
-    #define ENC28J60NETWORK_H_
-
-    #include "mbed.h"
-    #include "mempool.h"
-
-    #define UIP_RECEIVEBUFFERHANDLE 0xff
-
-//#define ENC28J60DEBUG
-
-/*
- * Received from ip-header, arp etc...
- * when tcp/udp -> tcp/udp-callback -> assign new packet to connection
- */
-class Enc28J60Network :
-    public MemoryPool
-{
-private:
-    SPI             _spi;
-    DigitalOut      _cs;
-    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);
-    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(PinName mosi, PinName miso, PinName sclk, PinName cs);
-    void        init(uint8_t* macaddr);
-    memhandle   receivePacket(void);
-    void        freePacket(void);
-    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_ */
-
+/*
+ Enc28J60Network.h
+ UIPEthernet network driver for Microchip ENC28J60 Ethernet Interface.
+
+ Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
+ All rights reserved.
+
+ based on enc28j60.c file from the AVRlib library by Pascal Stang.
+ For AVRlib See http://www.procyonengineering.com/
+
+ Modified (ported to mbed) by Zoltan Hudak <hudakz@inbox.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 <http://www.gnu.org/licenses/>.
+ */
+#ifndef Enc28J60Network_H_
+    #define Enc28J60Network_H_
+
+    #include <mbed.h>
+    #include "mempool.h"
+
+    #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:
+    SPI                     _spi;
+    DigitalOut              _cs;
+    static uint16_t         nextPacketPtr;
+    static uint8_t          bank;
+
+    static 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);
+    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);
+    uint16_t                phyRead(uint8_t address);
+    void                    clkout(uint8_t clk);
+
+    friend void             enc28J60_mempool_block_move_callback(memaddress, memaddress, memaddress);
+public:
+    Enc28J60Network(PinName mosi, PinName miso, PinName sclk, PinName cs);
+    uint8_t     getrev(void);
+    void        powerOn(void);
+    void        powerOff(void);
+    bool        linkStatus(void);
+
+    void        init(uint8_t* macaddr);
+    memhandle   receivePacket(void);
+    void        freePacket(void);
+    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 /* Enc28J60NetworkClass_H_ */
--- a/utility/Server.h	Sat Dec 20 11:10:40 2014 +0000
+++ b/utility/Server.h	Sun Mar 08 20:26:56 2015 +0000
@@ -3,7 +3,7 @@
   Copyright (c) 2011 Adrian McEwen.  All right reserved.
 
   Modified (ported to mbed) by Zoltan Hudak <hudakz@inbox.com>
-  
+
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
@@ -21,7 +21,6 @@
 #ifndef server_h
     #define server_h
 
-//class Server : public Print {
 class   Server
 {
 public:
--- a/utility/Udp.h	Sat Dec 20 11:10:40 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
- *  Udp.cpp: Library to send/receive UDP packets.
- *
- * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
- * 1) UDP does not guarantee the order in which assembled UDP packets are received. This
- * might not happen often in practice, but in larger network topologies, a UDP
- * packet can be received out of sequence. 
- * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
- * aware of it. Again, this may not be a concern in practice on small local networks.
- * For more information, see http://www.cafeaulait.org/course/week12/35.html
- *
- * MIT License:
- * Copyright (c) 2008 Bjoern Hartmann
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- * bjoern@cs.stanford.edu 12/30/2008
- */
-#ifndef udp_h
-    #define udp_h
-
-    #include <mbed.h>
-    #include <IPAddress.h>
-
-//class UDP : public Stream {
-class   UDP
-{
-public:
-    virtual uint8_t     begin(uint16_t) = 0;    // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
-    virtual void        stop(void) = 0;         // 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
-    virtual int         beginPacket(IPAddress ip, uint16_t port) = 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
-    virtual int         beginPacket(const char* host, uint16_t port) = 0;
-
-    // Finish off this packet and send it
-    // Returns 1 if the packet was sent successfully, 0 if there was an error
-    virtual int         endPacket(void) = 0;
-
-    // Write a single byte into the packet
-    virtual size_t      write(uint8_t) = 0;
-
-    // Write size bytes from buffer into the packet
-    virtual size_t      write(const uint8_t* buffer, size_t size) = 0;
-
-    // Start processing the next available incoming packet
-    // Returns the size of the packet in bytes, or 0 if no packets are available
-    virtual int         parsePacket(void) = 0;
-
-    // Number of bytes remaining in the current packet
-    virtual int         available(void) = 0;
-
-    // Read a single byte from the current packet
-    virtual int         read(void) = 0;
-
-    // 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
-    virtual int         read(unsigned char* buffer, size_t len) = 0;
-
-    // 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
-    virtual int         read(char* buffer, size_t len) = 0;
-
-    // Return the next byte from the current packet without moving on to the next byte
-    virtual int         peek(void) = 0;
-    virtual void        flush(void) = 0;        // Finish reading the current packet
-
-    // Return the IP address of the host who sent the current incoming packet
-    virtual IPAddress   remoteIP(void) = 0;
-
-    // Return the port of the host who sent the current incoming packet
-    virtual uint16_t    remotePort(void) = 0;
-protected:
-    uint8_t*    rawIPAddress(IPAddress& addr)   { return addr.raw_address(); };
-};
-#endif
--- a/utility/clock-arch.c	Sat Dec 20 11:10:40 2014 +0000
+++ b/utility/clock-arch.c	Sun Mar 08 20:26:56 2015 +0000
@@ -1,35 +1,33 @@
-/*
- clock-arch.c - mbed implementation of uIP clock device.
- Copyright (c) 2010 Adam Nielsen <malvineous@shikadi.net>
- All rights reserved.
-
- Modified (ported to mbed) by Zoltan Hudak <hudakz@inbox.com>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-#include <time.h>
-#include "clock-arch.h"
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-clock_time_t clock_time(void) {
-    return(clock_time_t) time(NULL);
-}
-
-
+/*
+ clock-arch.c - mbed implementation of uIP clock device.
+ Copyright (c) 2010 Adam Nielsen <malvineous@shikadi.net>
+ All rights reserved.
+
+ Modified (ported to mbed) by Zoltan Hudak <hudakz@inbox.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <time.h>
+#include "clock-arch.h"
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+clock_time_t clock_time(void) {
+    return(clock_time_t) time(NULL);
+}
--- a/utility/enc28j60.h	Sat Dec 20 11:10:40 2014 +0000
+++ b/utility/enc28j60.h	Sun Mar 08 20:26:56 2015 +0000
@@ -12,272 +12,246 @@
 *
 *
 *****************************************************************************/
+
 #ifndef ENC28J60_H
-    #define ENC28J60_H
-    #include <inttypes.h>
+#define ENC28J60_H
+#include <inttypes.h>
 
 // ENC28J60 Control Registers
-
 // Control register definitions are a combination of address,
 // bank number, and Ethernet/MAC/PHY indicator bits.
 // - Register address        (bits 0-4)
 // - Bank number        (bits 5-6)
 // - MAC/PHY indicator        (bit 7)
-    #define ADDR_MASK   0x1F
-    #define BANK_MASK   0x60
-    #define SPRD_MASK   0x80
+#define ADDR_MASK        0x1F
+#define BANK_MASK        0x60
+#define SPRD_MASK        0x80
 // All-bank registers
-
-    #define EIE     0x1B
-    #define EIR     0x1C
-    #define ESTAT   0x1D
-    #define ECON2   0x1E
-    #define ECON1   0x1F
+#define EIE              0x1B
+#define EIR              0x1C
+#define ESTAT            0x1D
+#define ECON2            0x1E
+#define ECON1            0x1F
 // Bank 0 registers
-
-    #define ERDPTL      (0x00 | 0x00)
-    #define ERDPTH      (0x01 | 0x00)
-    #define EWRPTL      (0x02 | 0x00)
-    #define EWRPTH      (0x03 | 0x00)
-    #define ETXSTL      (0x04 | 0x00)
-    #define ETXSTH      (0x05 | 0x00)
-    #define ETXNDL      (0x06 | 0x00)
-    #define ETXNDH      (0x07 | 0x00)
-    #define ERXSTL      (0x08 | 0x00)
-    #define ERXSTH      (0x09 | 0x00)
-    #define ERXNDL      (0x0A | 0x00)
-    #define ERXNDH      (0x0B | 0x00)
-    #define ERXRDPTL    (0x0C | 0x00)
-    #define ERXRDPTH    (0x0D | 0x00)
-    #define ERXWRPTL    (0x0E | 0x00)
-    #define ERXWRPTH    (0x0F | 0x00)
-    #define EDMASTL     (0x10 | 0x00)
-    #define EDMASTH     (0x11 | 0x00)
-    #define EDMANDL     (0x12 | 0x00)
-    #define EDMANDH     (0x13 | 0x00)
-    #define EDMADSTL    (0x14 | 0x00)
-    #define EDMADSTH    (0x15 | 0x00)
-    #define EDMACSL     (0x16 | 0x00)
-    #define EDMACSH     (0x17 | 0x00)
+#define ERDPTL           (0x00|0x00)
+#define ERDPTH           (0x01|0x00)
+#define EWRPTL           (0x02|0x00)
+#define EWRPTH           (0x03|0x00)
+#define ETXSTL           (0x04|0x00)
+#define ETXSTH           (0x05|0x00)
+#define ETXNDL           (0x06|0x00)
+#define ETXNDH           (0x07|0x00)
+#define ERXSTL           (0x08|0x00)
+#define ERXSTH           (0x09|0x00)
+#define ERXNDL           (0x0A|0x00)
+#define ERXNDH           (0x0B|0x00)
+#define ERXRDPTL         (0x0C|0x00)
+#define ERXRDPTH         (0x0D|0x00)
+#define ERXWRPTL         (0x0E|0x00)
+#define ERXWRPTH         (0x0F|0x00)
+#define EDMASTL          (0x10|0x00)
+#define EDMASTH          (0x11|0x00)
+#define EDMANDL          (0x12|0x00)
+#define EDMANDH          (0x13|0x00)
+#define EDMADSTL         (0x14|0x00)
+#define EDMADSTH         (0x15|0x00)
+#define EDMACSL          (0x16|0x00)
+#define EDMACSH          (0x17|0x00)
 // Bank 1 registers
-
-    #define EHT0    (0x00 | 0x20)
-    #define EHT1    (0x01 | 0x20)
-    #define EHT2    (0x02 | 0x20)
-    #define EHT3    (0x03 | 0x20)
-    #define EHT4    (0x04 | 0x20)
-    #define EHT5    (0x05 | 0x20)
-    #define EHT6    (0x06 | 0x20)
-    #define EHT7    (0x07 | 0x20)
-    #define EPMM0   (0x08 | 0x20)
-    #define EPMM1   (0x09 | 0x20)
-    #define EPMM2   (0x0A | 0x20)
-    #define EPMM3   (0x0B | 0x20)
-    #define EPMM4   (0x0C | 0x20)
-    #define EPMM5   (0x0D | 0x20)
-    #define EPMM6   (0x0E | 0x20)
-    #define EPMM7   (0x0F | 0x20)
-    #define EPMCSL  (0x10 | 0x20)
-    #define EPMCSH  (0x11 | 0x20)
-    #define EPMOL   (0x14 | 0x20)
-    #define EPMOH   (0x15 | 0x20)
-    #define EWOLIE  (0x16 | 0x20)
-    #define EWOLIR  (0x17 | 0x20)
-    #define ERXFCON (0x18 | 0x20)
-    #define EPKTCNT (0x19 | 0x20)
+#define EHT0             (0x00|0x20)
+#define EHT1             (0x01|0x20)
+#define EHT2             (0x02|0x20)
+#define EHT3             (0x03|0x20)
+#define EHT4             (0x04|0x20)
+#define EHT5             (0x05|0x20)
+#define EHT6             (0x06|0x20)
+#define EHT7             (0x07|0x20)
+#define EPMM0            (0x08|0x20)
+#define EPMM1            (0x09|0x20)
+#define EPMM2            (0x0A|0x20)
+#define EPMM3            (0x0B|0x20)
+#define EPMM4            (0x0C|0x20)
+#define EPMM5            (0x0D|0x20)
+#define EPMM6            (0x0E|0x20)
+#define EPMM7            (0x0F|0x20)
+#define EPMCSL           (0x10|0x20)
+#define EPMCSH           (0x11|0x20)
+#define EPMOL            (0x14|0x20)
+#define EPMOH            (0x15|0x20)
+#define EWOLIE           (0x16|0x20)
+#define EWOLIR           (0x17|0x20)
+#define ERXFCON          (0x18|0x20)
+#define EPKTCNT          (0x19|0x20)
 // Bank 2 registers
-
-    #define MACON1      (0x00 | 0x40 | 0x80)
-    #define MACON2      (0x01 | 0x40 | 0x80)
-    #define MACON3      (0x02 | 0x40 | 0x80)
-    #define MACON4      (0x03 | 0x40 | 0x80)
-    #define MABBIPG     (0x04 | 0x40 | 0x80)
-    #define MAIPGL      (0x06 | 0x40 | 0x80)
-    #define MAIPGH      (0x07 | 0x40 | 0x80)
-    #define MACLCON1    (0x08 | 0x40 | 0x80)
-    #define MACLCON2    (0x09 | 0x40 | 0x80)
-    #define MAMXFLL     (0x0A | 0x40 | 0x80)
-    #define MAMXFLH     (0x0B | 0x40 | 0x80)
-    #define MAPHSUP     (0x0D | 0x40 | 0x80)
-    #define MICON       (0x11 | 0x40 | 0x80)
-    #define MICMD       (0x12 | 0x40 | 0x80)
-    #define MIREGADR    (0x14 | 0x40 | 0x80)
-    #define MIWRL       (0x16 | 0x40 | 0x80)
-    #define MIWRH       (0x17 | 0x40 | 0x80)
-    #define MIRDL       (0x18 | 0x40 | 0x80)
-    #define MIRDH       (0x19 | 0x40 | 0x80)
+#define MACON1           (0x00|0x40|0x80)
+#define MACON2           (0x01|0x40|0x80)
+#define MACON3           (0x02|0x40|0x80)
+#define MACON4           (0x03|0x40|0x80)
+#define MABBIPG          (0x04|0x40|0x80)
+#define MAIPGL           (0x06|0x40|0x80)
+#define MAIPGH           (0x07|0x40|0x80)
+#define MACLCON1         (0x08|0x40|0x80)
+#define MACLCON2         (0x09|0x40|0x80)
+#define MAMXFLL          (0x0A|0x40|0x80)
+#define MAMXFLH          (0x0B|0x40|0x80)
+#define MAPHSUP          (0x0D|0x40|0x80)
+#define MICON            (0x11|0x40|0x80)
+#define MICMD            (0x12|0x40|0x80)
+#define MIREGADR         (0x14|0x40|0x80)
+#define MIWRL            (0x16|0x40|0x80)
+#define MIWRH            (0x17|0x40|0x80)
+#define MIRDL            (0x18|0x40|0x80)
+#define MIRDH            (0x19|0x40|0x80)
 // Bank 3 registers
-
-    #define MAADR1  (0x00 | 0x60 | 0x80)
-    #define MAADR0  (0x01 | 0x60 | 0x80)
-    #define MAADR3  (0x02 | 0x60 | 0x80)
-    #define MAADR2  (0x03 | 0x60 | 0x80)
-    #define MAADR5  (0x04 | 0x60 | 0x80)
-    #define MAADR4  (0x05 | 0x60 | 0x80)
-    #define EBSTSD  (0x06 | 0x60)
-    #define EBSTCON (0x07 | 0x60)
-    #define EBSTCSL (0x08 | 0x60)
-    #define EBSTCSH (0x09 | 0x60)
-    #define MISTAT  (0x0A | 0x60 | 0x80)
-    #define EREVID  (0x12 | 0x60)
-    #define ECOCON  (0x15 | 0x60)
-    #define EFLOCON (0x17 | 0x60)
-    #define EPAUSL  (0x18 | 0x60)
-    #define EPAUSH  (0x19 | 0x60)
+#define MAADR1           (0x00|0x60|0x80)
+#define MAADR0           (0x01|0x60|0x80)
+#define MAADR3           (0x02|0x60|0x80)
+#define MAADR2           (0x03|0x60|0x80)
+#define MAADR5           (0x04|0x60|0x80)
+#define MAADR4           (0x05|0x60|0x80)
+#define EBSTSD           (0x06|0x60)
+#define EBSTCON          (0x07|0x60)
+#define EBSTCSL          (0x08|0x60)
+#define EBSTCSH          (0x09|0x60)
+#define MISTAT           (0x0A|0x60|0x80)
+#define EREVID           (0x12|0x60)
+#define ECOCON           (0x15|0x60)
+#define EFLOCON          (0x17|0x60)
+#define EPAUSL           (0x18|0x60)
+#define EPAUSH           (0x19|0x60)
 // PHY registers
-
-    #define PHCON1  0x00
-    #define PHSTAT1 0x01
-    #define PHHID1  0x02
-    #define PHHID2  0x03
-    #define PHCON2  0x10
-    #define PHSTAT2 0x11
-    #define PHIE    0x12
-    #define PHIR    0x13
-    #define PHLCON  0x14
+#define PHCON1           0x00
+#define PHSTAT1          0x01
+#define PHHID1           0x02
+#define PHHID2           0x03
+#define PHCON2           0x10
+#define PHSTAT2          0x11
+#define PHIE             0x12
+#define PHIR             0x13
+#define PHLCON           0x14
 
 // ENC28J60 ERXFCON Register Bit Definitions
-
-    #define ERXFCON_UCEN    0x80
-    #define ERXFCON_ANDOR   0x40
-    #define ERXFCON_CRCEN   0x20
-    #define ERXFCON_PMEN    0x10
-    #define ERXFCON_MPEN    0x08
-    #define ERXFCON_HTEN    0x04
-    #define ERXFCON_MCEN    0x02
-    #define ERXFCON_BCEN    0x01
+#define ERXFCON_UCEN     0x80
+#define ERXFCON_ANDOR    0x40
+#define ERXFCON_CRCEN    0x20
+#define ERXFCON_PMEN     0x10
+#define ERXFCON_MPEN     0x08
+#define ERXFCON_HTEN     0x04
+#define ERXFCON_MCEN     0x02
+#define ERXFCON_BCEN     0x01
 // ENC28J60 EIE Register Bit Definitions
-
-    #define EIE_INTIE   0x80
-    #define EIE_PKTIE   0x40
-    #define EIE_DMAIE   0x20
-    #define EIE_LINKIE  0x10
-    #define EIE_TXIE    0x08
-    #define EIE_WOLIE   0x04
-    #define EIE_TXERIE  0x02
-    #define EIE_RXERIE  0x01
+#define EIE_INTIE        0x80
+#define EIE_PKTIE        0x40
+#define EIE_DMAIE        0x20
+#define EIE_LINKIE       0x10
+#define EIE_TXIE         0x08
+#define EIE_WOLIE        0x04
+#define EIE_TXERIE       0x02
+#define EIE_RXERIE       0x01
 // ENC28J60 EIR Register Bit Definitions
-
-    #define EIR_PKTIF   0x40
-    #define EIR_DMAIF   0x20
-    #define EIR_LINKIF  0x10
-    #define EIR_TXIF    0x08
-    #define EIR_WOLIF   0x04
-    #define EIR_TXERIF  0x02
-    #define EIR_RXERIF  0x01
+#define EIR_PKTIF        0x40
+#define EIR_DMAIF        0x20
+#define EIR_LINKIF       0x10
+#define EIR_TXIF         0x08
+#define EIR_WOLIF        0x04
+#define EIR_TXERIF       0x02
+#define EIR_RXERIF       0x01
 // ENC28J60 ESTAT Register Bit Definitions
-
-    #define ESTAT_INT       0x80
-    #define ESTAT_LATECOL   0x10
-    #define ESTAT_RXBUSY    0x04
-    #define ESTAT_TXABRT    0x02
-    #define ESTAT_CLKRDY    0x01
+#define ESTAT_INT        0x80
+#define ESTAT_LATECOL    0x10
+#define ESTAT_RXBUSY     0x04
+#define ESTAT_TXABRT     0x02
+#define ESTAT_CLKRDY     0x01
 // ENC28J60 ECON2 Register Bit Definitions
-
-    #define ECON2_AUTOINC   0x80
-    #define ECON2_PKTDEC    0x40
-    #define ECON2_PWRSV     0x20
-    #define ECON2_VRPS      0x08
+#define ECON2_AUTOINC    0x80
+#define ECON2_PKTDEC     0x40
+#define ECON2_PWRSV      0x20
+#define ECON2_VRPS       0x08
 // ENC28J60 ECON1 Register Bit Definitions
-
-    #define ECON1_TXRST     0x80
-    #define ECON1_RXRST     0x40
-    #define ECON1_DMAST     0x20
-    #define ECON1_CSUMEN    0x10
-    #define ECON1_TXRTS     0x08
-    #define ECON1_RXEN      0x04
-    #define ECON1_BSEL1     0x02
-    #define ECON1_BSEL0     0x01
+#define ECON1_TXRST      0x80
+#define ECON1_RXRST      0x40
+#define ECON1_DMAST      0x20
+#define ECON1_CSUMEN     0x10
+#define ECON1_TXRTS      0x08
+#define ECON1_RXEN       0x04
+#define ECON1_BSEL1      0x02
+#define ECON1_BSEL0      0x01
 // ENC28J60 MACON1 Register Bit Definitions
-
-    #define MACON1_LOOPBK   0x10
-    #define MACON1_TXPAUS   0x08
-    #define MACON1_RXPAUS   0x04
-    #define MACON1_PASSALL  0x02
-    #define MACON1_MARXEN   0x01
+#define MACON1_LOOPBK    0x10
+#define MACON1_TXPAUS    0x08
+#define MACON1_RXPAUS    0x04
+#define MACON1_PASSALL   0x02
+#define MACON1_MARXEN    0x01
 // ENC28J60 MACON2 Register Bit Definitions
-
-    #define MACON2_MARST    0x80
-    #define MACON2_RNDRST   0x40
-    #define MACON2_MARXRST  0x08
-    #define MACON2_RFUNRST  0x04
-    #define MACON2_MATXRST  0x02
-    #define MACON2_TFUNRST  0x01
+#define MACON2_MARST     0x80
+#define MACON2_RNDRST    0x40
+#define MACON2_MARXRST   0x08
+#define MACON2_RFUNRST   0x04
+#define MACON2_MATXRST   0x02
+#define MACON2_TFUNRST   0x01
 // ENC28J60 MACON3 Register Bit Definitions
-
-    #define MACON3_PADCFG2  0x80
-    #define MACON3_PADCFG1  0x40
-    #define MACON3_PADCFG0  0x20
-    #define MACON3_TXCRCEN  0x10
-    #define MACON3_PHDRLEN  0x08
-    #define MACON3_HFRMLEN  0x04
-    #define MACON3_FRMLNEN  0x02
-    #define MACON3_FULDPX   0x01
+#define MACON3_PADCFG2   0x80
+#define MACON3_PADCFG1   0x40
+#define MACON3_PADCFG0   0x20
+#define MACON3_TXCRCEN   0x10
+#define MACON3_PHDRLEN   0x08
+#define MACON3_HFRMLEN   0x04
+#define MACON3_FRMLNEN   0x02
+#define MACON3_FULDPX    0x01
 // ENC28J60 MICMD Register Bit Definitions
-
-    #define MICMD_MIISCAN   0x02
-    #define MICMD_MIIRD     0x01
+#define MICMD_MIISCAN    0x02
+#define MICMD_MIIRD      0x01
 // ENC28J60 MISTAT Register Bit Definitions
-
-    #define MISTAT_NVALID   0x04
-    #define MISTAT_SCAN     0x02
-    #define MISTAT_BUSY     0x01
+#define MISTAT_NVALID    0x04
+#define MISTAT_SCAN      0x02
+#define MISTAT_BUSY      0x01
 // ENC28J60 PHY PHCON1 Register Bit Definitions
-
-    #define PHCON1_PRST     0x8000
-    #define PHCON1_PLOOPBK  0x4000
-    #define PHCON1_PPWRSV   0x0800
-    #define PHCON1_PDPXMD   0x0100
+#define PHCON1_PRST      0x8000
+#define PHCON1_PLOOPBK   0x4000
+#define PHCON1_PPWRSV    0x0800
+#define PHCON1_PDPXMD    0x0100
 // ENC28J60 PHY PHSTAT1 Register Bit Definitions
-
-    #define PHSTAT1_PFDPX   0x1000
-    #define PHSTAT1_PHDPX   0x0800
-    #define PHSTAT1_LLSTAT  0x0004
-    #define PHSTAT1_JBSTAT  0x0002
+#define PHSTAT1_PFDPX    0x1000
+#define PHSTAT1_PHDPX    0x0800
+#define PHSTAT1_LLSTAT   0x0004
+#define PHSTAT1_JBSTAT   0x0002
 // ENC28J60 PHY PHCON2 Register Bit Definitions
-
-    #define PHCON2_FRCLINK  0x4000
-    #define PHCON2_TXDIS    0x2000
-    #define PHCON2_JABBER   0x0400
-    #define PHCON2_HDLDIS   0x0100
+#define PHCON2_FRCLINK   0x4000
+#define PHCON2_TXDIS     0x2000
+#define PHCON2_JABBER    0x0400
+#define PHCON2_HDLDIS    0x0100
 
 // ENC28J60 Packet Control Byte Bit Definitions
-
-    #define PKTCTRL_PHUGEEN     0x08
-    #define PKTCTRL_PPADEN      0x04
-    #define PKTCTRL_PCRCEN      0x02
-    #define PKTCTRL_POVERRIDE   0x01
+#define PKTCTRL_PHUGEEN  0x08
+#define PKTCTRL_PPADEN   0x04
+#define PKTCTRL_PCRCEN   0x02
+#define PKTCTRL_POVERRIDE 0x01
 
 // SPI operation codes
+#define ENC28J60_READ_CTRL_REG       0x00
+#define ENC28J60_READ_BUF_MEM        0x3A
+#define ENC28J60_WRITE_CTRL_REG      0x40
+#define ENC28J60_WRITE_BUF_MEM       0x7A
+#define ENC28J60_BIT_FIELD_SET       0x80
+#define ENC28J60_BIT_FIELD_CLR       0xA0
+#define ENC28J60_SOFT_RESET          0xFF
 
-    #define ENC28J60_READ_CTRL_REG  0x00
-    #define ENC28J60_READ_BUF_MEM   0x3A
-    #define ENC28J60_WRITE_CTRL_REG 0x40
-    #define ENC28J60_WRITE_BUF_MEM  0x7A
-    #define ENC28J60_BIT_FIELD_SET  0x80
-    #define ENC28J60_BIT_FIELD_CLR  0xA0
-    #define ENC28J60_SOFT_RESET     0xFF
 
 // The RXSTART_INIT should be zero. See Rev. B4 Silicon Errata
-
 // buffer boundaries applied to internal 8K ram
 // the entire available packet buffer space is allocated
 //
 // start with recbuf at 0/
-    #define RXSTART_INIT    0x0
+#define RXSTART_INIT     0x0
 // receive buffer end. make sure this is an odd value ( See Rev. B1,B4,B5,B7 Silicon Errata 'Memory (Ethernet Buffer)')
-
-    #define RXSTOP_INIT (0x1FFF - 0x1800)
+#define RXSTOP_INIT      (0x1FFF-0x1800)
 // start TX buffer RXSTOP_INIT+1
-
-    #define TXSTART_INIT    (RXSTOP_INIT + 1)
+#define TXSTART_INIT     (RXSTOP_INIT+1)
 // stp TX buffer at end of mem
+#define TXSTOP_INIT      0x1FFF
+//
+// max frame length which the conroller will accept:
+#define        MAX_FRAMELEN        1500        // (note: maximum ethernet frame length would be 1518)
+//#define MAX_FRAMELEN     600
 
-    #define TXSTOP_INIT 0x1FFF
-//
-
-// max frame length which the conroller will accept:
-    #define MAX_FRAMELEN    1500    // (note: maximum ethernet frame length would be 1518)
-
-//#define MAX_FRAMELEN     600
 #endif
--- a/utility/mempool.cpp	Sat Dec 20 11:10:40 2014 +0000
+++ b/utility/mempool.cpp	Sun Mar 08 20:26:56 2015 +0000
@@ -21,18 +21,19 @@
 
 #define POOLOFFSET  1
 
+struct memblock MemoryPool::    blocks[MEMPOOL_NUM_MEMBLOCKS + 1];
+
 /**
  * @brief
  * @note
  * @param
  * @retval
  */
-MemoryPool::MemoryPool(memaddress start, memaddress size) {
+void MemoryPool::init(void) {
     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;
 }
 
 /**
@@ -45,12 +46,12 @@
     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) -
+        memaddress  freesize = (next == NOBLOCK ? blocks[POOLSTART].begin + MEMPOOL_SIZE : blocks[next].begin) -
             block->begin -
             block->size;
         if(freesize == size) {
@@ -86,8 +87,8 @@
             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;
             }
@@ -95,7 +96,7 @@
             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;
@@ -104,7 +105,7 @@
 found:
     {
         block = &blocks[POOLOFFSET];
-        for(cur = POOLOFFSET; cur < NUM_MEMBLOCKS + POOLOFFSET; cur++) {
+        for(cur = POOLOFFSET; cur < MEMPOOL_NUM_MEMBLOCKS + POOLOFFSET; cur++) {
             if(block->size) {
                 block++;
                 continue;
@@ -133,6 +134,9 @@
  * @retval
  */
 void MemoryPool::freeBlock(memhandle handle) {
+    if(handle == NOBLOCK)
+        return;
+
     memblock*   b = &blocks[POOLSTART];
 
     do
--- a/utility/mempool.h	Sat Dec 20 11:10:40 2014 +0000
+++ b/utility/mempool.h	Sun Mar 08 20:26:56 2015 +0000
@@ -26,16 +26,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;
@@ -49,17 +39,13 @@
     friend class    MemoryPoolTest;
     #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(void);
+    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
--- a/utility/mempool_conf.h	Sat Dec 20 11:10:40 2014 +0000
+++ b/utility/mempool_conf.h	Sun Mar 08 20:26:56 2015 +0000
@@ -4,6 +4,7 @@
 extern "C"
 {
     #include "uipopt.h"
+    #include "enc28j60.h"
 }
     #include <inttypes.h>
 
@@ -15,11 +16,16 @@
     #else
         #define NUM_TCP_MEMBLOCKS   0
     #endif
-    #if UIP_UDP_NUMPACKETS and UIP_UDP_CONNS
-        #define NUM_UDP_MEMBLOCKS   (UIP_UDP_NUMPACKETS + 1) * UIP_UDP_CONNS
+    #if UIP_UDP and UIP_UDP_CONNS
+        #define NUM_UDP_MEMBLOCKS   3 * UIP_UDP_CONNS
     #else
         #define NUM_UDP_MEMBLOCKS   0
     #endif
-    #define NUM_MEMBLOCKS   (NUM_TCP_MEMBLOCKS + NUM_UDP_MEMBLOCKS)
-    #define MEMBLOCK_MV
+    #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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/utility/millis.cpp	Sun Mar 08 20:26:56 2015 +0000
@@ -0,0 +1,52 @@
+/*
+ uip_millis.cpp
+ Copyright (c) 2015 Zoltan Hudak <hudakz@inbox.com>
+ 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 <http://www.gnu.org/licenses/>.
+  */
+#include "millis.h"
+#include <mbed.h>
+
+volatile unsigned int   _millis;
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void millis_start(void) {
+    SysTick_Config(SystemCoreClock / 1000);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+extern "C" void SysTick_Handler(void) {
+    _millis += 1;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+extern "C" unsigned int millis(void) {
+    return _millis;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/utility/millis.h	Sun Mar 08 20:26:56 2015 +0000
@@ -0,0 +1,20 @@
+/*
+ uip_millis.h
+ Copyright (c) 2015 Zoltan Hudak <hudakz@inbox.com>
+ 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 <http://www.gnu.org/licenses/>.
+  */
+extern "C" void         millis_start(void);
+extern "C" unsigned int millis(void);
--- a/utility/uip-conf.h	Sat Dec 20 11:10:40 2014 +0000
+++ b/utility/uip-conf.h	Sun Mar 08 20:26:56 2015 +0000
@@ -166,21 +166,15 @@
 // SLIP
 
 //#define UIP_CONF_LLH_LEN 0
-typedef struct uipethernet_state
-{
-    void*   user;
-} uip_tcp_appstate_t;
+typedef void*   uip_tcp_appstate_t;
 
-void            uipethernet_appcall(void);
+void            uipclient_appcall(void);
 
-    #define UIP_APPCALL uipethernet_appcall
+    #define UIP_APPCALL uipclient_appcall
 
-typedef struct uipudp_state
-{
-    void*   user;
-} uip_udp_appstate_t;
+typedef void*   uip_udp_appstate_t;
 
-void    uipudp_appcall(void);
+void            uipudp_appcall(void);
 
     #define UIP_UDP_APPCALL uipudp_appcall
 
--- a/utility/uip-neighbor.c	Sat Dec 20 11:10:40 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,163 +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 <adam@sics.se>
- */
-#include "uip-neighbor.h"
-
-#include <string.h>
-
-#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;
-}
-
-/*---------------------------------------------------------------------------*/
--- a/utility/uip-neighbor.h	Sat Dec 20 11:10:40 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +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 <adam@sics.se>
- */
-#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__ */
--- a/utility/uip.c	Sat Dec 20 11:10:40 2014 +0000
+++ b/utility/uip.c	Sun Mar 08 20:26:56 2015 +0000
@@ -136,48 +136,48 @@
 #endif
 #ifndef UIP_CONF_EXTERNAL_BUFFER
 u8_t                        uip_buf[UIP_BUFSIZE + 2];   /* The packet buffer that contains
-				    incoming packets. */
+                    incoming packets. */
 #endif /* UIP_CONF_EXTERNAL_BUFFER */
 
 void*                       uip_appdata;    /* The uip_appdata pointer points to
-				    application data. */
+                    application data. */
 void*                       uip_sappdata;   /* The uip_appdata pointer points to
-				    the application data which is to
-				    be sent. */
+                    the application data which is to
+                    be sent. */
 #if UIP_URGDATA > 0
 void*                       uip_urgdata;    /* The uip_urgdata pointer points to
-   				    urgent data (out-of-band data), if
-   				    present. */
+                    urgent data (out-of-band data), if
+                    present. */
 u16_t                       uip_urglen, uip_surglen;
 #endif /* UIP_URGDATA > 0 */
 
 u16_t                       uip_len, uip_slen;
 
 /* The uip_len is either 8 or 16 bits,
-				depending on the maximum packet
-				size. */
+                depending on the maximum packet
+                size. */
 u8_t                        uip_flags;      /* The uip_flags variable is used for
-				communication between the TCP/IP stack
-				and the application program. */
+                communication between the TCP/IP stack
+                and the application program. */
 struct uip_conn*            uip_conn;       /* uip_conn always points to the current
-				connection. */
+                connection. */
 
 struct uip_conn             uip_conns[UIP_CONNS];
 
 /* The uip_conns array holds all TCP
-				connections. */
+                connections. */
 u16_t                       uip_listenports[UIP_LISTENPORTS];
 
 /* The uip_listenports list all currently
-				listning ports. */
+                listning ports. */
 #if UIP_UDP
 struct uip_udp_conn*        uip_udp_conn;
 struct uip_udp_conn         uip_udp_conns[UIP_UDP_CONNS];
 #endif /* UIP_UDP */
 
 static u16_t                ipid;           /* Ths ipid variable is an increasing
-				number that is used for the IP ID
-				field. */
+                number that is used for the IP ID
+                field. */
 
 /**
  * @brief
@@ -185,16 +185,17 @@
  * @param
  * @retval
  */
+
 void uip_setipid(u16_t id) {
     ipid = id;
 }
 
 static u8_t     iss[4];     /* The iss variable is used for the TCP
-				initial sequence number. */
+                initial sequence number. */
 
 #if UIP_ACTIVE_OPEN
 static u16_t    lastport;   /* Keeps track of the last port used for
-				a new connection. */
+                a new connection. */
 #endif /* UIP_ACTIVE_OPEN */
 
 /* Temporary variables. */
@@ -598,6 +599,7 @@
  * @param
  * @retval
  */
+
 static u8_t uip_reass(void) {
     u16_t   offset, len;
     u16_t   i;
@@ -645,14 +647,14 @@
         if(offset / (8 * 8) == (offset + len) / (8 * 8)) {
 
             /* If the two endpoints are in the same byte, we only update
-	 that byte. */
+     that byte. */
             uip_reassbitmap[offset / (8 * 8)] |= bitmap_bits[(offset / 8) & 7] &~bitmap_bits[((offset + len) / 8) & 7];
         }
         else {
 
             /* If the two endpoints are in different bytes, we update the
-	 bytes in the endpoints and fill the stuff inbetween with
-	 0xff. */
+     bytes in the endpoints and fill the stuff inbetween with
+     0xff. */
             uip_reassbitmap[offset / (8 * 8)] |= bitmap_bits[(offset / 8) & 7];
             for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
                 uip_reassbitmap[i] = 0xff;
@@ -677,7 +679,7 @@
         if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
 
             /* Check all bytes up to and including all but the last byte in
-	 the bitmap. */
+     the bitmap. */
             for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
                 if(uip_reassbitmap[i] != 0xff) {
                     goto nullreturn;
@@ -685,19 +687,19 @@
             }
 
             /* Check the last byte in the bitmap. It should contain just the
-	 right amount of bits. */
+     right amount of bits. */
             if(uip_reassbitmap[uip_reasslen / (8 * 8)] != (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {
                 goto nullreturn;
             }
 
             /* If we have come this far, we have a full packet in the
-	 buffer, so we allocate a pbuf and copy the packet into it. We
-	 also reset the timer. */
+     buffer, so we allocate a pbuf and copy the packet into it. We
+     also reset the timer. */
             uip_reasstmr = 0;
             memcpy(BUF, FBUF, uip_reasslen);
 
             /* Pretend to be a "normal" (i.e., not fragmented) IP packet
-	 from now on. */
+     from now on. */
             BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
             BUF->len[0] = uip_reasslen >> 8;
             BUF->len[1] = uip_reasslen & 0xff;
@@ -784,8 +786,8 @@
         if(uip_connr->tcpstateflags != UIP_CLOSED) {
 
             /* If the connection has outstanding data, we increase the
-	 connection's timer and see if it has reached the RTO value
-	 in which case we retransmit. */
+     connection's timer and see if it has reached the RTO value
+     in which case we retransmit. */
             if(uip_outstanding(uip_connr)) {
                 if(uip_connr->timer-- == 0) {
                     if
@@ -799,8 +801,8 @@
                         uip_connr->tcpstateflags = UIP_CLOSED;
 
                         /* We call UIP_APPCALL() with uip_flags set to
-	       UIP_TIMEDOUT to inform the application that the
-	       connection has timed out. */
+           UIP_TIMEDOUT to inform the application that the
+           connection has timed out. */
                         uip_flags = UIP_TIMEDOUT;
                         UIP_APPCALL();
 
@@ -814,11 +816,11 @@
                     ++(uip_connr->nrtx);
 
                     /* Ok, so we need to retransmit. We do this differently
-	     depending on which state we are in. In ESTABLISHED, we
-	     call upon the application so that it may prepare the
-	     data for the retransmit. In SYN_RCVD, we resend the
-	     SYNACK that we sent earlier and in LAST_ACK we have to
-	     retransmit our FINACK. */
+         depending on which state we are in. In ESTABLISHED, we
+         call upon the application so that it may prepare the
+         data for the retransmit. In SYN_RCVD, we resend the
+         SYNACK that we sent earlier and in LAST_ACK we have to
+         retransmit our FINACK. */
                     UIP_STAT(++uip_stat.tcp.rexmit);
                     switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
                     case UIP_SYN_RCVD:
@@ -921,14 +923,14 @@
         uip_len = (BUF->len[0] << 8) + BUF->len[1];
 #if UIP_CONF_IPV6
         uip_len += 40;  /* The length reported in the IPv6 header is the
-		      length of the payload that follows the
-		      header. However, uIP uses the uip_len variable
-		      for holding the size of the entire packet,
-		      including the IP header. For IPv4 this is not a
-		      problem as the length field in the IPv4 header
-		      contains the length of the entire packet. But
-		      for IPv6 we need to add the size of the IPv6
-		      header (40 bytes). */
+              length of the payload that follows the
+              header. However, uIP uses the uip_len variable
+              for holding the size of the entire packet,
+              including the IP header. For IPv4 this is not a
+              problem as the length field in the IPv4 header
+              contains the length of the entire packet. But
+              for IPv6 we need to add the size of the IPv6
+              header (40 bytes). */
 #endif /* UIP_CONF_IPV6 */
     }
     else {
@@ -982,7 +984,7 @@
         (
             BUF->proto == UIP_PROTO_UDP
         &&  uip_ipaddr_cmp(BUF->destipaddr, all_ones_addr)  /*&&
-	 uip_ipchksum() == 0xffff*/
+     uip_ipchksum() == 0xffff*/
         ) {
             goto udp_input;
         }
@@ -1014,7 +1016,7 @@
     if(uip_ipchksum() != 0xffff) {
 
         /* Compute and check the IP header
-				    checksum. */
+                    checksum. */
         UIP_STAT(++uip_stat.ip.drop);
         UIP_STAT(++uip_stat.ip.chkerr);
         UIP_LOG("ip: bad checksum.");
@@ -1025,8 +1027,8 @@
     if(BUF->proto == UIP_PROTO_TCP) {
 
         /* Check for TCP packet. If so,
-				       proceed with TCP input
-				       processing. */
+                       proceed with TCP input
+                       processing. */
         goto tcp_input;
     }
 
@@ -1042,7 +1044,7 @@
     if(BUF->proto != UIP_PROTO_ICMP) {
 
         /* We only allow ICMP packets from
-					here. */
+                    here. */
         UIP_STAT(++uip_stat.ip.drop);
         UIP_STAT(++uip_stat.ip.protoerr);
         UIP_LOG("ip: neither tcp nor icmp.");
@@ -1100,7 +1102,7 @@
     if(BUF->proto != UIP_PROTO_ICMP6) {
 
         /* We only allow ICMPv6 packets from
-					 here. */
+                     here. */
         UIP_STAT(++uip_stat.ip.drop);
         UIP_STAT(++uip_stat.ip.protoerr);
         UIP_LOG("ip: neither tcp nor icmp6.");
@@ -1120,7 +1122,7 @@
             }
 
             /* We should now send a neighbor advertisement back to where the
-	 neighbor solicication came from. */
+     neighbor solicication came from. */
             ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT;
             ICMPBUF->flags = ICMP6_FLAG_S;  /* Solicited flag. */
 
@@ -1274,7 +1276,7 @@
     if(uip_tcpchksum() != 0xffff) {
 
         /* Compute and check the TCP
-				       checksum. */
+                       checksum. */
         UIP_STAT(++uip_stat.tcp.drop);
         UIP_STAT(++uip_stat.tcp.chkerr);
         UIP_LOG("tcp: bad checksum.");
@@ -1452,11 +1454,11 @@
             else {
 
                 /* All other options have a length field, so that we easily
-	   can skip past them. */
+       can skip past them. */
                 if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
 
                     /* If the length field is zero, the options are malformed
-	     and we don't process them further. */
+         and we don't process them further. */
                     break;
                 }
 
@@ -1582,9 +1584,9 @@
     /* Do different things depending on in what state the connection is. */
     switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
     /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
-	implemented, since we force the application to close when the
-	peer sends a FIN (hence the application goes directly from
-	ESTABLISHED to LAST_ACK). */
+    implemented, since we force the application to close when the
+    peer sends a FIN (hence the application goes directly from
+    ESTABLISHED to LAST_ACK). */
     case UIP_SYN_RCVD:
         /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
        we are waiting for an ACK that acknowledges the data we sent
@@ -1642,11 +1644,11 @@
                     else {
 
                         /* All other options have a length field, so that we easily
-	       can skip past them. */
+           can skip past them. */
                         if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
 
                             /* If the length field is zero, the options are malformed
-		 and we don't process them further. */
+         and we don't process them further. */
                             break;
                         }
 
@@ -1804,32 +1806,32 @@
             if(uip_slen > 0) {
 
                 /* If the connection has acknowledged data, the contents of
-	   the ->len variable should be discarded. */
+       the ->len variable should be discarded. */
                 if((uip_flags & UIP_ACKDATA) != 0) {
                     uip_connr->len = 0;
                 }
 
                 /* If the ->len variable is non-zero the connection has
-	   already data in transit and cannot send anymore right
-	   now. */
+       already data in transit and cannot send anymore right
+       now. */
                 if(uip_connr->len == 0) {
 
                     /* The application cannot send more than what is allowed by
-	     the mss (the minumum of the MSS and the available
-	     window). */
+         the mss (the minumum of the MSS and the available
+         window). */
                     if(uip_slen > uip_connr->mss) {
                         uip_slen = uip_connr->mss;
                     }
 
                     /* Remember how much data we send out now so that we know
-	     when everything has been acknowledged. */
+         when everything has been acknowledged. */
                     uip_connr->len = uip_slen;
                 }
                 else {
 
                     /* If the application already had unacknowledged data, we
-	     make sure that the application does not send (i.e.,
-	     retransmit) out more than it previously sent out. */
+         make sure that the application does not send (i.e.,
+         retransmit) out more than it previously sent out. */
                     uip_slen = uip_connr->len;
                 }
             }
@@ -1853,7 +1855,7 @@
             }
 
             /* If there is no data to send, just send out a pure ACK if
-	 there is newdata. */
+     there is newdata. */
             if(uip_flags & UIP_NEWDATA) {
                 uip_len = UIP_TCPIP_HLEN;
                 BUF->flags = TCP_ACK;
--- a/utility/uip.h	Sat Dec 20 11:10:40 2014 +0000
+++ b/utility/uip.h	Sun Mar 08 20:26:56 2015 +0000
@@ -14,6 +14,8 @@
  * structures, TCP/IP header structures and function declarations.
  *
  */
+
+
 /*
  * Copyright (c) 2001-2003, Adam Dunkels.
  * All rights reserved.
@@ -47,31 +49,30 @@
  * $Id: uip.h,v 1.40 2006/06/08 07:12:07 adam Exp $
  *
  */
+
 #ifndef __UIP_H__
-    #define __UIP_H__
+#define __UIP_H__
 
-    #include "uipopt.h"
+#include "uipopt.h"
 
 /**
  * Repressentation of an IP address.
  *
  */
-
 typedef u16_t uip_ip4addr_t[2];
-typedef u16_t           uip_ip6addr_t[8];
-    #if UIP_CONF_IPV6
-typedef uip_ip6addr_t   uip_ipaddr_t;
-    #else /* UIP_CONF_IPV6 */
-
-typedef uip_ip4addr_t   uip_ipaddr_t;
-    #endif /* UIP_CONF_IPV6 */
+typedef u16_t uip_ip6addr_t[8];
+#if UIP_CONF_IPV6
+typedef uip_ip6addr_t uip_ipaddr_t;
+#else /* UIP_CONF_IPV6 */
+typedef uip_ip4addr_t uip_ipaddr_t;
+#endif /* UIP_CONF_IPV6 */
 
 /*---------------------------------------------------------------------------*/
-
 /* First, the functions that should be called from the
  * system. Initialization, the periodic timer and incoming packets are
  * handled by the following three functions.
  */
+
 /**
  * \defgroup uipconffunc uIP configuration functions
  * @{
@@ -94,7 +95,7 @@
 
  uip_ipaddr(&addr, 192,168,1,2);
  uip_sethostaddr(&addr);
-
+ 
  \endcode
  * \param addr A pointer to an IP address of type uip_ipaddr_t;
  *
@@ -102,7 +103,7 @@
  *
  * \hideinitializer
  */
-    #define uip_sethostaddr(addr)   uip_ipaddr_copy(uip_hostaddr, (addr))
+#define uip_sethostaddr(addr) uip_ipaddr_copy(uip_hostaddr, (addr))
 
 /**
  * Get the IP address of this host.
@@ -122,8 +123,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_gethostaddr(addr)   uip_ipaddr_copy((addr), uip_hostaddr)
+#define uip_gethostaddr(addr) uip_ipaddr_copy((addr), uip_hostaddr)
 
 /**
  * Set the default router's IP address.
@@ -135,8 +135,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_setdraddr(addr) uip_ipaddr_copy(uip_draddr, (addr))
+#define uip_setdraddr(addr) uip_ipaddr_copy(uip_draddr, (addr))
 
 /**
  * Set the netmask.
@@ -148,8 +147,8 @@
  *
  * \hideinitializer
  */
+#define uip_setnetmask(addr) uip_ipaddr_copy(uip_netmask, (addr))
 
-    #define uip_setnetmask(addr)    uip_ipaddr_copy(uip_netmask, (addr))
 
 /**
  * Get the default router's IP address.
@@ -159,8 +158,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_getdraddr(addr) uip_ipaddr_copy((addr), uip_draddr)
+#define uip_getdraddr(addr) uip_ipaddr_copy((addr), uip_draddr)
 
 /**
  * Get the netmask.
@@ -170,8 +168,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_getnetmask(addr)    uip_ipaddr_copy((addr), uip_netmask)
+#define uip_getnetmask(addr) uip_ipaddr_copy((addr), uip_netmask)
 
 /** @} */
 
@@ -181,20 +178,21 @@
  *
  * The uIP initialization functions are used for booting uIP.
  */
+
 /**
  * uIP initialization function.
  *
  * This function should be called at boot up to initilize the uIP
  * TCP/IP stack.
  */
-void    uip_init(void);
+void uip_init(void);
 
 /**
  * uIP initialization function.
  *
  * This function may be used at boot time to set the initial ip_id.
  */
-void    uip_setipid(u16_t id);
+void uip_setipid(u16_t id);
 
 /** @} */
 
@@ -244,19 +242,19 @@
       uip_input();
       if(uip_len > 0) {
         uip_arp_out();
-    ethernet_devicedriver_send();
+	ethernet_devicedriver_send();
       }
     } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) {
       uip_arp_arpin();
       if(uip_len > 0) {
-    ethernet_devicedriver_send();
+	ethernet_devicedriver_send();
       }
     }
  \endcode
  *
  * \hideinitializer
  */
-    #define uip_input() uip_process(UIP_DATA)
+#define uip_input()        uip_process(UIP_DATA)
 
 /**
  * Periodic processing for a connection identified by its number.
@@ -300,20 +298,14 @@
  *
  * \hideinitializer
  */
-
-    #define uip_periodic(conn) \
-    do \
-    { \
-        uip_conn = &uip_conns[conn]; \
-        uip_process(UIP_TIMER); \
-    } while(0)
+#define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \
+                                uip_process(UIP_TIMER); } while (0)
 
 /**
  *
  *
  */
-
-    #define uip_conn_active(conn)   (uip_conns[conn].tcpstateflags != UIP_CLOSED)
+#define uip_conn_active(conn) (uip_conns[conn].tcpstateflags != UIP_CLOSED)
 
 /**
  * Perform periodic processing for a connection identified by a pointer
@@ -328,13 +320,8 @@
  *
  * \hideinitializer
  */
-
-    #define uip_periodic_conn(conn) \
-    do \
-    { \
-        uip_conn = conn; \
-        uip_process(UIP_TIMER); \
-    } while(0)
+#define uip_periodic_conn(conn) do { uip_conn = conn; \
+                                     uip_process(UIP_TIMER); } while (0)
 
 /**
  * Reuqest that a particular connection should be polled.
@@ -347,15 +334,11 @@
  *
  * \hideinitializer
  */
+#define uip_poll_conn(conn) do { uip_conn = conn; \
+                                 uip_process(UIP_POLL_REQUEST); } while (0)
 
-    #define uip_poll_conn(conn) \
-    do \
-    { \
-        uip_conn = conn; \
-        uip_process(UIP_POLL_REQUEST); \
-    } while(0)
-    #if UIP_UDP
 
+#if UIP_UDP
 /**
  * Periodic processing for a UDP connection identified by its number.
  *
@@ -387,13 +370,8 @@
  *
  * \hideinitializer
  */
-
-        #define uip_udp_periodic(conn) \
-    do \
-    { \
-        uip_udp_conn = &uip_udp_conns[conn]; \
-        uip_process(UIP_UDP_TIMER); \
-    } while(0)
+#define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \
+                                uip_process(UIP_UDP_TIMER); } while (0)
 
 /**
  * Periodic processing for a UDP connection identified by a pointer to
@@ -409,16 +387,13 @@
  *
  * \hideinitializer
  */
+#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \
+                                         uip_process(UIP_UDP_TIMER); } while (0)
 
-        #define uip_udp_periodic_conn(conn) \
-    do \
-    { \
-        uip_udp_conn = conn; \
-        uip_process(UIP_UDP_TIMER); \
-    } while(0)
-    #endif /* UIP_UDP */
 
-                    /**
+#endif /* UIP_UDP */
+
+/**
  * The uIP packet buffer.
  *
  * The uip_buf array is used to hold incoming and outgoing
@@ -444,7 +419,7 @@
  }
  \endcode
  */
-                    extern u8_t uip_buf[UIP_BUFSIZE + 2];
+extern u8_t uip_buf[UIP_BUFSIZE+2];
 
 /** @} */
 
@@ -459,6 +434,7 @@
  *
  * Functions used by an application running of top of uIP.
  */
+
 /**
  * Start listening to the specified port.
  *
@@ -471,7 +447,7 @@
  *
  * \param port A 16-bit port number in network byte order.
  */
-void                            uip_listen(u16_t port);
+void uip_listen(u16_t port);
 
 /**
  * Stop listening to the specified port.
@@ -485,7 +461,7 @@
  *
  * \param port A 16-bit port number in network byte order.
  */
-void                            uip_unlisten(u16_t port);
+void uip_unlisten(u16_t port);
 
 /**
  * Connect to a remote host using TCP.
@@ -519,7 +495,9 @@
  * or NULL if no connection could be allocated.
  *
  */
-struct uip_conn*                uip_connect(uip_ipaddr_t* ripaddr, u16_t port);
+struct uip_conn *uip_connect(uip_ipaddr_t *ripaddr, u16_t port);
+
+
 
 /**
  * \internal
@@ -530,8 +508,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_outstanding(conn)   ((conn)->len)
+#define uip_outstanding(conn) ((conn)->len)
 
 /**
  * Send data on the current connection.
@@ -558,7 +535,7 @@
  *
  * \hideinitializer
  */
-void    uip_send(const void* data, int len);
+void uip_send(const void *data, int len);
 
 /**
  * The length of any incoming data that is currently avaliable (if avaliable)
@@ -569,9 +546,8 @@
  *
  * \hideinitializer
  */
-
 /*void uip_datalen(void);*/
-    #define uip_datalen()   uip_len
+#define uip_datalen()       uip_len
 
 /**
  * The length of any out-of-band data (urgent data) that has arrived
@@ -582,8 +558,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_urgdatalen()    uip_urglen
+#define uip_urgdatalen()    uip_urglen
 
 /**
  * Close the current connection.
@@ -592,8 +567,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_close() (uip_flags = UIP_CLOSE)
+#define uip_close()         (uip_flags = UIP_CLOSE)
 
 /**
  * Abort the current connection.
@@ -604,8 +578,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_abort() (uip_flags = UIP_ABORT)
+#define uip_abort()         (uip_flags = UIP_ABORT)
 
 /**
  * Tell the sending host to stop sending data.
@@ -615,8 +588,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_stop()  (uip_conn->tcpstateflags |= UIP_STOPPED)
+#define uip_stop()          (uip_conn->tcpstateflags |= UIP_STOPPED)
 
 /**
  * Find out if the current connection has been previously stopped with
@@ -624,8 +596,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_stopped(conn)   ((conn)->tcpstateflags & UIP_STOPPED)
+#define uip_stopped(conn)   ((conn)->tcpstateflags & UIP_STOPPED)
 
 /**
  * Restart the current connection, if is has previously been stopped
@@ -636,15 +607,12 @@
  *
  * \hideinitializer
  */
+#define uip_restart()         do { uip_flags |= UIP_NEWDATA; \
+                                   uip_conn->tcpstateflags &= ~UIP_STOPPED; \
+                              } while(0)
 
-    #define uip_restart() \
-    do \
-    { \
-        uip_flags |= UIP_NEWDATA; \
-        uip_conn->tcpstateflags &= ~UIP_STOPPED; \
-    } while(0)
 
-    /* uIP tests that can be made to determine in what state the current
+/* uIP tests that can be made to determine in what state the current
    connection is, and what the application function should do. */
 
 /**
@@ -655,7 +623,7 @@
  * \hideinitializer
  *
  */
-    #define uip_udpconnection() (uip_conn == NULL)
+#define uip_udpconnection() (uip_conn == NULL)
 
 /**
  * Is new incoming data available?
@@ -666,8 +634,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_newdata()   (uip_flags & UIP_NEWDATA)
+#define uip_newdata()   (uip_flags & UIP_NEWDATA)
 
 /**
  * Has previously sent data been acknowledged?
@@ -678,8 +645,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_acked() (uip_flags & UIP_ACKDATA)
+#define uip_acked()   (uip_flags & UIP_ACKDATA)
 
 /**
  * Has the connection just been connected?
@@ -691,8 +657,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_connected() (uip_flags & UIP_CONNECTED)
+#define uip_connected() (uip_flags & UIP_CONNECTED)
 
 /**
  * Has the connection been closed by the other end?
@@ -702,8 +667,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_closed()    (uip_flags & UIP_CLOSE)
+#define uip_closed()    (uip_flags & UIP_CLOSE)
 
 /**
  * Has the connection been aborted by the other end?
@@ -713,8 +677,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_aborted()   (uip_flags & UIP_ABORT)
+#define uip_aborted()    (uip_flags & UIP_ABORT)
 
 /**
  * Has the connection timed out?
@@ -724,8 +687,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_timedout()  (uip_flags & UIP_TIMEDOUT)
+#define uip_timedout()    (uip_flags & UIP_TIMEDOUT)
 
 /**
  * Do we need to retransmit previously data?
@@ -737,8 +699,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_rexmit()    (uip_flags & UIP_REXMIT)
+#define uip_rexmit()     (uip_flags & UIP_REXMIT)
 
 /**
  * Is the connection being polled by uIP?
@@ -752,8 +713,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_poll()  (uip_flags & UIP_POLL)
+#define uip_poll()       (uip_flags & UIP_POLL)
 
 /**
  * Get the initial maxium segment size (MSS) of the current
@@ -761,8 +721,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_initialmss()    (uip_conn->initialmss)
+#define uip_initialmss()             (uip_conn->initialmss)
 
 /**
  * Get the current maxium segment size that can be sent on the current
@@ -775,9 +734,9 @@
  *
  * \hideinitializer
  */
+#define uip_mss()             (uip_conn->mss)
 
-    #define uip_mss()   (uip_conn->mss)
-    /**
+/**
  * Set up a new UDP connection.
  *
  * This function sets up a new UDP connection. The function will
@@ -790,7 +749,7 @@
  \code
  uip_ipaddr_t addr;
  struct uip_udp_conn *c;
-
+ 
  uip_ipaddr(&addr, 192,168,2,1);
  c = uip_udp_new(&addr, HTONS(12345));
  if(c != NULL) {
@@ -804,7 +763,7 @@
  * \return The uip_udp_conn structure for the new connection or NULL
  * if no connection could be allocated.
  */
-    struct uip_udp_conn*    uip_udp_new(uip_ipaddr_t* ripaddr, u16_t rport);
+struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport);
 
 /**
  * Removed a UDP connection.
@@ -813,8 +772,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_udp_remove(conn)    (conn)->lport = 0
+#define uip_udp_remove(conn) (conn)->lport = 0
 
 /**
  * Bind a UDP connection to a local port.
@@ -826,8 +784,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_udp_bind(conn, port)    (conn)->lport = port
+#define uip_udp_bind(conn, port) (conn)->lport = port
 
 /**
  * Send a UDP datagram of length len on the current connection.
@@ -840,12 +797,12 @@
  *
  * \hideinitializer
  */
-
-    #define uip_udp_send(len)   uip_send((char*)uip_appdata, len)
+#define uip_udp_send(len) uip_send((char *)uip_appdata, len)
 
 /** @} */
 
 /* uIP convenience and converting functions. */
+
 /**
  * \defgroup uipconvfunc uIP conversion functions
  * @{
@@ -853,7 +810,7 @@
  * These functions can be used for converting between different data
  * formats used by uIP.
  */
-
+ 
 /**
  * Construct an IP address from four bytes.
  *
@@ -865,7 +822,7 @@
  \code
  uip_ipaddr_t ipaddr;
  struct uip_conn *c;
-
+ 
  uip_ipaddr(&ipaddr, 192,168,1,2);
  c = uip_connect(&ipaddr, HTONS(80));
  \endcode
@@ -880,12 +837,10 @@
  *
  * \hideinitializer
  */
-    #define uip_ipaddr(addr, addr0, addr1, addr2, addr3) \
-    do \
-    { \
-        ((u16_t *) (addr))[0] = HTONS(((addr0) << 8) | (addr1)); \
-        ((u16_t *) (addr))[1] = HTONS(((addr2) << 8) | (addr3)); \
-    } while(0)
+#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \
+                     ((u16_t *)(addr))[0] = HTONS(((addr0) << 8) | (addr1)); \
+                     ((u16_t *)(addr))[1] = HTONS(((addr2) << 8) | (addr3)); \
+                  } while(0)
 
 /**
  * Construct an IPv6 address from eight 16-bit words.
@@ -894,19 +849,18 @@
  *
  * \hideinitializer
  */
+#define uip_ip6addr(addr, addr0,addr1,addr2,addr3,addr4,addr5,addr6,addr7) do { \
+                     ((u16_t *)(addr))[0] = HTONS((addr0)); \
+                     ((u16_t *)(addr))[1] = HTONS((addr1)); \
+                     ((u16_t *)(addr))[2] = HTONS((addr2)); \
+                     ((u16_t *)(addr))[3] = HTONS((addr3)); \
+                     ((u16_t *)(addr))[4] = HTONS((addr4)); \
+                     ((u16_t *)(addr))[5] = HTONS((addr5)); \
+                     ((u16_t *)(addr))[6] = HTONS((addr6)); \
+                     ((u16_t *)(addr))[7] = HTONS((addr7)); \
+                  } while(0)
 
-    #define uip_ip6addr(addr, addr0, addr1, addr2, addr3, addr4, addr5, addr6, addr7) \
-    do \
-    { \
-        ((u16_t *) (addr))[0] = HTONS((addr0)); \
-        ((u16_t *) (addr))[1] = HTONS((addr1)); \
-        ((u16_t *) (addr))[2] = HTONS((addr2)); \
-        ((u16_t *) (addr))[3] = HTONS((addr3)); \
-        ((u16_t *) (addr))[4] = HTONS((addr4)); \
-        ((u16_t *) (addr))[5] = HTONS((addr5)); \
-        ((u16_t *) (addr))[6] = HTONS((addr6)); \
-        ((u16_t *) (addr))[7] = HTONS((addr7)); \
-    } while(0)  /**
+/**
  * Copy an IP address to another IP address.
  *
  * Copies an IP address from one place to another.
@@ -924,20 +878,16 @@
  *
  * \hideinitializer
  */
+#if !UIP_CONF_IPV6
+#define uip_ipaddr_copy(dest, src) do { \
+                     ((u16_t *)dest)[0] = ((u16_t *)src)[0]; \
+                     ((u16_t *)dest)[1] = ((u16_t *)src)[1]; \
+                  } while(0)
+#else /* !UIP_CONF_IPV6 */
+#define uip_ipaddr_copy(dest, src) memcpy(dest, src, sizeof(uip_ip6addr_t))
+#endif /* !UIP_CONF_IPV6 */
 
-    #if !UIP_CONF_IPV6
-        #define uip_ipaddr_copy(dest, src) \
-    do \
-    { \
-        ((u16_t*)dest)[0] = ((u16_t*)src)[0]; \
-        ((u16_t*)dest)[1] = ((u16_t*)src)[1]; \
-    } while(0)
-    #else /* !UIP_CONF_IPV6 */
-
-        #define uip_ipaddr_copy(dest, src)  memcpy(dest, src, sizeof(uip_ip6addr_t))
-    #endif /* !UIP_CONF_IPV6 */
-
-            /**
+/**
  * Compare two IP addresses
  *
  * Compares two IP addresses.
@@ -957,14 +907,12 @@
  *
  * \hideinitializer
  */
-
-    #if !UIP_CONF_IPV6
-        #define uip_ipaddr_cmp(addr1, addr2) \
-        (((u16_t*)addr1)[0] == ((u16_t*)addr2)[0] && ((u16_t*)addr1)[1] == ((u16_t*)addr2)[1])
-    #else /* !UIP_CONF_IPV6 */
-
-        #define uip_ipaddr_cmp(addr1, addr2)    (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0)
-    #endif /* !UIP_CONF_IPV6 */
+#if !UIP_CONF_IPV6
+#define uip_ipaddr_cmp(addr1, addr2) (((u16_t *)addr1)[0] == ((u16_t *)addr2)[0] && \
+				      ((u16_t *)addr1)[1] == ((u16_t *)addr2)[1])
+#else /* !UIP_CONF_IPV6 */
+#define uip_ipaddr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0)
+#endif /* !UIP_CONF_IPV6 */
 
 /**
  * Compare two IP addresses with netmasks
@@ -990,12 +938,12 @@
  *
  * \hideinitializer
  */
+#define uip_ipaddr_maskcmp(addr1, addr2, mask) \
+                          (((((u16_t *)addr1)[0] & ((u16_t *)mask)[0]) == \
+                            (((u16_t *)addr2)[0] & ((u16_t *)mask)[0])) && \
+                           ((((u16_t *)addr1)[1] & ((u16_t *)mask)[1]) == \
+                            (((u16_t *)addr2)[1] & ((u16_t *)mask)[1])))
 
-    #define uip_ipaddr_maskcmp(addr1, addr2, mask) \
-        ( \
-            ((((u16_t*)addr1)[0] & ((u16_t*)mask)[0]) == (((u16_t*)addr2)[0] & ((u16_t*)mask)[0])) \
-        &&  ((((u16_t*)addr1)[1] & ((u16_t*)mask)[1]) == (((u16_t*)addr2)[1] & ((u16_t*)mask)[1])) \
-        )
 
 /**
  * Mask out the network part of an IP address.
@@ -1021,13 +969,10 @@
  *
  * \hideinitializer
  */
-
-    #define uip_ipaddr_mask(dest, src, mask) \
-    do \
-    { \
-        ((u16_t*)dest)[0] = ((u16_t*)src)[0] & ((u16_t*)mask)[0]; \
-        ((u16_t*)dest)[1] = ((u16_t*)src)[1] & ((u16_t*)mask)[1]; \
-    } while(0)
+#define uip_ipaddr_mask(dest, src, mask) do { \
+                     ((u16_t *)dest)[0] = ((u16_t *)src)[0] & ((u16_t *)mask)[0]; \
+                     ((u16_t *)dest)[1] = ((u16_t *)src)[1] & ((u16_t *)mask)[1]; \
+                  } while(0)
 
 /**
  * Pick the first octet of an IP address.
@@ -1047,8 +992,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_ipaddr1(addr)   (htons(((u16_t *) (addr))[0]) >> 8)
+#define uip_ipaddr1(addr) (htons(((u16_t *)(addr))[0]) >> 8)
 
 /**
  * Pick the second octet of an IP address.
@@ -1068,8 +1012,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_ipaddr2(addr)   (htons(((u16_t *) (addr))[0]) & 0xff)
+#define uip_ipaddr2(addr) (htons(((u16_t *)(addr))[0]) & 0xff)
 
 /**
  * Pick the third octet of an IP address.
@@ -1089,8 +1032,7 @@
  *
  * \hideinitializer
  */
-
-    #define uip_ipaddr3(addr)   (htons(((u16_t *) (addr))[1]) >> 8)
+#define uip_ipaddr3(addr) (htons(((u16_t *)(addr))[1]) >> 8)
 
 /**
  * Pick the fourth octet of an IP address.
@@ -1110,9 +1052,9 @@
  *
  * \hideinitializer
  */
+#define uip_ipaddr4(addr) (htons(((u16_t *)(addr))[1]) & 0xff)
 
-    #define uip_ipaddr4(addr)   (htons(((u16_t *) (addr))[1]) & 0xff)
-                /**
+/**
  * Convert 16-bit quantity from host byte order to network byte order.
  *
  * This macro is primarily used for converting constants from host
@@ -1121,34 +1063,30 @@
  *
  * \hideinitializer
  */
-
-    #ifndef HTONS
-        #if UIP_BYTE_ORDER == UIP_BIG_ENDIAN
-            #define HTONS(n)    (n)
-        #else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
+#ifndef HTONS
+#   if UIP_BYTE_ORDER == UIP_BIG_ENDIAN
+#      define HTONS(n) (n)
+#   else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
+#      define HTONS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8))
+#   endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
+#else
+#error "HTONS already defined!"
+#endif /* HTONS */
 
-            #define HTONS(n)    (u16_t) ((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8))
-        #endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
-
-    #else
-        #error "HTONS already defined!"
-    #endif /* HTONS */
-
-                /**
+/**
  * Convert 16-bit quantity from host byte order to network byte order.
  *
  * This function is primarily used for converting variables from host
  * byte order to network byte order. For converting constants to
  * network byte order, use the HTONS() macro instead.
  */
+#ifndef htons
+u16_t htons(u16_t val);
+#endif /* htons */
+#ifndef ntohs
+#define ntohs htons
+#endif
 
-    #ifndef htons
-                u16_t htons(u16_t val);
-    #endif /* htons */
-
-    #ifndef ntohs
-        #define ntohs   htons
-    #endif
 /** @} */
 
 /**
@@ -1158,16 +1096,17 @@
  * called. If the application wishes to send data, the application may
  * use this space to write the data into before calling uip_send().
  */
-extern void*    uip_appdata;
+extern void *uip_appdata;
 
-    #if UIP_URGDATA > 0
+#if UIP_URGDATA > 0
 /* u8_t *uip_urgdata:
  *
  * This pointer points to any urgent data that has been received. Only
  * present if compiled with support for urgent data (UIP_URGDATA).
  */
-extern void*    uip_urgdata;
-    #endif /* UIP_URGDATA > 0 */
+extern void *uip_urgdata;
+#endif /* UIP_URGDATA > 0 */
+
 
 /**
  * \defgroup uipdrivervars Variables used in uIP device drivers
@@ -1192,12 +1131,14 @@
  * packet.
  *
  */
-extern u16_t    uip_len;
+extern u16_t uip_len;
 
 /** @} */
-    #if UIP_URGDATA > 0
-extern u16_t    uip_urglen, uip_surglen;
-    #endif /* UIP_URGDATA > 0 */
+
+#if UIP_URGDATA > 0
+extern u16_t uip_urglen, uip_surglen;
+#endif /* UIP_URGDATA > 0 */
+
 
 /**
  * Representation of a uIP TCP connection.
@@ -1209,146 +1150,137 @@
  * file pointers) for the connection. The type of this field is
  * configured in the "uipopt.h" header file.
  */
-
-struct uip_conn
-{
-    uip_ipaddr_t        ripaddr;        /**< The IP address of the remote host. */
-
-    u16_t               lport;          /**< The local TCP port, in network byte order. */
-    u16_t               rport;          /**< The local remote TCP port, in network byte
-             order. */
-
-    u8_t                rcv_nxt[4];     /**< The sequence number that we expect to
-             receive next. */
-    u8_t                snd_nxt[4];     /**< The sequence number that was last sent by
+struct uip_conn {
+  uip_ipaddr_t ripaddr;   /**< The IP address of the remote host. */
+  
+  u16_t lport;        /**< The local TCP port, in network byte order. */
+  u16_t rport;        /**< The local remote TCP port, in network byte
+			 order. */
+  
+  u8_t rcv_nxt[4];    /**< The sequence number that we expect to
+			 receive next. */
+  u8_t snd_nxt[4];    /**< The sequence number that was last sent by
                          us. */
-    u16_t               len;            /**< Length of the data that was previously sent. */
-    u16_t               mss;            /**< Current maximum segment size for the
-             connection. */
-    u16_t               initialmss;     /**< Initial maximum segment size for the
-             connection. */
-    u8_t                sa;             /**< Retransmission time-out calculation state
-             variable. */
-    u8_t                sv;             /**< Retransmission time-out calculation state
-             variable. */
-    u8_t                rto;            /**< Retransmission time-out. */
-    u8_t                tcpstateflags;  /**< TCP state and flags. */
-    u8_t                timer;          /**< The retransmission timer. */
-    u8_t                nrtx;           /**< The number of retransmissions for the last
-             segment sent. */
+  u16_t len;          /**< Length of the data that was previously sent. */
+  u16_t mss;          /**< Current maximum segment size for the
+			 connection. */
+  u16_t initialmss;   /**< Initial maximum segment size for the
+			 connection. */
+  u8_t sa;            /**< Retransmission time-out calculation state
+			 variable. */
+  u8_t sv;            /**< Retransmission time-out calculation state
+			 variable. */
+  u8_t rto;           /**< Retransmission time-out. */
+  u8_t tcpstateflags; /**< TCP state and flags. */
+  u8_t timer;         /**< The retransmission timer. */
+  u8_t nrtx;          /**< The number of retransmissions for the last
+			 segment sent. */
 
-    /** The application state. */
-    uip_tcp_appstate_t  appstate;
+  /** The application state. */
+  uip_tcp_appstate_t appstate;
 };
 
+
 /**
  * Pointer to the current TCP connection.
  *
  * The uip_conn pointer can be used to access the current TCP
  * connection.
  */
-extern struct uip_conn*     uip_conn;
-
+extern struct uip_conn *uip_conn;
 /* The array containing all uIP connections. */
-extern struct uip_conn      uip_conns[UIP_CONNS];
-
+extern struct uip_conn uip_conns[UIP_CONNS];
 /**
  * \addtogroup uiparch
  * @{
  */
+
 /**
  * 4-byte array used for the 32-bit sequence number calculations.
  */
-extern u8_t                 uip_acc32[4];
+extern u8_t uip_acc32[4];
 
 /** @} */
 
-    #if UIP_UDP
 
+#if UIP_UDP
 /**
  * Representation of a uIP UDP connection.
  */
-struct uip_udp_conn
-{
-    uip_ipaddr_t        ripaddr;    /**< The IP address of the remote peer. */
-    u16_t               lport;      /**< The local port number in network byte order. */
-    u16_t               rport;      /**< The remote port number in network byte order. */
-    u8_t                ttl;        /**< Default time-to-live. */
+struct uip_udp_conn {
+  uip_ipaddr_t ripaddr;   /**< The IP address of the remote peer. */
+  u16_t lport;        /**< The local port number in network byte order. */
+  u16_t rport;        /**< The remote port number in network byte order. */
+  u8_t  ttl;          /**< Default time-to-live. */
 
-    /** The application state. */
-    uip_udp_appstate_t  appstate;
+  /** The application state. */
+  uip_udp_appstate_t appstate;
 };
 
 /**
  * The current UDP connection.
  */
-extern struct uip_udp_conn*     uip_udp_conn;
-extern struct uip_udp_conn      uip_udp_conns[UIP_UDP_CONNS];
-    #endif /* UIP_UDP */
+extern struct uip_udp_conn *uip_udp_conn;
+extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
+#endif /* UIP_UDP */
 
 /**
  * The structure holding the TCP/IP statistics that are gathered if
  * UIP_STATISTICS is set to 1.
  *
  */
-
-struct uip_stats
-{
-    struct
-    {
-        uip_stats_t drop;       /**< Number of dropped packets at the IP
-                 layer. */
-        uip_stats_t recv;       /**< Number of received packets at the IP
-                 layer. */
-        uip_stats_t sent;       /**< Number of sent packets at the IP
-                 layer. */
-        uip_stats_t vhlerr;     /**< Number of packets dropped due to wrong
-                 IP version or header length. */
-        uip_stats_t hblenerr;   /**< Number of packets dropped due to wrong
-                 IP length, high byte. */
-        uip_stats_t lblenerr;   /**< Number of packets dropped due to wrong
-                 IP length, low byte. */
-        uip_stats_t fragerr;    /**< Number of packets dropped since they
-                 were IP fragments. */
-        uip_stats_t chkerr;     /**< Number of packets dropped due to IP
-                 checksum errors. */
-        uip_stats_t protoerr;   /**< Number of packets dropped since they
-                 were neither ICMP, UDP nor TCP. */
-    } ip;   /**< IP statistics. */
-    struct
-    {
-        uip_stats_t drop;       /**< Number of dropped ICMP packets. */
-        uip_stats_t recv;       /**< Number of received ICMP packets. */
-        uip_stats_t sent;       /**< Number of sent ICMP packets. */
-        uip_stats_t typeerr;    /**< Number of ICMP packets with a wrong
-                 type. */
-    } icmp; /**< ICMP statistics. */
-    struct
-    {
-        uip_stats_t drop;       /**< Number of dropped TCP segments. */
-        uip_stats_t recv;       /**< Number of recived TCP segments. */
-        uip_stats_t sent;       /**< Number of sent TCP segments. */
-        uip_stats_t chkerr;     /**< Number of TCP segments with a bad
-                 checksum. */
-        uip_stats_t ackerr;     /**< Number of TCP segments with a bad ACK
-                 number. */
-        uip_stats_t rst;        /**< Number of recevied TCP RST (reset) segments. */
-        uip_stats_t rexmit;     /**< Number of retransmitted TCP segments. */
-        uip_stats_t syndrop;    /**< Number of dropped SYNs due to too few
-                 connections was avaliable. */
-        uip_stats_t synrst;     /**< Number of SYNs for closed ports,
-                 triggering a RST. */
-    } tcp;  /**< TCP statistics. */
-    #if UIP_UDP
-    struct
-    {
-        uip_stats_t drop;   /**< Number of dropped UDP segments. */
-        uip_stats_t recv;   /**< Number of recived UDP segments. */
-        uip_stats_t sent;   /**< Number of sent UDP segments. */
-        uip_stats_t chkerr; /**< Number of UDP segments with a bad
-                 checksum. */
-    } udp;  /**< UDP statistics. */
-    #endif /* UIP_UDP */
+struct uip_stats {
+  struct {
+    uip_stats_t drop;     /**< Number of dropped packets at the IP
+			     layer. */
+    uip_stats_t recv;     /**< Number of received packets at the IP
+			     layer. */
+    uip_stats_t sent;     /**< Number of sent packets at the IP
+			     layer. */
+    uip_stats_t vhlerr;   /**< Number of packets dropped due to wrong
+			     IP version or header length. */
+    uip_stats_t hblenerr; /**< Number of packets dropped due to wrong
+			     IP length, high byte. */
+    uip_stats_t lblenerr; /**< Number of packets dropped due to wrong
+			     IP length, low byte. */
+    uip_stats_t fragerr;  /**< Number of packets dropped since they
+			     were IP fragments. */
+    uip_stats_t chkerr;   /**< Number of packets dropped due to IP
+			     checksum errors. */
+    uip_stats_t protoerr; /**< Number of packets dropped since they
+			     were neither ICMP, UDP nor TCP. */
+  } ip;                   /**< IP statistics. */
+  struct {
+    uip_stats_t drop;     /**< Number of dropped ICMP packets. */
+    uip_stats_t recv;     /**< Number of received ICMP packets. */
+    uip_stats_t sent;     /**< Number of sent ICMP packets. */
+    uip_stats_t typeerr;  /**< Number of ICMP packets with a wrong
+			     type. */
+  } icmp;                 /**< ICMP statistics. */
+  struct {
+    uip_stats_t drop;     /**< Number of dropped TCP segments. */
+    uip_stats_t recv;     /**< Number of recived TCP segments. */
+    uip_stats_t sent;     /**< Number of sent TCP segments. */
+    uip_stats_t chkerr;   /**< Number of TCP segments with a bad
+			     checksum. */
+    uip_stats_t ackerr;   /**< Number of TCP segments with a bad ACK
+			     number. */
+    uip_stats_t rst;      /**< Number of recevied TCP RST (reset) segments. */
+    uip_stats_t rexmit;   /**< Number of retransmitted TCP segments. */
+    uip_stats_t syndrop;  /**< Number of dropped SYNs due to too few
+			     connections was avaliable. */
+    uip_stats_t synrst;   /**< Number of SYNs for closed ports,
+			     triggering a RST. */
+  } tcp;                  /**< TCP statistics. */
+#if UIP_UDP
+  struct {
+    uip_stats_t drop;     /**< Number of dropped UDP segments. */
+    uip_stats_t recv;     /**< Number of recived UDP segments. */
+    uip_stats_t sent;     /**< Number of sent UDP segments. */
+    uip_stats_t chkerr;   /**< Number of UDP segments with a bad
+			     checksum. */
+  } udp;                  /**< UDP statistics. */
+#endif /* UIP_UDP */
 };
 
 /**
@@ -1358,6 +1290,7 @@
  */
 extern struct uip_stats uip_stat;
 
+
 /*---------------------------------------------------------------------------*/
 /* All the stuff below this point is internal to uIP and should not be
  * used directly by an application or by a device driver.
@@ -1369,7 +1302,7 @@
  * that are defined in this file. Please read below for more
  * infomation.
  */
-extern u8_t             uip_flags;
+extern u8_t uip_flags;
 
 /* The following flags may be set in the global variable uip_flags
    before calling the application callback. The UIP_ACKDATA,
@@ -1378,46 +1311,40 @@
    should *NOT* be accessed directly, but only through the uIP
    functions/macros. */
 
-    #define UIP_ACKDATA     1       /* Signifies that the outstanding data was
-                   acked and the application should send
-                   out new data instead of retransmitting
-                   the last data. */
-
-    #define UIP_NEWDATA     2       /* Flags the fact that the peer has sent
-                   us new data. */
-
-    #define UIP_REXMIT      4       /* Tells the application to retransmit the
-                   data that was last sent. */
-
-    #define UIP_POLL        8       /* Used for polling the application, to
-                   check if the application has data that
-                   it wants to send. */
-
-    #define UIP_CLOSE       16      /* The remote host has closed the
-                   connection, thus the connection has
-                   gone away. Or the application signals
-                   that it wants to close the
-                   connection. */
-
-    #define UIP_ABORT       32      /* The remote host has aborted the
-                   connection, thus the connection has
-                   gone away. Or the application signals
-                   that it wants to abort the
-                   connection. */
-
-    #define UIP_CONNECTED   64      /* We have got a connection from a remote
+#define UIP_ACKDATA   1     /* Signifies that the outstanding data was
+			       acked and the application should send
+			       out new data instead of retransmitting
+			       the last data. */
+#define UIP_NEWDATA   2     /* Flags the fact that the peer has sent
+			       us new data. */
+#define UIP_REXMIT    4     /* Tells the application to retransmit the
+			       data that was last sent. */
+#define UIP_POLL      8     /* Used for polling the application, to
+			       check if the application has data that
+			       it wants to send. */
+#define UIP_CLOSE     16    /* The remote host has closed the
+			       connection, thus the connection has
+			       gone away. Or the application signals
+			       that it wants to close the
+			       connection. */
+#define UIP_ABORT     32    /* The remote host has aborted the
+			       connection, thus the connection has
+			       gone away. Or the application signals
+			       that it wants to abort the
+			       connection. */
+#define UIP_CONNECTED 64    /* We have got a connection from a remote
                                host and have set up a new connection
                                for it, or an active connection has
                                been successfully established. */
 
-    #define UIP_TIMEDOUT    128     /* The connection has been aborted due to
-                   too many retransmissions. */
+#define UIP_TIMEDOUT  128   /* The connection has been aborted due to
+			       too many retransmissions. */
 
 /* uip_process(flag):
  *
  * The actual uIP function which does all the work.
  */
-void    uip_process(u8_t flag);
+void uip_process(u8_t flag);
 
 /* The following flags are passed as an argument to the uip_process()
    function. They are used to distinguish between the two cases where
@@ -1425,123 +1352,142 @@
    incoming data that should be processed, or because the periodic
    timer has fired. These values are never used directly, but only in
    the macrose defined in this file. */
-
-    #define UIP_DATA            1   /* Tells uIP that there is incoming
-                   data in the uip_buf buffer. The
-                   length of the data is stored in the
-                   global variable uip_len. */
-
-    #define UIP_TIMER           2   /* Tells uIP that the periodic timer
-                   has fired. */
-
-    #define UIP_POLL_REQUEST    3   /* Tells uIP that a connection should
-                   be polled. */
-
-    #define UIP_UDP_SEND_CONN   4   /* Tells uIP that a UDP datagram
-                   should be constructed in the
-                   uip_buf buffer. */
-
-    #if UIP_UDP
-        #define UIP_UDP_TIMER   5
-    #endif /* UIP_UDP */
+ 
+#define UIP_DATA          1     /* Tells uIP that there is incoming
+				   data in the uip_buf buffer. The
+				   length of the data is stored in the
+				   global variable uip_len. */
+#define UIP_TIMER         2     /* Tells uIP that the periodic timer
+				   has fired. */
+#define UIP_POLL_REQUEST  3     /* Tells uIP that a connection should
+				   be polled. */
+#define UIP_UDP_SEND_CONN 4     /* Tells uIP that a UDP datagram
+				   should be constructed in the
+				   uip_buf buffer. */
+#if UIP_UDP
+#define UIP_UDP_TIMER     5
+#endif /* UIP_UDP */
 
 /* The TCP states used in the uip_conn->tcpstateflags. */
-
-    #define UIP_CLOSED      0
-    #define UIP_SYN_RCVD    1
-    #define UIP_SYN_SENT    2
-    #define UIP_ESTABLISHED 3
-    #define UIP_FIN_WAIT_1  4
-    #define UIP_FIN_WAIT_2  5
-    #define UIP_CLOSING     6
-    #define UIP_TIME_WAIT   7
-    #define UIP_LAST_ACK    8
-    #define UIP_TS_MASK     15
-
-    #define UIP_STOPPED     16
+#define UIP_CLOSED      0
+#define UIP_SYN_RCVD    1
+#define UIP_SYN_SENT    2
+#define UIP_ESTABLISHED 3
+#define UIP_FIN_WAIT_1  4
+#define UIP_FIN_WAIT_2  5
+#define UIP_CLOSING     6
+#define UIP_TIME_WAIT   7
+#define UIP_LAST_ACK    8
+#define UIP_TS_MASK     15
+  
+#define UIP_STOPPED      16
 
 /* The TCP and IP headers. */
-struct uip_tcpip_hdr
-{
-    #if UIP_CONF_IPV6
-    /* IPv6 header. */
-    u8_t            vtc, tcflow;
-    u16_t           flow;
-    u8_t            len[2];
-    u8_t            proto, ttl;
-    uip_ip6addr_t   srcipaddr, destipaddr;
-    #else /* UIP_CONF_IPV6 */
-    /* IPv4 header. */
-
-    u8_t            vhl, tos, len[2], ipid[2], ipoffset[2], ttl, proto;
-    u16_t           ipchksum;
-    u16_t           srcipaddr[2], destipaddr[2];
-    #endif /* UIP_CONF_IPV6 */
-
-    /* TCP header. */
-
-    u16_t           srcport, destport;
-    u8_t            seqno[4], ackno[4], tcpoffset, flags, wnd[2];
-    u16_t           tcpchksum;
-    u8_t            urgp[2];
-    u8_t            optdata[4];
+struct uip_tcpip_hdr {
+#if UIP_CONF_IPV6
+  /* IPv6 header. */
+  u8_t vtc,
+    tcflow;
+  u16_t flow;
+  u8_t len[2];
+  u8_t proto, ttl;
+  uip_ip6addr_t srcipaddr, destipaddr;
+#else /* UIP_CONF_IPV6 */
+  /* IPv4 header. */
+  u8_t vhl,
+    tos,
+    len[2],
+    ipid[2],
+    ipoffset[2],
+    ttl,
+    proto;
+  u16_t ipchksum;
+  u16_t srcipaddr[2],
+    destipaddr[2];
+#endif /* UIP_CONF_IPV6 */
+  
+  /* TCP header. */
+  u16_t srcport,
+    destport;
+  u8_t seqno[4],
+    ackno[4],
+    tcpoffset,
+    flags,
+    wnd[2];
+  u16_t tcpchksum;
+  u8_t urgp[2];
+  u8_t optdata[4];
 };
 
 /* The ICMP and IP headers. */
-struct uip_icmpip_hdr
-{
-    #if UIP_CONF_IPV6
-    /* IPv6 header. */
-    u8_t            vtc, tcf;
-    u16_t           flow;
-    u8_t            len[2];
-    u8_t            proto, ttl;
-    uip_ip6addr_t   srcipaddr, destipaddr;
-    #else /* UIP_CONF_IPV6 */
-    /* IPv4 header. */
-
-    u8_t            vhl, tos, len[2], ipid[2], ipoffset[2], ttl, proto;
-    u16_t           ipchksum;
-    u16_t           srcipaddr[2], destipaddr[2];
-    #endif /* UIP_CONF_IPV6 */
-
-    /* ICMP (echo) header. */
-
-    u8_t            type, icode;
-    u16_t           icmpchksum;
-    #if !UIP_CONF_IPV6
-    u16_t           id, seqno;
-    #else /* !UIP_CONF_IPV6 */
-    u8_t            flags, reserved1, reserved2, reserved3;
-    u8_t            icmp6data[16];
-    u8_t            options[1];
-    #endif /* !UIP_CONF_IPV6 */
+struct uip_icmpip_hdr {
+#if UIP_CONF_IPV6
+  /* IPv6 header. */
+  u8_t vtc,
+    tcf;
+  u16_t flow;
+  u8_t len[2];
+  u8_t proto, ttl;
+  uip_ip6addr_t srcipaddr, destipaddr;
+#else /* UIP_CONF_IPV6 */
+  /* IPv4 header. */
+  u8_t vhl,
+    tos,
+    len[2],
+    ipid[2],
+    ipoffset[2],
+    ttl,
+    proto;
+  u16_t ipchksum;
+  u16_t srcipaddr[2],
+    destipaddr[2];
+#endif /* UIP_CONF_IPV6 */
+  
+  /* ICMP (echo) header. */
+  u8_t type, icode;
+  u16_t icmpchksum;
+#if !UIP_CONF_IPV6
+  u16_t id, seqno;
+#else /* !UIP_CONF_IPV6 */
+  u8_t flags, reserved1, reserved2, reserved3;
+  u8_t icmp6data[16];
+  u8_t options[1];
+#endif /* !UIP_CONF_IPV6 */
 };
 
+
 /* The UDP and IP headers. */
-struct uip_udpip_hdr
-{
-    #if UIP_CONF_IPV6
-    /* IPv6 header. */
-    u8_t            vtc, tcf;
-    u16_t           flow;
-    u8_t            len[2];
-    u8_t            proto, ttl;
-    uip_ip6addr_t   srcipaddr, destipaddr;
-    #else /* UIP_CONF_IPV6 */
-    /* IP header. */
+struct uip_udpip_hdr {
+#if UIP_CONF_IPV6
+  /* IPv6 header. */
+  u8_t vtc,
+    tcf;
+  u16_t flow;
+  u8_t len[2];
+  u8_t proto, ttl;
+  uip_ip6addr_t srcipaddr, destipaddr;
+#else /* UIP_CONF_IPV6 */
+  /* IP header. */
+  u8_t vhl,
+    tos,
+    len[2],
+    ipid[2],
+    ipoffset[2],
+    ttl,
+    proto;
+  u16_t ipchksum;
+  u16_t srcipaddr[2],
+    destipaddr[2];
+#endif /* UIP_CONF_IPV6 */
+  
+  /* UDP header. */
+  u16_t srcport,
+    destport;
+  u16_t udplen;
+  u16_t udpchksum;
+};
 
-    u8_t            vhl, tos, len[2], ipid[2], ipoffset[2], ttl, proto;
-    u16_t           ipchksum;
-    u16_t           srcipaddr[2], destipaddr[2];
-    #endif /* UIP_CONF_IPV6 */
 
-    /* UDP header. */
-
-    u16_t           srcport, destport;
-    u16_t           udplen;
-    u16_t           udpchksum;
-};
 
 /**
  * The buffer size available for user data in the \ref uip_buf buffer.
@@ -1557,49 +1503,44 @@
  *
  * \hideinitializer
  */
-    #define UIP_APPDATA_SIZE    (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
-    #define UIP_PROTO_ICMP      1
-    #define UIP_PROTO_TCP       6
-    #define UIP_PROTO_UDP       17
-    #define UIP_PROTO_ICMP6     58
+#define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
+
+
+#define UIP_PROTO_ICMP  1
+#define UIP_PROTO_TCP   6
+#define UIP_PROTO_UDP   17
+#define UIP_PROTO_ICMP6 58
 
 /* Header sizes. */
-
-    #if UIP_CONF_IPV6
-        #define UIP_IPH_LEN 40
-    #else /* UIP_CONF_IPV6 */
-
-        #define UIP_IPH_LEN 20  /* Size of IP header */
-    #endif /* UIP_CONF_IPV6 */
-
-    #define UIP_UDPH_LEN    8   /* Size of UDP header */
-
-    #define UIP_TCPH_LEN    20  /* Size of TCP header */
+#if UIP_CONF_IPV6
+#define UIP_IPH_LEN    40
+#else /* UIP_CONF_IPV6 */
+#define UIP_IPH_LEN    20    /* Size of IP header */
+#endif /* UIP_CONF_IPV6 */
+#define UIP_UDPH_LEN    8    /* Size of UDP header */
+#define UIP_TCPH_LEN   20    /* Size of TCP header */
+#define UIP_IPUDPH_LEN (UIP_UDPH_LEN + UIP_IPH_LEN)    /* Size of IP +
+							  UDP
+							  header */
+#define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN)    /* Size of IP +
+							  TCP
+							  header */
+#define UIP_TCPIP_HLEN UIP_IPTCPH_LEN
 
-    #define UIP_IPUDPH_LEN  (UIP_UDPH_LEN + UIP_IPH_LEN)    /* Size of IP +
-                              UDP
-                              header */
-
-    #define UIP_IPTCPH_LEN  (UIP_TCPH_LEN + UIP_IPH_LEN)    /* Size of IP +
-                              TCP
-                              header */
 
-    #define UIP_TCPIP_HLEN  UIP_IPTCPH_LEN
+#if UIP_FIXEDADDR
+extern const uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
+#else /* UIP_FIXEDADDR */
+extern uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
+#endif /* UIP_FIXEDADDR */
 
-    #if UIP_FIXEDADDR
-extern const uip_ipaddr_t   uip_hostaddr, uip_netmask, uip_draddr;
-    #else /* UIP_FIXEDADDR */
 
-extern uip_ipaddr_t         uip_hostaddr, uip_netmask, uip_draddr;
-    #endif /* UIP_FIXEDADDR */
 
 /**
  * Representation of a 48-bit Ethernet address.
  */
-
-struct uip_eth_addr
-{
-    u8_t    addr[6];
+struct uip_eth_addr {
+  u8_t addr[6];
 };
 
 /**
@@ -1618,7 +1559,7 @@
  *
  * \return The Internet checksum of the buffer.
  */
-u16_t   uip_chksum(u16_t* buf, u16_t len);
+u16_t uip_chksum(u16_t *buf, u16_t len);
 
 /**
  * Calculate the IP header checksum of the packet header in uip_buf.
@@ -1629,7 +1570,7 @@
  * \return The IP header checksum of the IP header in the uip_buf
  * buffer.
  */
-u16_t   uip_ipchksum(void);
+u16_t uip_ipchksum(void);
 
 /**
  * Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
@@ -1640,7 +1581,7 @@
  * \return The TCP checksum of the TCP segment in uip_buf and pointed
  * to by uip_appdata.
  */
-u16_t   uip_tcpchksum(void);
+u16_t uip_tcpchksum(void);
 
 /**
  * Calculate the UDP checksum of the packet in uip_buf and uip_appdata.
@@ -1651,7 +1592,10 @@
  * \return The UDP checksum of the UDP segment in uip_buf and pointed
  * to by uip_appdata.
  */
-u16_t   uip_udpchksum(void);
+u16_t uip_udpchksum(void);
+
+
 #endif /* __UIP_H__ */
 
+
 /** @} */
--- a/utility/uip_clock.cpp	Sat Dec 20 11:10:40 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-#include <time.h>
-#include "uip_clock.h"
-
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-clock_time_t clock_time(void) {
-    return(clock_time_t) time(NULL);
-}
--- a/utility/uip_debug.h	Sat Dec 20 11:10:40 2014 +0000
+++ b/utility/uip_debug.h	Sun Mar 08 20:26:56 2015 +0000
@@ -2,7 +2,7 @@
     #define UIP_DEBUG_H
 extern "C"
 {
-    #include "uip.h"
+    #import "utility/uip.h"
 }
 class   UIPDebug
 {
--- a/utility/uipethernet-conf.h	Sat Dec 20 11:10:40 2014 +0000
+++ b/utility/uipethernet-conf.h	Sun Mar 08 20:26:56 2015 +0000
@@ -6,15 +6,29 @@
     #define UIP_SOCKET_NUMPACKETS       5
     #define UIP_CONF_MAX_CONNECTIONS    4
 
-/* for UDP */
+/* for UDP
+ * set UIP_CONF_UDP to 0 to disable UDP (saves aprox. 5kb flash) */
 
     #define UIP_CONF_UDP        1
     #define UIP_CONF_BROADCAST  1
     #define UIP_CONF_UDP_CONNS  4
-    #define UIP_UDP_NUMPACKETS  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
+    #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
+
+/* periodic timer for uip (in ms) */
+
+    #define UIP_PERIODIC_TIMER  250
+
+/* timer to poll client for data after last write (in ms)
+ * set to -1 to disable fast polling and rely on periodic only (saves 100 bytes flash) */
+
+    #define UIP_CLIENT_TIMER    20
 #endif
--- a/utility/util.h	Sat Dec 20 11:10:40 2014 +0000
+++ b/utility/util.h	Sun Mar 08 20:26:56 2015 +0000
@@ -1,13 +1,9 @@
 #ifndef UTIL_H
-#define UTIL_H
-
-#define htons(x) ( ((x)<<8) | (((x)>>8)&0xFF) )
-#define ntohs(x) htons(x)
+    #define UTIL_H
 
-#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \
-                   ((x)<< 8 & 0x00FF0000UL) | \
-                   ((x)>> 8 & 0x0000FF00UL) | \
-                   ((x)>>24 & 0x000000FFUL) )
-#define ntohl(x) htonl(x)
-
+    #define htons(x)    (((x) << 8) | (((x) >> 8) & 0xFF))
+    #define ntohs(x)    htons(x)
+    #define htonl(x) \
+        (((x) << 24 & 0xFF000000UL) | ((x) << 8 & 0x00FF0000UL) | ((x) >> 8 & 0x0000FF00UL) | ((x) >> 24 & 0x000000FFUL))
+    #define ntohl(x)    htonl(x)
 #endif