Rewrite from scratch a TCP/IP stack for mbed. So far the following parts are usable: Drivers: - EMAC driver (from CMSIS 2.0) Protocols: - Ethernet protocol - ARP over ethernet for IPv4 - IPv4 over Ethernet - ICMPv4 over IPv4 - UDPv4 over IPv4 APIs: - Sockets for UDPv4 The structure of this stack is designed to be very modular. Each protocol can register one or more protocol to handle its payload, and in each protocol, an API can be hooked (like Sockets for example). This is an early release.

Files at this revision

API Documentation at this revision

Comitter:
Benoit
Date:
Sun Jun 12 19:17:11 2011 +0000
Parent:
0:19f5f51584de
Child:
2:3d1c0fbd10e6
Commit message:
Frames are now received using an interrupt handler

Changed in this revision

ARP.c Show diff for this revision Revisions of this file
ARP.cpp Show annotated file Show diff for this revision Revisions of this file
ARP.h Show annotated file Show diff for this revision Revisions of this file
Debug.c Show diff for this revision Revisions of this file
Debug.cpp Show annotated file Show diff for this revision Revisions of this file
Debug.h Show annotated file Show diff for this revision Revisions of this file
Ethernet.c Show diff for this revision Revisions of this file
Ethernet.cpp Show annotated file Show diff for this revision Revisions of this file
ICMPv4.c Show diff for this revision Revisions of this file
ICMPv4.cpp Show annotated file Show diff for this revision Revisions of this file
ICMPv4.h Show annotated file Show diff for this revision Revisions of this file
IPv4.c Show diff for this revision Revisions of this file
IPv4.cpp Show annotated file Show diff for this revision Revisions of this file
IPv4.h Show annotated file Show diff for this revision Revisions of this file
NetIF.c Show diff for this revision Revisions of this file
NetIF.cpp Show annotated file Show diff for this revision Revisions of this file
NetIF.h Show annotated file Show diff for this revision Revisions of this file
Queue.c Show diff for this revision Revisions of this file
Queue.cpp Show annotated file Show diff for this revision Revisions of this file
Queue.h Show annotated file Show diff for this revision Revisions of this file
Sockets.c Show diff for this revision Revisions of this file
Sockets.cpp Show annotated file Show diff for this revision Revisions of this file
Sockets.h Show annotated file Show diff for this revision Revisions of this file
TCPv4.cpp Show annotated file Show diff for this revision Revisions of this file
UDPv4.c Show diff for this revision Revisions of this file
UDPv4.cpp Show annotated file Show diff for this revision Revisions of this file
UDPv4.h Show annotated file Show diff for this revision Revisions of this file
lpc17xx_clkpwr.c Show diff for this revision Revisions of this file
lpc17xx_clkpwr.cpp Show annotated file Show diff for this revision Revisions of this file
lpc17xx_clkpwr.h Show annotated file Show diff for this revision Revisions of this file
lpc17xx_emac.c Show diff for this revision Revisions of this file
lpc17xx_emac.cpp Show annotated file Show diff for this revision Revisions of this file
lpc17xx_emac.h Show annotated file Show diff for this revision Revisions of this file
lpc17xx_pinsel.c Show diff for this revision Revisions of this file
lpc17xx_pinsel.cpp Show annotated file Show diff for this revision Revisions of this file
mbedNet.h Show annotated file Show diff for this revision Revisions of this file
mbedNetIF.c Show diff for this revision Revisions of this file
mbedNetIF.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/ARP.c	Sun Jun 12 11:23:03 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,565 +0,0 @@
-/*
- * $Id: ARP.c 29 2011-06-11 14:53:08Z benoit $
- * $Author: benoit $
- * $Date: 2011-06-11 16:53:08 +0200 (sam., 11 juin 2011) $
- * $Rev: 29 $
- * 
- * 
- * 
- * 
- * 
- */
- 
-#include "ARP.h"
-#include "Ethernet.h"
-#include "Debug.h"
-#include "IPv4.h"
-#include <string.h>
-
-
-#define    DEBUG_CURRENT_MODULE_NAME    "ARP"
-#define    DEBUG_CURRENT_MODULE_ID        DEBUG_MODULE_ARP
-
-
-enum ARP_EntryStatus
-{
-    ARP_Entry_Free = 0,
-    ARP_Entry_PendingReply,
-    ARP_Entry_Dynamic,
-    ARP_Entry_Expired,
-    ARP_Entry_Static,
-    ARP_Entry_Count,
-};
-typedef enum ARP_EntryStatus ARP_EntryStatus_t;
-
-
-const char *arpEntryStatusText[ARP_Entry_Count] = 
-{
-    "free",
-    "pending",
-    "dynamic",
-    "expired",
-    "static",
-};
-
-struct ARP_CacheEntry
-{
-    IPv4_Addr_t            ipv4Addr;
-    Ethernet_Addr_t        ethernetAddr;
-    NetIF_t             *netIF;
-    uint16_t            age;
-    ARP_EntryStatus_t    status;
-    RTOS_Mutex_t        mutex;
-};
-typedef struct ARP_CacheEntry ARP_CacheEntry_t;
-
-
-#pragma push
-#pragma pack(1)
-static struct 
-{
-    Ethernet_Header_t    ethernetHeader;
-    ARP_Header_t        arpHeader;
-    ARP_IPv4Data_t        ipv4ARPData;
-} arp_FullIPv4Packet;
-#pragma pop
-
-
-static void Init(void);
-static void Handler(NetIF_t *netIF, Packet_t *packet);
-static void PeriodicFunction(void);
-static ARP_CacheEntry_t *GetReusableEntry(void);
-static ARP_CacheEntry_t *GetEntryByIPv4Address(IPv4_Addr_t address);
-
-
-static ARP_CacheEntry_t        arp_CacheTable[ARP_CACHE_MAX_ENTRIES];
-
-
-Protocol_Handler_t arp = 
-{
-    PROTOCOL_INDEX_NOT_INITIALIZED,                /* Always PROTOCOL_INDEX_NOT_INITIALIZED at initialization */
-    Protocol_ID_ARP,                             /* Protocol ID */
-    htons(ETHERNET_PROTO_ARP),                     /* Protocol number */
-    Init,                                         /* Protocol initialisation function */
-    Handler,                                    /* Protocol handler */
-    NULL,                                        /* Protocol registration function */
-    NULL,                                        /* API registration function */
-};
-
-
-static void Init(void)
-{
-    int32_t                index;
-    
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing ARP layer"));
-    memset(arp_CacheTable, 0, sizeof(arp_CacheTable));
-    for (index = 0; index < ARP_CACHE_MAX_ENTRIES; index++)
-    {
-        arp_CacheTable[index].mutex = RTOS_MUTEX_CREATE();
-    }
-    NetIF_RegisterPeriodicFunction("ARP cache", PeriodicFunction, ARP_FUNCTION_PERIOD);
-}
-
-
-static void Handler(NetIF_t *netIF, Packet_t *packet)
-{
-    ARP_Type_t            type;
-    ARP_Protocol_t        protocol;
-    ARP_Operation_t        operation;
-    ARP_IPv4Data_t        *ipv4ARP;
-    ARP_Header_t        *arpHeader = (ARP_Header_t *)packet->data;
-    Ethernet_Addr_t        *ourHWAddress;
-    Ethernet_Header_t    *ethernetHeader;
-    ARP_CacheEntry_t    *entry;
-
-
-    type = ntohs(arpHeader->type);
-    protocol = ntohs(arpHeader->protocol);
-    operation = ntohs(arpHeader->operation);
-
-    if (type != ARP_HW_TYPE_ENET) goto Exit;            /* not an ethernet ARP, ignore  */
-    if (protocol != ETHERNET_PROTO_IPV4) goto Exit;        /* Not an IPv4 ARP, ignore */
-    
-    ipv4ARP = (ARP_IPv4Data_t *)(arpHeader + 1);
-    
-    switch(operation)
-    {
-        case ARP_OPERATION_REQUEST:
-            if (ipv4ARP->ipDest.addr == netIF->ipv4Address.addr)     /* Does it match our hw address? */
-            {
-                DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE0)
-                {
-                    ARP_DumpHeader("Got ", arpHeader);
-                }
-                
-                ourHWAddress = (Ethernet_Addr_t *)netIF->driverParameter;
-                
-                arpHeader->operation = htons(ARP_OPERATION_REPLY);
-                
-                ipv4ARP->hwDest = ipv4ARP->hwSource;
-                ipv4ARP->ipDest.addr = ipv4ARP->ipSource.addr;
-                ipv4ARP->hwSource = *ourHWAddress;
-                ipv4ARP->ipSource = netIF->ipv4Address;
-                
-                NetIF_ProtoPop(packet);
-
-                ethernetHeader = (Ethernet_Header_t *)packet->data;
-                ethernetHeader->destination = ethernetHeader->source;
-                ethernetHeader->source = *ourHWAddress;
-                
-                DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE0)
-                {                
-                    ARP_DumpHeader("Replying ", arpHeader);
-                }
-                                
-                netIF->driver->Write(packet->data, packet->length);
-            }
-            
-            break;
-            
-        case ARP_OPERATION_REPLY:
-            /* Check if it matches an entry we requested */
-            DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE0)
-            {
-                ARP_DumpHeader("Got ", arpHeader);
-            }
-            
-            entry = GetEntryByIPv4Address(ipv4ARP->ipSource);
-            if (entry == NULL) break;    /* fake arp request */
-            
-            entry->status = ARP_Entry_Dynamic;
-            entry->ethernetAddr = ipv4ARP->hwSource;
-            entry->netIF = netIF;
-            entry->age = 0;
-            
-            RTOS_MUTEX_UNLOCK(entry->mutex);
-            
-            DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE0)
-            {
-                DEBUG_RAW(("Adding entry %d.%d.%d.%d at %02x:%02x:%02x:%02x:%02x:%02x",
-                    ipv4ARP->ipSource.IP0,
-                    ipv4ARP->ipSource.IP1,
-                    ipv4ARP->ipSource.IP2,
-                    ipv4ARP->ipSource.IP3,
-                    ipv4ARP->hwSource.MA0,
-                    ipv4ARP->hwSource.MA1,
-                    ipv4ARP->hwSource.MA2,
-                    ipv4ARP->hwSource.MA3,
-                    ipv4ARP->hwSource.MA4,
-                    ipv4ARP->hwSource.MA5
-                ));
-            }
-            break;
-    }
-    
-Exit:
-    return;
-}
-
-
-static void PeriodicFunction(void)
-{
-    int32_t        index;
-    ARP_CacheEntry_t    *entry;
-    
-    for (index = 0; index < ARP_CACHE_MAX_ENTRIES; index++)
-    {
-        entry = arp_CacheTable + index;
-        RTOS_MUTEX_LOCK(entry->mutex);
-        switch(entry->status)
-        {
-            case ARP_Entry_Dynamic:
-                entry->age += ARP_FUNCTION_PERIOD;
-                if (entry->age > ARP_MAX_ENTRY_AGE)
-                {
-                    entry->status = ARP_Entry_Expired;
-                    entry->age = 0;
-                }
-                break;
-                
-            case ARP_Entry_PendingReply:
-                entry->age += ARP_FUNCTION_PERIOD;
-                if (entry->age > ARP_MAX_ENTRY_AGE)
-                {
-                    entry->status = ARP_Entry_Free;
-                    entry->age = 0;
-                }
-                break;
-        }
-        RTOS_MUTEX_UNLOCK(entry->mutex);
-    }
-}
-
-
-static ARP_CacheEntry_t *GetReusableEntry(void)
-{
-    int32_t                index,
-                        oldestEntryIndex, oldestEntryAge;
-    ARP_CacheEntry_t    *entry;
-    
-    /* First look for a free entry */
-    for (index = 0; index < ARP_CACHE_MAX_ENTRIES; index++)
-    {
-        entry = arp_CacheTable + index;
-        RTOS_MUTEX_LOCK(entry->mutex);
-        
-        if (entry->status == ARP_Entry_Free)
-        {
-            break;
-        }
-
-        RTOS_MUTEX_UNLOCK(entry->mutex);
-        entry = NULL;
-    }
-    
-    if (entry != NULL) goto Exit;    /* A free entry was found, return it */
-    
-    /* Now look for an expired entry */
-    oldestEntryIndex = -1;
-    oldestEntryAge = -1;
-    for (index = 0; index < ARP_CACHE_MAX_ENTRIES; index++)
-    {
-        entry = arp_CacheTable + index;
-        RTOS_MUTEX_LOCK(entry->mutex);
-        
-        if (entry->age > oldestEntryAge)
-        {
-            oldestEntryIndex = index;
-            oldestEntryAge = entry->age;
-        }
-        
-        if (entry->status == ARP_Entry_Expired)
-        {
-            break;
-        }
-
-        RTOS_MUTEX_UNLOCK(entry->mutex);
-        entry = NULL;
-    }
-
-    if (entry != NULL) goto Exit;    /* An expired entry was found, return it */
-
-    /* Last possibility, return the oldest non static entry */    
-    entry = arp_CacheTable + oldestEntryIndex;
-    RTOS_MUTEX_LOCK(entry->mutex);
-
-Exit:
-    return entry;
-}
-
-
-static ARP_CacheEntry_t *GetEntryByIPv4Address(IPv4_Addr_t address)
-{
-    int32_t                index;
-    ARP_CacheEntry_t    *entry = NULL;
-    
-    for (index = 0; index < ARP_CACHE_MAX_ENTRIES; index++)
-    {
-        entry = arp_CacheTable + index;
-        RTOS_MUTEX_LOCK(entry->mutex);
-        
-        if (entry->ipv4Addr.addr == address.addr)
-        {
-            break;
-        }
-        RTOS_MUTEX_UNLOCK(entry->mutex);
-        entry = NULL;
-    }
-    
-    return entry;
-}
-
-
-int32_t    ARP_ResolveIPv4Address(NetIF_t *netIF, IPv4_Addr_t address, Ethernet_Addr_t *ethernetAddr)
-{
-    int32_t                result = -1;
-    Ethernet_Addr_t        *hwAddress;
-    ARP_CacheEntry_t    *entry;
-    
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Resolving %d.%d.%d.%d",
-        address.IP0,
-        address.IP1,
-        address.IP2,
-        address.IP3
-    ));
-    
-    /* Look if entry is already available in table */
-    entry = GetEntryByIPv4Address(address);
-    if (entry != NULL)                /* Found entry, look its status */
-    {
-        switch(entry->status)
-        {
-            case ARP_Entry_Static:
-                DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("Found static entry"));
-                if (ethernetAddr != NULL) *ethernetAddr = entry->ethernetAddr;
-                RTOS_MUTEX_UNLOCK(entry->mutex);
-                result = 0;
-                break;
-                
-            case ARP_Entry_Dynamic:
-                DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("Found dynamic entry"));
-                if (ethernetAddr != NULL) *ethernetAddr = entry->ethernetAddr;
-                entry->age = 0;
-                RTOS_MUTEX_UNLOCK(entry->mutex);
-                result = 0;
-                break;
-                
-            case ARP_Entry_Expired:
-                DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("Found expired entry, reactivating it"));
-                if (ethernetAddr != NULL) *ethernetAddr = entry->ethernetAddr;
-                entry->status = ARP_Entry_Dynamic;
-                entry->age = 0;
-                RTOS_MUTEX_UNLOCK(entry->mutex);
-                result = 0;
-                break;
-                
-            case ARP_Entry_PendingReply:
-                DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("Found pending entry"));
-                entry->age = 0;
-                RTOS_MUTEX_UNLOCK(entry->mutex);
-                break;
-                
-            default:
-                DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Default?!"));
-                break;
-        }
-    }
-    
-    if (result == 0) goto Exit;        /* Resolution was successfull, exit */
-    
-    
-    /* Entry not found, send a request */
-    result = -1;
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Sending ARP resolution request for %d.%d.%d.%d",
-        address.IP0,
-        address.IP1,
-        address.IP2,
-        address.IP3
-    ));
-    
-    /* Update entry, setting its status to Pending reply */
-    entry = GetReusableEntry();
-    if (entry != NULL)
-    {
-        entry->status = ARP_Entry_PendingReply;
-        entry->ipv4Addr.addr = address.addr;
-        entry->netIF = netIF;
-        entry->age = 0;
-        RTOS_MUTEX_UNLOCK(entry->mutex);
-    }
-    /* Send ARP who-has */    
-    hwAddress = (Ethernet_Addr_t *)netIF->driverParameter;
-
-    arp_FullIPv4Packet.ethernetHeader.destination = ethernet_Addr_Broadcast;
-    arp_FullIPv4Packet.ethernetHeader.source = *hwAddress;
-    arp_FullIPv4Packet.ethernetHeader.protocol = htons(ETHERNET_PROTO_ARP);
-    
-    arp_FullIPv4Packet.arpHeader.type = htons(ARP_HW_TYPE_ENET);
-    arp_FullIPv4Packet.arpHeader.protocol = htons(ETHERNET_PROTO_IPV4);
-    arp_FullIPv4Packet.arpHeader.operation = htons(ARP_OPERATION_REQUEST);
-    arp_FullIPv4Packet.arpHeader.hardAddrLen = 6;
-    arp_FullIPv4Packet.arpHeader.protoAddrLen = 4;
-    
-    arp_FullIPv4Packet.ipv4ARPData.hwSource = *hwAddress;
-    arp_FullIPv4Packet.ipv4ARPData.ipSource = netIF->ipv4Address;
-    arp_FullIPv4Packet.ipv4ARPData.hwDest = ethernet_Addr_Null;
-    arp_FullIPv4Packet.ipv4ARPData.ipDest = address;
-    
-    DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE0)
-    {
-        ARP_DumpHeader("Sending ", &arp_FullIPv4Packet.arpHeader);
-    }
-    
-    netIF->driver->Write((uint8_t *)&arp_FullIPv4Packet, sizeof(arp_FullIPv4Packet));
-    
-Exit:
-    return result;
-}
-
-
-int32_t    ARP_AddStaticEntry(NetIF_t *netIF, IPv4_Addr_t address, const Ethernet_Addr_t *ethernetAddr)
-{
-    int32_t                result = 0;
-    ARP_CacheEntry_t    *entry;
-    
-    entry = GetReusableEntry();
-    if (entry == NULL)
-    {
-        result = -1;
-        goto Exit;
-    }
-    entry->netIF = netIF;
-    entry->status = ARP_Entry_Static;
-    entry->ipv4Addr.addr = address.addr;
-    entry->ethernetAddr = *ethernetAddr;
-    entry->age = 0;
-    RTOS_MUTEX_UNLOCK(entry->mutex);
-
-Exit:
-    return result;
-}
-
-
-int32_t    ARP_RemoveEntry(const NetIF_t *netIF, IPv4_Addr_t address)
-{
-    int32_t        result = 0;
-    
-    
-    
-    return result;
-}
-
-
-void ARP_InvalidateCache(Bool_t flushStaticEntries)
-{
-    int32_t                index;
-    ARP_CacheEntry_t    *entry;
-    
-    for (index = 0; index < ARP_CACHE_MAX_ENTRIES; index++)
-    {
-        entry = arp_CacheTable + index;
-        RTOS_MUTEX_LOCK(entry->mutex);
-        if ((entry->status == ARP_Entry_Static) && (!flushStaticEntries)) 
-        {
-            RTOS_MUTEX_UNLOCK(entry->mutex);
-            continue;
-        }
-        entry->status = ARP_Entry_Free;
-        RTOS_MUTEX_UNLOCK(entry->mutex);
-    }
-}
-
-
-void ARP_DisplayCache(void)
-{
-    int32_t                index;
-    ARP_CacheEntry_t    *entry = NULL;
-    
-    DEBUG_RAW(("ARP cache"));
-    DEBUG_RAW(("index dev   MAC address            type  age  IPv4 address"));
-    DEBUG_RAW(("----------------------------------------------------------"));
-      /*      en0   00:11:22:33:44:55  dyn    10 163.157.128.131 */
-    for (index = 0; index < ARP_CACHE_MAX_ENTRIES; index++)
-    {
-        entry = arp_CacheTable + index;
-    
-        DEBUG_RAW(("%2d    %s%c   %02x:%02x:%02x:%02x:%02x:%02x  %8s  %4d  %d.%d.%d.%d",
-            index, 
-            entry->status != ARP_Entry_Free ? entry->netIF->name : "--", 
-            entry->status != ARP_Entry_Free ? entry->netIF->index + '0' : '-', 
-            entry->ethernetAddr.MA0,
-            entry->ethernetAddr.MA1,
-            entry->ethernetAddr.MA2,
-            entry->ethernetAddr.MA3,
-            entry->ethernetAddr.MA4,
-            entry->ethernetAddr.MA5,
-                
-            arpEntryStatusText[entry->status],
-            entry->age,
-            
-            entry->ipv4Addr.IP0,
-            entry->ipv4Addr.IP1,
-            entry->ipv4Addr.IP2,
-            entry->ipv4Addr.IP3
-        ));    
-    }
-}
-
-void ARP_DumpHeader(const char *prefix, ARP_Header_t *arpHeader)
-{
-    ARP_IPv4Data_t    *ipv4ARP = NULL;
-    
-    if (arpHeader->protocol == htons(ETHERNET_PROTO_IPV4))
-    {
-        ipv4ARP = (ARP_IPv4Data_t *)(arpHeader + 1);
-        
-        switch(ntohs(arpHeader->operation))
-        {
-            case ARP_OPERATION_REQUEST:
-                DEBUG_RAW(("%sARP who-has %d.%d.%d.%d tell %02x:%02x:%02x:%02x:%02x:%02x",
-                    prefix != NULL ? prefix : "",
-            
-                    ipv4ARP->ipDest.IP0,
-                    ipv4ARP->ipDest.IP1,
-                    ipv4ARP->ipDest.IP2,
-                    ipv4ARP->ipDest.IP3,
-            
-                    ipv4ARP->hwSource.MA0,
-                    ipv4ARP->hwSource.MA1,
-                    ipv4ARP->hwSource.MA2,
-                    ipv4ARP->hwSource.MA3,
-                    ipv4ARP->hwSource.MA4,
-                    ipv4ARP->hwSource.MA5
-                ));
-                break;
-                
-            case ARP_OPERATION_REPLY:
-                DEBUG_RAW(("%sARP %d.%d.%d.%d is-at %02x:%02x:%02x:%02x:%02x:%02x",
-                    prefix != NULL ? prefix : "",
-            
-                    ipv4ARP->ipSource.IP0,
-                    ipv4ARP->ipSource.IP1,
-                    ipv4ARP->ipSource.IP2,
-                    ipv4ARP->ipSource.IP3,
-            
-                    ipv4ARP->hwSource.MA0,
-                    ipv4ARP->hwSource.MA1,
-                    ipv4ARP->hwSource.MA2,
-                    ipv4ARP->hwSource.MA3,
-                    ipv4ARP->hwSource.MA4,
-                    ipv4ARP->hwSource.MA5
-                ));
-                break;
-            
-            default:
-                break;
-        }
-    }
-    else
-    {
-        DEBUG_RAW(("%sARP: unsupported protocol %d",
-            prefix != NULL ? prefix : "",
-            arpHeader->protocol
-        ));
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ARP.cpp	Sun Jun 12 19:17:11 2011 +0000
@@ -0,0 +1,568 @@
+/*
+ * $Id: ARP.c 29 2011-06-11 14:53:08Z benoit $
+ * $Author: benoit $
+ * $Date: 2011-06-11 16:53:08 +0200 (sam., 11 juin 2011) $
+ * $Rev: 29 $
+ * 
+ * 
+ * 
+ * 
+ * 
+ */
+ 
+#include "ARP.h"
+#include "Ethernet.h"
+#include "Debug.h"
+#include "IPv4.h"
+#include <string.h>
+
+
+#define    DEBUG_CURRENT_MODULE_NAME    "ARP"
+#define    DEBUG_CURRENT_MODULE_ID        DEBUG_MODULE_ARP
+
+
+enum ARP_EntryStatus
+{
+    ARP_Entry_Free = 0,
+    ARP_Entry_PendingReply,
+    ARP_Entry_Dynamic,
+    ARP_Entry_Expired,
+    ARP_Entry_Static,
+    ARP_Entry_Count,
+};
+typedef enum ARP_EntryStatus ARP_EntryStatus_t;
+
+
+const char *arpEntryStatusText[ARP_Entry_Count] = 
+{
+    "free",
+    "pending",
+    "dynamic",
+    "expired",
+    "static",
+};
+
+struct ARP_CacheEntry
+{
+    IPv4_Addr_t            ipv4Addr;
+    Ethernet_Addr_t        ethernetAddr;
+    NetIF_t             *netIF;
+    uint16_t            age;
+    ARP_EntryStatus_t    status;
+    RTOS_Mutex_t        mutex;
+};
+typedef struct ARP_CacheEntry ARP_CacheEntry_t;
+
+
+#pragma push
+#pragma pack(1)
+static struct 
+{
+    Ethernet_Header_t    ethernetHeader;
+    ARP_Header_t        arpHeader;
+    ARP_IPv4Data_t        ipv4ARPData;
+} arp_FullIPv4Packet;
+#pragma pop
+
+
+static void Init(void);
+static void Handler(NetIF_t *netIF, Packet_t *packet);
+static void PeriodicFunction(void);
+static ARP_CacheEntry_t *GetReusableEntry(void);
+static ARP_CacheEntry_t *GetEntryByIPv4Address(IPv4_Addr_t address);
+
+
+static ARP_CacheEntry_t        arp_CacheTable[ARP_CACHE_MAX_ENTRIES];
+
+
+Protocol_Handler_t arp = 
+{
+    PROTOCOL_INDEX_NOT_INITIALIZED,                /* Always PROTOCOL_INDEX_NOT_INITIALIZED at initialization */
+    Protocol_ID_ARP,                             /* Protocol ID */
+    htons(ETHERNET_PROTO_ARP),                     /* Protocol number */
+    Init,                                         /* Protocol initialisation function */
+    Handler,                                    /* Protocol handler */
+    NULL,                                        /* Protocol registration function */
+    NULL,                                        /* API registration function */
+};
+
+
+static void Init(void)
+{
+    int32_t                index;
+    
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing ARP layer"));
+    memset(arp_CacheTable, 0, sizeof(arp_CacheTable));
+    for (index = 0; index < ARP_CACHE_MAX_ENTRIES; index++)
+    {
+        arp_CacheTable[index].mutex = RTOS_MUTEX_CREATE();
+    }
+    NetIF_RegisterPeriodicFunction("ARP cache", PeriodicFunction, ARP_FUNCTION_PERIOD);
+}
+
+
+static void Handler(NetIF_t *netIF, Packet_t *packet)
+{
+    static ARP_Type_t			type;
+    static ARP_Protocol_t		protocol;
+    static ARP_Operation_t		operation;
+    static ARP_IPv4Data_t		*ipv4ARP;
+    static ARP_Header_t			*arpHeader;
+    static Ethernet_Addr_t		*ourHWAddress;
+    static Ethernet_Header_t	*ethernetHeader;
+    static ARP_CacheEntry_t		*entry;
+
+	arpHeader = (ARP_Header_t *)packet->data;
+    type = ntohs(arpHeader->type);
+    protocol = ntohs(arpHeader->protocol);
+    operation = ntohs(arpHeader->operation);
+
+    if (type != ARP_HW_TYPE_ENET) goto Exit;            /* not an ethernet ARP, ignore  */
+    if (protocol != ETHERNET_PROTO_IPV4) goto Exit;        /* Not an IPv4 ARP, ignore */
+    
+    ipv4ARP = (ARP_IPv4Data_t *)(arpHeader + 1);
+    
+    switch(operation)
+    {
+        case ARP_OPERATION_REQUEST:
+            if (ipv4ARP->ipDest.addr == netIF->ipv4Address.addr)     /* Does it match our hw address? */
+            {
+                DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE0)
+                {
+                    ARP_DumpHeader("Got ", arpHeader);
+                }
+                
+                ourHWAddress = (Ethernet_Addr_t *)netIF->driverParameter;
+                
+                arpHeader->operation = htons(ARP_OPERATION_REPLY);
+                
+                ipv4ARP->hwDest = ipv4ARP->hwSource;
+                ipv4ARP->ipDest.addr = ipv4ARP->ipSource.addr;
+                ipv4ARP->hwSource = *ourHWAddress;
+                ipv4ARP->ipSource = netIF->ipv4Address;
+                
+                NetIF_ProtoPop(packet);
+
+                ethernetHeader = (Ethernet_Header_t *)packet->data;
+                ethernetHeader->destination = ethernetHeader->source;
+                ethernetHeader->source = *ourHWAddress;
+                
+                DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE0)
+                {                
+                    ARP_DumpHeader("Replying ", arpHeader);
+                }
+                                
+                netIF->driver->Write(packet->data, packet->length);
+            }
+            
+            break;
+            
+        case ARP_OPERATION_REPLY:
+            /* Check if it matches an entry we requested */
+            DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE0)
+            {
+                ARP_DumpHeader("Got ", arpHeader);
+            }
+            
+            entry = GetEntryByIPv4Address(ipv4ARP->ipSource);
+            if (entry == NULL) break;    /* fake arp request */
+            
+            entry->status = ARP_Entry_Dynamic;
+            entry->ethernetAddr = ipv4ARP->hwSource;
+            entry->netIF = netIF;
+            entry->age = 0;
+            
+            RTOS_MUTEX_UNLOCK(entry->mutex);
+            
+            DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE0)
+            {
+                DEBUG_RAW(("Adding entry %d.%d.%d.%d at %02x:%02x:%02x:%02x:%02x:%02x",
+                    ipv4ARP->ipSource.IP0,
+                    ipv4ARP->ipSource.IP1,
+                    ipv4ARP->ipSource.IP2,
+                    ipv4ARP->ipSource.IP3,
+                    ipv4ARP->hwSource.MA0,
+                    ipv4ARP->hwSource.MA1,
+                    ipv4ARP->hwSource.MA2,
+                    ipv4ARP->hwSource.MA3,
+                    ipv4ARP->hwSource.MA4,
+                    ipv4ARP->hwSource.MA5
+                ));
+            }
+            break;
+    }
+    
+Exit:
+    return;
+}
+
+
+static void PeriodicFunction(void)
+{
+    int32_t        index;
+    ARP_CacheEntry_t    *entry;
+    
+    for (index = 0; index < ARP_CACHE_MAX_ENTRIES; index++)
+    {
+        entry = arp_CacheTable + index;
+        RTOS_MUTEX_LOCK(entry->mutex);
+        switch(entry->status)
+        {
+            case ARP_Entry_Dynamic:
+                entry->age += ARP_FUNCTION_PERIOD;
+                if (entry->age > ARP_MAX_ENTRY_AGE)
+                {
+                    entry->status = ARP_Entry_Expired;
+                    entry->age = 0;
+                }
+                break;
+                
+            case ARP_Entry_PendingReply:
+                entry->age += ARP_FUNCTION_PERIOD;
+                if (entry->age > ARP_MAX_ENTRY_AGE)
+                {
+                    entry->status = ARP_Entry_Free;
+                    entry->age = 0;
+                }
+                break;
+        }
+        RTOS_MUTEX_UNLOCK(entry->mutex);
+    }
+}
+
+
+static ARP_CacheEntry_t *GetReusableEntry(void)
+{
+    int32_t                index,
+                        oldestEntryIndex, oldestEntryAge;
+    ARP_CacheEntry_t    *entry;
+    
+    /* First look for a free entry */
+    for (index = 0; index < ARP_CACHE_MAX_ENTRIES; index++)
+    {
+        entry = arp_CacheTable + index;
+        RTOS_MUTEX_LOCK(entry->mutex);
+        
+        if (entry->status == ARP_Entry_Free)
+        {
+            break;
+        }
+
+        RTOS_MUTEX_UNLOCK(entry->mutex);
+        entry = NULL;
+    }
+    
+    if (entry != NULL) goto Exit;    /* A free entry was found, return it */
+    
+    /* Now look for an expired entry */
+    oldestEntryIndex = -1;
+    oldestEntryAge = -1;
+    for (index = 0; index < ARP_CACHE_MAX_ENTRIES; index++)
+    {
+        entry = arp_CacheTable + index;
+        RTOS_MUTEX_LOCK(entry->mutex);
+        
+        if (entry->age > oldestEntryAge)
+        {
+            oldestEntryIndex = index;
+            oldestEntryAge = entry->age;
+        }
+        
+        if (entry->status == ARP_Entry_Expired)
+        {
+            break;
+        }
+
+        RTOS_MUTEX_UNLOCK(entry->mutex);
+        entry = NULL;
+    }
+
+    if (entry != NULL) goto Exit;    /* An expired entry was found, return it */
+
+    /* Last possibility, return the oldest non static entry */    
+    entry = arp_CacheTable + oldestEntryIndex;
+    RTOS_MUTEX_LOCK(entry->mutex);
+
+Exit:
+    return entry;
+}
+
+
+static ARP_CacheEntry_t *GetEntryByIPv4Address(IPv4_Addr_t address)
+{
+    int32_t                index;
+    ARP_CacheEntry_t    *entry = NULL;
+    
+    for (index = 0; index < ARP_CACHE_MAX_ENTRIES; index++)
+    {
+        entry = arp_CacheTable + index;
+        RTOS_MUTEX_LOCK(entry->mutex);
+        
+        if (entry->ipv4Addr.addr == address.addr)
+        {
+            break;
+        }
+        RTOS_MUTEX_UNLOCK(entry->mutex);
+        entry = NULL;
+    }
+    
+    return entry;
+}
+
+
+int32_t ARP_ResolveIPv4Address(NetIF_t *netIF, IPv4_Addr_t address, Ethernet_Addr_t *ethernetAddr)
+{
+    int32_t                result = -1;
+    Ethernet_Addr_t        *hwAddress;
+    ARP_CacheEntry_t    *entry;
+    
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Resolving %d.%d.%d.%d",
+        address.IP0,
+        address.IP1,
+        address.IP2,
+        address.IP3
+    ));
+    
+    /* Look if entry is already available in table */
+    entry = GetEntryByIPv4Address(address);
+    if (entry != NULL)                /* Found entry, look its status */
+    {
+        switch(entry->status)
+        {
+            case ARP_Entry_Static:
+                DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("Found static entry"));
+                if (ethernetAddr != NULL) *ethernetAddr = entry->ethernetAddr;
+                RTOS_MUTEX_UNLOCK(entry->mutex);
+                result = 0;
+                break;
+                
+            case ARP_Entry_Dynamic:
+                DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("Found dynamic entry"));
+                if (ethernetAddr != NULL) *ethernetAddr = entry->ethernetAddr;
+                entry->age = 0;
+                RTOS_MUTEX_UNLOCK(entry->mutex);
+                result = 0;
+                break;
+                
+            case ARP_Entry_Expired:
+                DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("Found expired entry, reactivating it"));
+                if (ethernetAddr != NULL) *ethernetAddr = entry->ethernetAddr;
+                entry->status = ARP_Entry_Dynamic;
+                entry->age = 0;
+                RTOS_MUTEX_UNLOCK(entry->mutex);
+                result = 0;
+                break;
+                
+            case ARP_Entry_PendingReply:
+                DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("Found pending entry"));
+                entry->age = 0;
+                RTOS_MUTEX_UNLOCK(entry->mutex);
+                break;
+                
+            default:
+                DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Default?!"));
+                break;
+        }
+    }
+    
+    if (result == 0) goto Exit;        /* Resolution was successfull, exit */
+    
+    
+    /* Entry not found, send a request */
+    result = -1;
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Sending ARP resolution request for %d.%d.%d.%d",
+        address.IP0,
+        address.IP1,
+        address.IP2,
+        address.IP3
+    ));
+    
+    /* Update entry, setting its status to Pending reply */
+    entry = GetReusableEntry();
+    if (entry != NULL)
+    {
+        entry->status = ARP_Entry_PendingReply;
+        entry->ipv4Addr.addr = address.addr;
+        entry->netIF = netIF;
+        entry->age = 0;
+        RTOS_MUTEX_UNLOCK(entry->mutex);
+    }
+    /* Send ARP who-has */    
+    hwAddress = (Ethernet_Addr_t *)netIF->driverParameter;
+
+    arp_FullIPv4Packet.ethernetHeader.destination = ethernet_Addr_Broadcast;
+    arp_FullIPv4Packet.ethernetHeader.source = *hwAddress;
+    arp_FullIPv4Packet.ethernetHeader.protocol = htons(ETHERNET_PROTO_ARP);
+    
+    arp_FullIPv4Packet.arpHeader.type = htons(ARP_HW_TYPE_ENET);
+    arp_FullIPv4Packet.arpHeader.protocol = htons(ETHERNET_PROTO_IPV4);
+    arp_FullIPv4Packet.arpHeader.operation = htons(ARP_OPERATION_REQUEST);
+    arp_FullIPv4Packet.arpHeader.hardAddrLen = 6;
+    arp_FullIPv4Packet.arpHeader.protoAddrLen = 4;
+    
+    arp_FullIPv4Packet.ipv4ARPData.hwSource = *hwAddress;
+    arp_FullIPv4Packet.ipv4ARPData.ipSource = netIF->ipv4Address;
+    arp_FullIPv4Packet.ipv4ARPData.hwDest = ethernet_Addr_Null;
+    arp_FullIPv4Packet.ipv4ARPData.ipDest = address;
+    
+    DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE0)
+    {
+        ARP_DumpHeader("Sending ", &arp_FullIPv4Packet.arpHeader);
+    }
+    
+    netIF->driver->Write((uint8_t *)&arp_FullIPv4Packet, sizeof(arp_FullIPv4Packet));
+    
+Exit:
+    return result;
+}
+
+
+int32_t ARP_AddStaticEntry(NetIF_t *netIF, IPv4_Addr_t address, const Ethernet_Addr_t *ethernetAddr)
+{
+    int32_t                result = 0;
+    ARP_CacheEntry_t    *entry;
+    
+    entry = GetReusableEntry();
+    if (entry == NULL)
+    {
+        result = -1;
+        goto Exit;
+    }
+    entry->netIF = netIF;
+    entry->status = ARP_Entry_Static;
+    entry->ipv4Addr.addr = address.addr;
+    entry->ethernetAddr = *ethernetAddr;
+    entry->age = 0;
+    RTOS_MUTEX_UNLOCK(entry->mutex);
+
+Exit:
+    return result;
+}
+
+
+int32_t ARP_RemoveEntry(const NetIF_t *netIF, IPv4_Addr_t address)
+{
+    int32_t        result = 0;
+    
+    
+    
+    return result;
+}
+
+
+void ARP_FlushCache(Bool_t flushStaticEntries)
+{
+    int32_t                index;
+    ARP_CacheEntry_t    *entry;
+    
+    for (index = 0; index < ARP_CACHE_MAX_ENTRIES; index++)
+    {
+        entry = arp_CacheTable + index;
+        RTOS_MUTEX_LOCK(entry->mutex);
+        if ((entry->status == ARP_Entry_Static) && (!flushStaticEntries)) 
+        {
+            RTOS_MUTEX_UNLOCK(entry->mutex);
+            continue;
+        }
+        entry->status = ARP_Entry_Free;
+		entry->ipv4Addr = ipv4_Addr_Any;
+		entry->ethernetAddr = ethernet_Addr_Null;
+		entry->age = 0;
+        RTOS_MUTEX_UNLOCK(entry->mutex);
+    }
+}
+
+
+void ARP_DisplayCache(void)
+{
+    int32_t                index;
+    ARP_CacheEntry_t    *entry = NULL;
+    
+    DEBUG_RAW(("ARP cache"));
+    DEBUG_RAW(("index dev   MAC address            type  age  IPv4 address"));
+    DEBUG_RAW(("----------------------------------------------------------"));
+      /*      en0   00:11:22:33:44:55  dyn    10 163.157.128.131 */
+    for (index = 0; index < ARP_CACHE_MAX_ENTRIES; index++)
+    {
+        entry = arp_CacheTable + index;
+    
+        DEBUG_RAW(("%2d    %s%c   %02x:%02x:%02x:%02x:%02x:%02x  %8s  %4d  %d.%d.%d.%d",
+            index, 
+            entry->status != ARP_Entry_Free ? entry->netIF->name : "--", 
+            entry->status != ARP_Entry_Free ? entry->netIF->index + '0' : '-', 
+            entry->ethernetAddr.MA0,
+            entry->ethernetAddr.MA1,
+            entry->ethernetAddr.MA2,
+            entry->ethernetAddr.MA3,
+            entry->ethernetAddr.MA4,
+            entry->ethernetAddr.MA5,
+                
+            arpEntryStatusText[entry->status],
+            entry->age,
+            
+            entry->ipv4Addr.IP0,
+            entry->ipv4Addr.IP1,
+            entry->ipv4Addr.IP2,
+            entry->ipv4Addr.IP3
+        ));    
+    }
+}
+
+void ARP_DumpHeader(const char *prefix, ARP_Header_t *arpHeader)
+{
+    ARP_IPv4Data_t    *ipv4ARP = NULL;
+    
+    if (arpHeader->protocol == htons(ETHERNET_PROTO_IPV4))
+    {
+        ipv4ARP = (ARP_IPv4Data_t *)(arpHeader + 1);
+        
+        switch(ntohs(arpHeader->operation))
+        {
+            case ARP_OPERATION_REQUEST:
+                DEBUG_RAW(("%sARP who-has %d.%d.%d.%d tell %02x:%02x:%02x:%02x:%02x:%02x",
+                    prefix != NULL ? prefix : "",
+            
+                    ipv4ARP->ipDest.IP0,
+                    ipv4ARP->ipDest.IP1,
+                    ipv4ARP->ipDest.IP2,
+                    ipv4ARP->ipDest.IP3,
+            
+                    ipv4ARP->hwSource.MA0,
+                    ipv4ARP->hwSource.MA1,
+                    ipv4ARP->hwSource.MA2,
+                    ipv4ARP->hwSource.MA3,
+                    ipv4ARP->hwSource.MA4,
+                    ipv4ARP->hwSource.MA5
+                ));
+                break;
+                
+            case ARP_OPERATION_REPLY:
+                DEBUG_RAW(("%sARP %d.%d.%d.%d is-at %02x:%02x:%02x:%02x:%02x:%02x",
+                    prefix != NULL ? prefix : "",
+            
+                    ipv4ARP->ipSource.IP0,
+                    ipv4ARP->ipSource.IP1,
+                    ipv4ARP->ipSource.IP2,
+                    ipv4ARP->ipSource.IP3,
+            
+                    ipv4ARP->hwSource.MA0,
+                    ipv4ARP->hwSource.MA1,
+                    ipv4ARP->hwSource.MA2,
+                    ipv4ARP->hwSource.MA3,
+                    ipv4ARP->hwSource.MA4,
+                    ipv4ARP->hwSource.MA5
+                ));
+                break;
+            
+            default:
+                break;
+        }
+    }
+    else
+    {
+        DEBUG_RAW(("%sARP: unsupported protocol %d",
+            prefix != NULL ? prefix : "",
+            arpHeader->protocol
+        ));
+    }
+}
--- a/ARP.h	Sun Jun 12 11:23:03 2011 +0000
+++ b/ARP.h	Sun Jun 12 19:17:11 2011 +0000
@@ -59,12 +59,12 @@
 extern Protocol_Handler_t arp;
 
 
-CAPI int32_t    ARP_ResolveIPv4Address(NetIF_t *netIF, IPv4_Addr_t address, Ethernet_Addr_t *ethernetAddr);
-CAPI int32_t    ARP_AddStaticEntry(NetIF_t *netIF, IPv4_Addr_t address, const Ethernet_Addr_t *ethernetAddr);
-CAPI int32_t    ARP_RemoveEntry(const NetIF_t *netIF, IPv4_Addr_t address);
-CAPI void        ARP_InvalidateCache(Bool_t flushStaticEntries);
-CAPI void        ARP_Timer(void);
-CAPI void        ARP_DisplayCache(void);
-CAPI void         ARP_DumpHeader(const char *prefix, ARP_Header_t *arpHeader);
+int32_t    ARP_ResolveIPv4Address(NetIF_t *netIF, IPv4_Addr_t address, Ethernet_Addr_t *ethernetAddr);
+int32_t    ARP_AddStaticEntry(NetIF_t *netIF, IPv4_Addr_t address, const Ethernet_Addr_t *ethernetAddr);
+int32_t    ARP_RemoveEntry(const NetIF_t *netIF, IPv4_Addr_t address);
+void        ARP_FlushCache(Bool_t flushStaticEntries);
+void        ARP_Timer(void);
+void        ARP_DisplayCache(void);
+void         ARP_DumpHeader(const char *prefix, ARP_Header_t *arpHeader);
 
 #endif /* __ARP_H__ */
--- a/Debug.c	Sun Jun 12 11:23:03 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/*
- * $Id: Debug.c 26 2011-06-09 10:24:02Z benoit $
- * $Author: benoit $
- * $Date: 2011-06-09 12:24:02 +0200 (jeu., 09 juin 2011) $
- * $Rev: 26 $
- * 
- * 
- * 
- * 
- * 
- */
- 
-#include "Debug.h"
-
-
-Debug_LevelMask_t    debug_LevelMask = DEBUG_LEVEL_WARNING | DEBUG_LEVEL_ERROR | DEBUG_LEVEL_PANIC;
-Debug_ModuleMask_t    debug_ModuleMask = DEBUG_MODULE_ALL;
-
-
-void Debug_SetMasks(Debug_ModuleMask_t moduleMask, Debug_LevelMask_t levelMask)
-{
-    debug_LevelMask = levelMask;
-    debug_ModuleMask = moduleMask;
-}
-
-const char *Debug_GetText(uint32_t level)
-{
-    char *result;
-
-    switch(level)
-    {
-        case DEBUG_LEVEL_INFO:
-            result = "INFO";
-            break;
-            
-        case DEBUG_LEVEL_WARNING:
-            result = "WARNING";
-            break;
-        
-        case DEBUG_LEVEL_ERROR:
-            result = "ERROR";
-            break;
-        
-        case DEBUG_LEVEL_PANIC:
-            result = "PANIC";
-            break;
-        
-        case DEBUG_LEVEL_VERBOSE0:
-            result = "VERBOSE0";
-            break;
-        
-        case DEBUG_LEVEL_VERBOSE1:
-            result = "VERBOSE1";
-            break;
-        
-        case DEBUG_LEVEL_VERBOSE2:
-            result = "VERBOSE2";
-            break;
-        
-        default:
-            result = "<unknown>";
-            break;
-    }
-    
-    return result;
-}
-
-
-void Debug_DumpBufferHex(uint8_t *buffer, int32_t length)
-{
-    int32_t        i, address, index, tmpIndex;
-    
-    index = 0;
-    address = 0;
-    while(index < length)
-    {
-        /* Print buffer relative address */
-        DEBUG_RAW_NOCRLF(("%03X  ", address));
-    
-        /* Print hex bytes */
-        for (i = 0; i < DEBUG_BUFFER_DUMP_LINE_LEN; i++)
-        {
-            tmpIndex = index + i;
-            if (tmpIndex < length)
-            {
-                DEBUG_RAW_NOCRLF(("%02X ", buffer[tmpIndex]));
-            }
-            else
-            {
-                DEBUG_RAW_NOCRLF(("   "));
-            }
-        }
-    
-        DEBUG_RAW_NOCRLF((" -  "));
-    
-        /* Print ascii chars */
-        for (i = 0; i < DEBUG_BUFFER_DUMP_LINE_LEN; i++)
-        {
-            tmpIndex = index + i;
-            if (tmpIndex < length)
-            {
-                DEBUG_RAW_NOCRLF(("%c", buffer[tmpIndex] >= 32 ? buffer[tmpIndex] : '.'));
-            }
-        }
-
-        index += DEBUG_BUFFER_DUMP_LINE_LEN;
-        address += DEBUG_BUFFER_DUMP_LINE_LEN;
-        
-        DEBUG_RAW_NOCRLF(("\r\n"));
-    }
-    
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Debug.cpp	Sun Jun 12 19:17:11 2011 +0000
@@ -0,0 +1,113 @@
+/*
+ * $Id: Debug.c 26 2011-06-09 10:24:02Z benoit $
+ * $Author: benoit $
+ * $Date: 2011-06-09 12:24:02 +0200 (jeu., 09 juin 2011) $
+ * $Rev: 26 $
+ * 
+ * 
+ * 
+ * 
+ * 
+ */
+ 
+#include "Debug.h"
+
+
+Debug_LevelMask_t    debug_LevelMask = DEBUG_LEVEL_WARNING | DEBUG_LEVEL_ERROR | DEBUG_LEVEL_PANIC;
+Debug_ModuleMask_t    debug_ModuleMask = DEBUG_MODULE_ALL;
+
+
+void Debug_SetMasks(Debug_ModuleMask_t moduleMask, Debug_LevelMask_t levelMask)
+{
+    debug_LevelMask = levelMask;
+    debug_ModuleMask = moduleMask;
+}
+
+const char *Debug_GetText(uint32_t level)
+{
+    char *result;
+
+    switch(level)
+    {
+        case DEBUG_LEVEL_INFO:
+            result = "INFO";
+            break;
+            
+        case DEBUG_LEVEL_WARNING:
+            result = "WARNING";
+            break;
+        
+        case DEBUG_LEVEL_ERROR:
+            result = "ERROR";
+            break;
+        
+        case DEBUG_LEVEL_PANIC:
+            result = "PANIC";
+            break;
+        
+        case DEBUG_LEVEL_VERBOSE0:
+            result = "VERBOSE0";
+            break;
+        
+        case DEBUG_LEVEL_VERBOSE1:
+            result = "VERBOSE1";
+            break;
+        
+        case DEBUG_LEVEL_VERBOSE2:
+            result = "VERBOSE2";
+            break;
+        
+        default:
+            result = "<unknown>";
+            break;
+    }
+    
+    return result;
+}
+
+
+void Debug_DumpBufferHex(uint8_t *buffer, int32_t length)
+{
+    int32_t        i, address, index, tmpIndex;
+    
+    index = 0;
+    address = 0;
+    while(index < length)
+    {
+        /* Print buffer relative address */
+        DEBUG_RAW_NOCRLF(("%03X  ", address));
+    
+        /* Print hex bytes */
+        for (i = 0; i < DEBUG_BUFFER_DUMP_LINE_LEN; i++)
+        {
+            tmpIndex = index + i;
+            if (tmpIndex < length)
+            {
+                DEBUG_RAW_NOCRLF(("%02X ", buffer[tmpIndex]));
+            }
+            else
+            {
+                DEBUG_RAW_NOCRLF(("   "));
+            }
+        }
+    
+        DEBUG_RAW_NOCRLF((" -  "));
+    
+        /* Print ascii chars */
+        for (i = 0; i < DEBUG_BUFFER_DUMP_LINE_LEN; i++)
+        {
+            tmpIndex = index + i;
+            if (tmpIndex < length)
+            {
+                DEBUG_RAW_NOCRLF(("%c", buffer[tmpIndex] >= 32 ? buffer[tmpIndex] : '.'));
+            }
+        }
+
+        index += DEBUG_BUFFER_DUMP_LINE_LEN;
+        address += DEBUG_BUFFER_DUMP_LINE_LEN;
+        
+        DEBUG_RAW_NOCRLF(("\r\n"));
+    }
+    
+}
+
--- a/Debug.h	Sun Jun 12 11:23:03 2011 +0000
+++ b/Debug.h	Sun Jun 12 19:17:11 2011 +0000
@@ -91,8 +91,8 @@
 
 
 
-CAPI const char *Debug_GetText(uint32_t level);
-CAPI void Debug_DumpBufferHex(uint8_t *buffer, int32_t length);
-CAPI void Debug_SetMasks(Debug_ModuleMask_t moduleMask, Debug_LevelMask_t levelMask);
+const char *Debug_GetText(uint32_t level);
+void Debug_DumpBufferHex(uint8_t *buffer, int32_t length);
+void Debug_SetMasks(Debug_ModuleMask_t moduleMask, Debug_LevelMask_t levelMask);
 
 #endif  /* __DEBUG_H__ */
--- a/Ethernet.c	Sun Jun 12 11:23:03 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-/*
- * $Id: Ethernet.c 29 2011-06-11 14:53:08Z benoit $
- * $Author: benoit $
- * $Date: 2011-06-11 16:53:08 +0200 (sam., 11 juin 2011) $
- * $Rev: 29 $
- * 
- * 
- * 
- * 
- * 
- */
- 
-#include "Ethernet.h"
-#include "Debug.h"
-#include <string.h>
-
-
-#define    DEBUG_CURRENT_MODULE_NAME    "Ethernet"
-#define    DEBUG_CURRENT_MODULE_ID        DEBUG_MODULE_ETHERNET
-
-
-static void Init(void);
-static int32_t RegisterProtocol(Protocol_Handler_t *protocolHandler);
-static int32_t RegisterAPI(Net_API_t *api);
-
-void Ethernet_Handler(NetIF_t *netIF, Packet_t *packet);
-
-
-static Protocol_Handler_t    *protocolHandlerTable[ETHERNET_PROTOCOL_MAX_COUNT];
-static int32_t                protocolHandlerCount = 0;
-
-const Ethernet_Addr_t        ethernet_Addr_Broadcast =     {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-const Ethernet_Addr_t        ethernet_Addr_Null =         {0, 0, 0, 0, 0, 0};
-
-
-Protocol_Handler_t ethernet = 
-{ 
-    PROTOCOL_INDEX_NOT_INITIALIZED,     /* Always PROTOCOL_INDEX_NOT_INITIALIZED at initialization */
-    Protocol_ID_Ethernet,                 /* Protocol ID */
-    PROTOCOL_NUMBER_NONE,                 /* Protocol number */
-    Init,                                 /* Protocol initialisation function */
-    Ethernet_Handler,                     /* Protocol handler */
-    RegisterProtocol,                     /* Protocol registration function */
-    RegisterAPI,                        /* API registration function */
-};
-
-
-static Net_API_t    *netAPITable[NET_API_PER_PROTOCOL_MAX_COUNT];
-static int32_t        netAPICount = 0;
-
-
-static void Init(void)
-{
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing ethernet layer"));
-    memset(protocolHandlerTable, 0, sizeof(protocolHandlerTable));
-    protocolHandlerCount = 0;
-    memset(netAPITable, 0, sizeof(netAPITable));
-    netAPICount = 0;
-}
-
-
-static int32_t RegisterProtocol(Protocol_Handler_t *protocolHandler)
-{
-    int32_t                            result = 0;
-    
-    if (protocolHandlerCount >= ETHERNET_PROTOCOL_MAX_COUNT)
-    {
-        DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Too many protocols"));
-        result = -1;
-        mbedNet_LastError = mbedNetResult_TooManyRegisteredProtocols;
-        goto Exit;
-    }
-    
-    protocolHandlerTable[protocolHandlerCount] = protocolHandler;
-    protocolHandler->index = protocolHandlerCount;
-    protocolHandler->Init();
-    
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Registered protocol %04X ethernet/%s",
-        ntohs(protocolHandler->protocolNumber),
-        protocol_IDNames[protocolHandler->protocolID]
-    ));
-    
-    protocolHandlerCount++;
-        
-Exit:
-    return result;
-}
-
-
-static int32_t RegisterAPI(Net_API_t *netAPI)
-{
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Registering %s API", api_IDNames[netAPI->apiID]));
-    netAPI->InitAPI();
-    netAPITable[netAPICount] = netAPI;
-    netAPICount++;
-    return -1;
-}
-
-
-void Ethernet_Handler(NetIF_t *netIF, Packet_t *packet)
-{
-    int32_t                    protocolIndex, index;
-    Ethernet_Proto_t        protocolNumber;
-    Protocol_Handler_t        *protocolHandler;
-    Ethernet_Header_t        *ethernetHeader = (Ethernet_Header_t *)packet->data;
-    
-    protocolNumber = ethernetHeader->protocol;
-    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("frame of %d bytes for protocol %04X (payload + %02d)", packet->length, ntohs(protocolNumber), sizeof(Ethernet_Header_t)));
-    //Debug_DumpBufferHex(packet, length);
-    
-    /* Process API if any */
-    for (index = 0; index < netAPICount; index++)
-    {
-        netAPITable[index]->Hook(netIF, Protocol_ID_Ethernet, packet);
-    }
-    
-    for (protocolIndex = 0; protocolIndex < protocolHandlerCount; protocolIndex++)
-    {
-        protocolHandler = protocolHandlerTable[protocolIndex];
-        if (protocolHandler->protocolNumber == protocolNumber)
-        {
-            DEBUG_SOURCE(DEBUG_LEVEL_VERBOSE2, ("'%s' frame of %d bytes", protocol_IDNames[protocolHandler->protocolID], packet->length));
-            NetIF_ProtoPush(packet, sizeof(Ethernet_Header_t), Protocol_ID_Ethernet);
-            protocolHandler->HandlePacket(netIF, packet);
-            goto Exit;
-        }
-    }
-    
-Exit:
-    return;
-}
-
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Ethernet.cpp	Sun Jun 12 19:17:11 2011 +0000
@@ -0,0 +1,131 @@
+/*
+ * $Id: Ethernet.c 29 2011-06-11 14:53:08Z benoit $
+ * $Author: benoit $
+ * $Date: 2011-06-11 16:53:08 +0200 (sam., 11 juin 2011) $
+ * $Rev: 29 $
+ * 
+ * 
+ * 
+ * 
+ * 
+ */
+ 
+#include "Ethernet.h"
+#include "Debug.h"
+#include <string.h>
+
+
+#define    DEBUG_CURRENT_MODULE_NAME    "Ethernet"
+#define    DEBUG_CURRENT_MODULE_ID        DEBUG_MODULE_ETHERNET
+
+
+static void Init(void);
+static int32_t RegisterProtocol(Protocol_Handler_t *protocolHandler);
+static int32_t RegisterAPI(Net_API_t *api);
+static void Handler(NetIF_t *netIF, Packet_t *packet);
+
+
+static Protocol_Handler_t    *protocolHandlerTable[ETHERNET_PROTOCOL_MAX_COUNT];
+static int32_t                protocolHandlerCount = 0;
+
+const Ethernet_Addr_t        ethernet_Addr_Broadcast =     {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+const Ethernet_Addr_t        ethernet_Addr_Null =         {0, 0, 0, 0, 0, 0};
+
+
+Protocol_Handler_t ethernet = 
+{ 
+    PROTOCOL_INDEX_NOT_INITIALIZED,     /* Always PROTOCOL_INDEX_NOT_INITIALIZED at initialization */
+    Protocol_ID_Ethernet,               /* Protocol ID */
+    PROTOCOL_NUMBER_NONE,               /* Protocol number */
+    Init,                               /* Protocol initialisation function */
+    Handler,                     		/* Protocol handler */
+    RegisterProtocol,                   /* Protocol registration function */
+    RegisterAPI,                        /* API registration function */
+};
+
+
+static Net_API_t    *netAPITable[NET_API_PER_PROTOCOL_MAX_COUNT];
+static int32_t        netAPICount = 0;
+
+
+static void Init(void)
+{
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing ethernet layer"));
+    memset(protocolHandlerTable, 0, sizeof(protocolHandlerTable));
+    protocolHandlerCount = 0;
+    memset(netAPITable, 0, sizeof(netAPITable));
+    netAPICount = 0;
+}
+
+
+static int32_t RegisterProtocol(Protocol_Handler_t *protocolHandler)
+{
+    int32_t                            result = 0;
+    
+    if (protocolHandlerCount >= ETHERNET_PROTOCOL_MAX_COUNT)
+    {
+        DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Too many protocols"));
+        result = -1;
+        mbedNet_LastError = mbedNetResult_TooManyRegisteredProtocols;
+        goto Exit;
+    }
+    
+    protocolHandlerTable[protocolHandlerCount] = protocolHandler;
+    protocolHandler->index = protocolHandlerCount;
+    protocolHandler->Init();
+    
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Registered protocol %04X ethernet/%s",
+        ntohs(protocolHandler->protocolNumber),
+        protocol_IDNames[protocolHandler->protocolID]
+    ));
+    
+    protocolHandlerCount++;
+        
+Exit:
+    return result;
+}
+
+
+static int32_t RegisterAPI(Net_API_t *netAPI)
+{
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Registering %s API", api_IDNames[netAPI->apiID]));
+    netAPI->InitAPI();
+    netAPITable[netAPICount] = netAPI;
+    netAPICount++;
+    return -1;
+}
+
+
+void Handler(NetIF_t *netIF, Packet_t *packet)
+{
+    int32_t				protocolIndex, index;
+    Ethernet_Proto_t	protocolNumber;
+    Protocol_Handler_t	*protocolHandler;
+    Ethernet_Header_t	*ethernetHeader;
+    
+	ethernetHeader = (Ethernet_Header_t *)packet->data;
+    protocolNumber = ethernetHeader->protocol;
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("frame of %d bytes for protocol %04X (payload + %02d)", packet->length, ntohs(protocolNumber), sizeof(Ethernet_Header_t)));
+    //Debug_DumpBufferHex(packet, length);
+    
+    /* Process API if any */
+    for (index = 0; index < netAPICount; index++)
+    {
+        netAPITable[index]->Hook(netIF, Protocol_ID_Ethernet, packet);
+    }
+    
+	for (protocolIndex = 0; protocolIndex < protocolHandlerCount; protocolIndex++)
+    {
+        protocolHandler = protocolHandlerTable[protocolIndex];
+        if (protocolHandler->protocolNumber == protocolNumber)
+        {
+			DEBUG_SOURCE(DEBUG_LEVEL_VERBOSE0, ("'%s' frame of %d bytes", protocol_IDNames[protocolHandler->protocolID], packet->length));
+            NetIF_ProtoPush(packet, sizeof(Ethernet_Header_t), Protocol_ID_Ethernet);
+            protocolHandler->HandlePacket(netIF, packet);
+            break;
+        }
+    }
+    return;
+}
+
+
--- a/ICMPv4.c	Sun Jun 12 11:23:03 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-/*
- * $Id: ICMPv4.c 29 2011-06-11 14:53:08Z benoit $
- * $Author: benoit $
- * $Date: 2011-06-11 16:53:08 +0200 (sam., 11 juin 2011) $
- * $Rev: 29 $
- * 
- * 
- * 
- * 
- * 
- */
- 
-#include "ICMPv4.h"
-#include "Ethernet.h"
-#include "Debug.h"
-
-
-#define    DEBUG_CURRENT_MODULE_NAME    "ICMPv4"
-#define    DEBUG_CURRENT_MODULE_ID        DEBUG_MODULE_ICMPV4
-
-
-static void Init(void);
-static void Handler(NetIF_t *netIF, Packet_t *packet);
-
-
-Protocol_Handler_t    icmpv4 = 
-{ 
-    PROTOCOL_INDEX_NOT_INITIALIZED,     /* Always PROTOCOL_INDEX_NOT_INITIALIZED at initialization */
-    Protocol_ID_ICMPv4,                 /* Protocol ID */
-    IPV4_PROTO_ICMPV4,                     /* Protocol number */
-    Init,                                 /* Protocol initialisation function */
-    Handler,                             /* Protocol handler */
-    NULL,                                /* Protocol registration function */
-    NULL,                                /* API registration function */
-};
-
-
-static void Init(void)
-{
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing ICMPv4 layer"));
-}
-
-
-static void Handler(NetIF_t *netIF, Packet_t *packet)
-{
-    ICMPv4_Header_t        *icmpv4Packet;
-    ICMPv4_Type_t        type;
-    ICMPv4_Code_t        code;
-    IPv4_Header_t        *ipv4Header;
-    Ethernet_Header_t    *ethernetHeader;
-    int32_t                depth, lengthToSend;
-    
-    //Debug_DumpBufferHex(packet, length);
-    
-
-    icmpv4Packet = (ICMPv4_Header_t *)packet->data;
-    type = icmpv4Packet->type;
-    code = icmpv4Packet->code;
-    code = code;
-
-    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("icmpv4 frame of %d bytes icmpv4(%02x, %02x) frame of %d bytes",
-        packet->length,
-        icmpv4Packet->type,
-        icmpv4Packet->code,
-        packet->length
-    ));
-    depth = packet->depth;
-    ipv4Header = (IPv4_Header_t *)packet->headerPtrTable[depth];
-    ethernetHeader = (Ethernet_Header_t *)packet->headerPtrTable[depth - 1];
-    
-    switch(type)
-    {
-        case ICMPV4_TYPE_ECHO_REQUEST:
-            DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE0)
-            {
-                ICMPv4_DumpHeader("Got ",  ipv4Header);
-            }
-            
-            ipv4Header->dest.addr = ipv4Header->source.addr;
-            ipv4Header->source.addr = netIF->ipv4Address.addr;
-            ethernetHeader->destination = ethernetHeader->source;
-            ethernetHeader->source = *((Ethernet_Addr_t *)netIF->driverParameter);
-            icmpv4Packet->type = ICMPV4_TYPE_ECHO_REPLY;
-            lengthToSend = packet->headerLenTable[depth - 1] + packet->headerLenTable[depth - 1] + ntohs(ipv4Header->totalLength);
-            icmpv4Packet->crc = 0;
-            icmpv4Packet->crc = ICMPv4_ComputeCRC(icmpv4Packet, ntohs(ipv4Header->totalLength) - packet->headerLenTable[depth]);
-            
-            DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE0)
-            {
-                ICMPv4_DumpHeader("Replying ", ipv4Header);
-            }
-            
-            netIF->driver->Write((uint8_t *)ethernetHeader, lengthToSend );
-            
-            break;
-            
-        default:
-            break;
-    }
-}
-
-
-uint16_t ICMPv4_ComputeCRC(ICMPv4_Header_t *packet, int32_t length)
-{
-    uint32_t    crc = 0, size = length;
-    uint16_t    *data = (uint16_t *)packet, tmp;
-    
-    while(size > 1)
-    {
-        tmp = ntohs(*data);
-        crc += tmp;
-        data++;
-        size -= sizeof(uint16_t);
-    }
-    
-    if (size > 0)
-    {
-        tmp = (*((uint8_t *)data)) << 8;
-        crc += tmp;
-    }
-    
-    crc = (crc >> 16) + (crc & 0xFFFF);
-    if (crc & 0xFFFF0000) crc = (crc >> 16) + (crc & 0xFFFF);
-        
-    return htons((~crc) & 0xFFFF);
-}
-
-
-Bool_t ICMPv4_CheckCRC(ICMPv4_Header_t *packet, int32_t length)
-{
-    return True;
-}
-
-
-void ICMPv4_DumpHeader(const char *prefix, IPv4_Header_t *ipv4Header)
-{
-    ICMPv4_Header_t    *icmpv4Header = (ICMPv4_Header_t *)(ipv4Header + 1);
-
-    switch(icmpv4Header->type)
-    {
-        case ICMPV4_TYPE_ECHO_REQUEST:
-            DEBUG_RAW((
-                "%sICMPv4 echo request from %d.%d.%d.%d",
-                prefix != NULL ? prefix : "",
-                ipv4Header->source.IP0,
-                ipv4Header->source.IP1,
-                ipv4Header->source.IP2,
-                ipv4Header->source.IP3
-            ));
-            break;
-            
-        case ICMPV4_TYPE_ECHO_REPLY:
-            DEBUG_RAW((
-                "%sICMPv4 echo reply to %d.%d.%d.%d",
-                prefix != NULL ? prefix : "",
-                ipv4Header->dest.IP0,
-                ipv4Header->dest.IP1,
-                ipv4Header->dest.IP2,
-                ipv4Header->dest.IP3
-            ));
-            break;
-
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ICMPv4.cpp	Sun Jun 12 19:17:11 2011 +0000
@@ -0,0 +1,162 @@
+/*
+ * $Id: ICMPv4.c 29 2011-06-11 14:53:08Z benoit $
+ * $Author: benoit $
+ * $Date: 2011-06-11 16:53:08 +0200 (sam., 11 juin 2011) $
+ * $Rev: 29 $
+ * 
+ * 
+ * 
+ * 
+ * 
+ */
+ 
+#include "ICMPv4.h"
+#include "Ethernet.h"
+#include "Debug.h"
+
+
+#define    DEBUG_CURRENT_MODULE_NAME    "ICMPv4"
+#define    DEBUG_CURRENT_MODULE_ID        DEBUG_MODULE_ICMPV4
+
+
+static void Init(void);
+static void Handler(NetIF_t *netIF, Packet_t *packet);
+
+
+Protocol_Handler_t    icmpv4 = 
+{ 
+    PROTOCOL_INDEX_NOT_INITIALIZED,     /* Always PROTOCOL_INDEX_NOT_INITIALIZED at initialization */
+    Protocol_ID_ICMPv4,                 /* Protocol ID */
+    IPV4_PROTO_ICMPV4,                     /* Protocol number */
+    Init,                                 /* Protocol initialisation function */
+    Handler,                             /* Protocol handler */
+    NULL,                                /* Protocol registration function */
+    NULL,                                /* API registration function */
+};
+
+
+static void Init(void)
+{
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing ICMPv4 layer"));
+}
+
+
+static void Handler(NetIF_t *netIF, Packet_t *packet)
+{
+    ICMPv4_Header_t      *icmpv4Packet;
+	ICMPv4_Type_t        type;
+    ICMPv4_Code_t        code;
+    IPv4_Header_t        *ipv4Header;
+    Ethernet_Header_t    *ethernetHeader;
+    int32_t               depth, lengthToSend;
+    
+    //Debug_DumpBufferHex(packet, length);
+    
+	icmpv4Packet = (ICMPv4_Header_t *)packet->data;
+    type = icmpv4Packet->type;
+    code = icmpv4Packet->code;
+
+    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("icmpv4 frame of %d bytes icmpv4(%02x, %02x) frame of %d bytes",
+        packet->length,
+        type,
+        code,
+        packet->length
+    ));
+    depth = packet->depth;
+    ipv4Header = (IPv4_Header_t *)packet->headerPtrTable[depth];
+    ethernetHeader = (Ethernet_Header_t *)packet->headerPtrTable[depth - 1];
+    
+    switch(type)
+    {
+        case ICMPV4_TYPE_ECHO_REQUEST:
+            DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE0)
+            {
+                ICMPv4_DumpHeader("Got ",  ipv4Header);
+            }
+            
+            ipv4Header->dest.addr = ipv4Header->source.addr;
+            ipv4Header->source.addr = netIF->ipv4Address.addr;
+            ethernetHeader->destination = ethernetHeader->source;
+            ethernetHeader->source = *((Ethernet_Addr_t *)netIF->driverParameter);
+            icmpv4Packet->type = ICMPV4_TYPE_ECHO_REPLY;
+            lengthToSend = packet->headerLenTable[depth - 1] + packet->headerLenTable[depth - 1] + ntohs(ipv4Header->totalLength);
+            icmpv4Packet->crc = 0;
+            icmpv4Packet->crc = ICMPv4_ComputeCRC(icmpv4Packet, ntohs(ipv4Header->totalLength) - packet->headerLenTable[depth]);
+            
+            DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE0)
+            {
+                ICMPv4_DumpHeader("Replying ", ipv4Header);
+            }
+            
+            netIF->driver->Write((uint8_t *)ethernetHeader, lengthToSend );
+            
+            break;
+            
+        default:
+            break;
+    }
+}
+
+
+uint16_t ICMPv4_ComputeCRC(ICMPv4_Header_t *packet, int32_t length)
+{
+    uint32_t    crc = 0, size = length;
+    uint16_t    *data = (uint16_t *)packet, tmp;
+    
+    while(size > 1)
+    {
+        tmp = ntohs(*data);
+        crc += tmp;
+        data++;
+        size -= sizeof(uint16_t);
+    }
+    
+    if (size > 0)
+    {
+        tmp = (*((uint8_t *)data)) << 8;
+        crc += tmp;
+    }
+    
+    crc = (crc >> 16) + (crc & 0xFFFF);
+    if (crc & 0xFFFF0000) crc = (crc >> 16) + (crc & 0xFFFF);
+        
+    return htons((~crc) & 0xFFFF);
+}
+
+
+Bool_t ICMPv4_CheckCRC(ICMPv4_Header_t *packet, int32_t length)
+{
+    return True;
+}
+
+
+void ICMPv4_DumpHeader(const char *prefix, IPv4_Header_t *ipv4Header)
+{
+    ICMPv4_Header_t    *icmpv4Header = (ICMPv4_Header_t *)(ipv4Header + 1);
+
+    switch(icmpv4Header->type)
+    {
+        case ICMPV4_TYPE_ECHO_REQUEST:
+            DEBUG_RAW((
+                "%sICMPv4 echo request from %d.%d.%d.%d",
+                prefix != NULL ? prefix : "",
+                ipv4Header->source.IP0,
+                ipv4Header->source.IP1,
+                ipv4Header->source.IP2,
+                ipv4Header->source.IP3
+            ));
+            break;
+            
+        case ICMPV4_TYPE_ECHO_REPLY:
+            DEBUG_RAW((
+                "%sICMPv4 echo reply to %d.%d.%d.%d",
+                prefix != NULL ? prefix : "",
+                ipv4Header->dest.IP0,
+                ipv4Header->dest.IP1,
+                ipv4Header->dest.IP2,
+                ipv4Header->dest.IP3
+            ));
+            break;
+
+    }
+}
--- a/ICMPv4.h	Sun Jun 12 11:23:03 2011 +0000
+++ b/ICMPv4.h	Sun Jun 12 19:17:11 2011 +0000
@@ -50,8 +50,8 @@
 extern Protocol_Handler_t    icmpv4;
 
 
-CAPI uint16_t    ICMPv4_ComputeCRC(ICMPv4_Header_t *packet, int32_t length);
-CAPI Bool_t        ICMPv4_CheckCRC(ICMPv4_Header_t *packet, int32_t length);
-CAPI void         ICMPv4_DumpHeader(const char *prefix, IPv4_Header_t *ipv4Header);
+uint16_t	ICMPv4_ComputeCRC(ICMPv4_Header_t *packet, int32_t length);
+Bool_t		ICMPv4_CheckCRC(ICMPv4_Header_t *packet, int32_t length);
+void		ICMPv4_DumpHeader(const char *prefix, IPv4_Header_t *ipv4Header);
 
 #endif /* __ICMPV4_H__ */
--- a/IPv4.c	Sun Jun 12 11:23:03 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,179 +0,0 @@
-/*
- * $Id: IPv4.c 29 2011-06-11 14:53:08Z benoit $
- * $Author: benoit $
- * $Date: 2011-06-11 16:53:08 +0200 (sam., 11 juin 2011) $
- * $Rev: 29 $
- * 
- * 
- * 
- * 
- * 
- */
- 
-#include "IPv4.h"
-#include "Ethernet.h"
-#include "Debug.h"
-#include <string.h>
-
-
-#define    DEBUG_CURRENT_MODULE_NAME    "IPv4"
-#define    DEBUG_CURRENT_MODULE_ID        DEBUG_MODULE_IPV4
-
-
-static void        Init(void);
-static int32_t    RegisterProtocol(Protocol_Handler_t *protocolHandler);
-static void        Handler(NetIF_t *netIF, Packet_t *packet);
-
-
-static Protocol_Handler_t    *protocolHandlerTable[IPV4_PROTOCOL_MAX_COUNT];
-static int32_t                protocolHandlerCount = 0;
-
-
-const IPv4_Addr_t         ipv4_Addr_Broadcast        = { 255, 255, 255, 255 };
-const IPv4_Addr_t         ipv4_Addr_Any            = { 0, 0, 0, 0};
-
-
-Protocol_Handler_t             ipv4 = 
-{ 
-    PROTOCOL_INDEX_NOT_INITIALIZED,        /* Always PROTOCOL_INDEX_NOT_INITIALIZED at initialization */
-    Protocol_ID_IPv4,                     /* Protocol ID */
-    htons(ETHERNET_PROTO_IPV4),         /* Protocol number */
-    Init,                                 /* Protocol initialisation function */
-    Handler,                             /* Protocol handler */
-    RegisterProtocol,                     /* Protocol registration function */
-    NULL,                                /* API registration function */
-};
-
-
-static void Init(void)
-{
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing IPv4 layer"));
-    protocolHandlerCount = 0;
-    memset(protocolHandlerTable, 0, sizeof(protocolHandlerTable));
-}
-
-
-static int32_t RegisterProtocol(Protocol_Handler_t *protocolHandler)
-{
-    int32_t        result = 0;
-
-    if (protocolHandlerCount >= IPV4_PROTOCOL_MAX_COUNT)
-    {
-        DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Too many protocols"));
-        result = -1;
-        mbedNet_LastError = mbedNetResult_TooManyRegisteredProtocols;
-        goto Exit;
-    }
-    
-    protocolHandlerTable[protocolHandlerCount] = protocolHandler;
-    protocolHandler->index = protocolHandlerCount;
-    protocolHandler->Init();
-    
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Registered protocol %2d ipv4/%s",
-        protocolHandler->protocolNumber,
-        protocol_IDNames[protocolHandler->protocolID]
-    ));
-    
-    protocolHandlerCount++;
-    
-Exit:
-    return result;
-}
-
-
-static void Handler(NetIF_t *netIF, Packet_t *packet)
-{
-    int32_t                protocolIndex,
-                        payloadOffset;
-    Protocol_Number_t    protocolNumber;
-    Protocol_Handler_t    *protocolHandler;
-    IPv4_Header_t        *ipv4Packet = (IPv4_Header_t *)packet->data;
-
-    protocolNumber = ipv4Packet->protocol;
-    payloadOffset = ipv4Packet->ihl << 2;
-    
-    if ((ipv4Packet->dest.addr != netIF->ipv4Address.addr) && (ipv4Packet->dest.addr != netIF->ipv4Broadcast.addr))
-    {
-        #if DEBUG_IPV4
-        IPV4_DumpIPv4Header("Not for us ", ipv4Packet);
-        #endif /* DEBUG_IPV4 */
-        goto Exit;
-    }
-    
-    #if DEBUG_IPV4
-    IPv4_DumpIPv4Header("processing ", ipv4Packet);
-    #endif /* DEBUG_IPV4 */
-    
-    //Debug_DumpBufferHex(packet, length);
-    for (protocolIndex = 0; protocolIndex < protocolHandlerCount; protocolIndex++)
-    {
-        protocolHandler = protocolHandlerTable[protocolIndex];
-        if (protocolHandler->protocolNumber == protocolNumber)
-        {
-            NetIF_ProtoPush(packet, payloadOffset, Protocol_ID_IPv4);
-            protocolHandler->HandlePacket(netIF, packet);
-            goto Exit;
-        }
-    }
-    
-    #if DEBUG_IPV4
-    IPV4_DumpIPv4Header("Not handled ", ipv4Packet);
-    #endif /* DEBUG_IPV4 */
-    
-    
-Exit:
-    return;
-}
-
-
-void IPv4_DumpIPv4Header(const char *prefix, IPv4_Header_t *ipv4Packet)
-{
-    DEBUG_RAW(("%sIPv4 %d.%d.%d.%d --> %d.%d.%d.%d  ver:%01X ihl:%01X tos:%03d totlen:%04d id:%04X flags:%1d frag:%05d ttl:%3d  proto:%03d crc:%04X" ,
-        prefix != NULL ? prefix : "",
-        ipv4Packet->source.IP0,
-        ipv4Packet->source.IP1,
-        ipv4Packet->source.IP2,
-        ipv4Packet->source.IP3,
-        ipv4Packet->dest.IP0,
-        ipv4Packet->dest.IP1,
-        ipv4Packet->dest.IP2,
-        ipv4Packet->dest.IP3,
-        ipv4Packet->version,
-        ipv4Packet->ihl,
-        ipv4Packet->tos,
-        ntohs(ipv4Packet->totalLength),
-        ntohs(ipv4Packet->id),
-        (ntohs(ipv4Packet->fragmentFlags) & 0x1FFF) >> 13,
-        ntohs(ipv4Packet->fragmentFlags),
-        ipv4Packet->ttl,
-        ipv4Packet->protocol,
-        ntohs(ipv4Packet->crc)
-    ));
-}
-
-
-uint16_t    IPv4_ComputeCRC(IPv4_Header_t *ipv4Header)
-{
-    uint32_t    crc = 0, 
-                length;
-    uint16_t    *data;
-    
-    data = (uint16_t *)ipv4Header;
-    length = ipv4Header->ihl * 4;
-    
-    while(length > 1)
-    {
-        crc += *data;
-        data++;
-        length -= 2;
-    }
-    if (length)
-    {
-        crc += *(uint8_t *)(data);
-    }
-    
-    crc = (crc >> 16) + (crc & 0xFFFF);
-    crc = crc + (crc >> 16);
-    
-    return (uint16_t)(~crc);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IPv4.cpp	Sun Jun 12 19:17:11 2011 +0000
@@ -0,0 +1,166 @@
+/*
+ * $Id: IPv4.c 29 2011-06-11 14:53:08Z benoit $
+ * $Author: benoit $
+ * $Date: 2011-06-11 16:53:08 +0200 (sam., 11 juin 2011) $
+ * $Rev: 29 $
+ * 
+ * 
+ * 
+ * 
+ * 
+ */
+ 
+#include "IPv4.h"
+#include "Ethernet.h"
+#include "Debug.h"
+#include <string.h>
+
+
+#define    DEBUG_CURRENT_MODULE_NAME    "IPv4"
+#define    DEBUG_CURRENT_MODULE_ID        DEBUG_MODULE_IPV4
+
+
+static void 	Init(void);
+static int32_t  RegisterProtocol(Protocol_Handler_t *protocolHandler);
+static void     Handler(NetIF_t *netIF, Packet_t *packet);
+
+
+static Protocol_Handler_t    *protocolHandlerTable[IPV4_PROTOCOL_MAX_COUNT];
+static int32_t                protocolHandlerCount = 0;
+
+
+const IPv4_Addr_t         ipv4_Addr_Broadcast        = { 255, 255, 255, 255 };
+const IPv4_Addr_t         ipv4_Addr_Any            = { 0, 0, 0, 0};
+
+
+Protocol_Handler_t             ipv4 = 
+{ 
+    PROTOCOL_INDEX_NOT_INITIALIZED,        /* Always PROTOCOL_INDEX_NOT_INITIALIZED at initialization */
+    Protocol_ID_IPv4,                     /* Protocol ID */
+    htons(ETHERNET_PROTO_IPV4),         /* Protocol number */
+    Init,                                 /* Protocol initialisation function */
+    Handler,                             /* Protocol handler */
+    RegisterProtocol,                     /* Protocol registration function */
+    NULL,                                /* API registration function */
+};
+
+
+static void Init(void)
+{
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing IPv4 layer"));
+    protocolHandlerCount = 0;
+    memset(protocolHandlerTable, 0, sizeof(protocolHandlerTable));
+}
+
+
+static int32_t RegisterProtocol(Protocol_Handler_t *protocolHandler)
+{
+    int32_t        result = 0;
+
+    if (protocolHandlerCount >= IPV4_PROTOCOL_MAX_COUNT)
+    {
+        DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Too many protocols"));
+        result = -1;
+        mbedNet_LastError = mbedNetResult_TooManyRegisteredProtocols;
+        goto Exit;
+    }
+    
+    protocolHandlerTable[protocolHandlerCount] = protocolHandler;
+    protocolHandler->index = protocolHandlerCount;
+    protocolHandler->Init();
+    
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Registered protocol %2d ipv4/%s",
+        protocolHandler->protocolNumber,
+        protocol_IDNames[protocolHandler->protocolID]
+    ));
+    
+    protocolHandlerCount++;
+    
+Exit:
+    return result;
+}
+
+
+static void Handler(NetIF_t *netIF, Packet_t *packet)
+{
+    int32_t   			protocolIndex,
+    	        		payloadOffset;
+    Protocol_Number_t	protocolNumber;
+	Protocol_Handler_t	*protocolHandler;
+    IPv4_Header_t		*ipv4Packet;
+	
+	
+	ipv4Packet = (IPv4_Header_t *)packet->data;
+    protocolNumber = ipv4Packet->protocol;
+    payloadOffset = ipv4Packet->ihl << 2;
+    
+    
+    if ((ipv4Packet->dest.addr == netIF->ipv4Address.addr) || (ipv4Packet->dest.addr == netIF->ipv4Broadcast.addr))
+    {
+	    for (protocolIndex = 0; protocolIndex < protocolHandlerCount; protocolIndex++)
+	    {
+	        protocolHandler = protocolHandlerTable[protocolIndex];
+	        if (protocolHandler->protocolNumber == protocolNumber)
+	        {
+				NetIF_ProtoPush(packet, payloadOffset, Protocol_ID_IPv4);
+	            protocolHandler->HandlePacket(netIF, packet);
+	            break;
+	        }
+	    }
+    }
+        
+    return;
+}
+
+
+void IPv4_DumpIPv4Header(const char *prefix, IPv4_Header_t *ipv4Packet)
+{
+    DEBUG_RAW(("%sIPv4 %d.%d.%d.%d --> %d.%d.%d.%d  ver:%01X ihl:%01X tos:%03d totlen:%04d id:%04X flags:%1d frag:%05d ttl:%3d  proto:%03d crc:%04X" ,
+        prefix != NULL ? prefix : "",
+        ipv4Packet->source.IP0,
+        ipv4Packet->source.IP1,
+        ipv4Packet->source.IP2,
+        ipv4Packet->source.IP3,
+        ipv4Packet->dest.IP0,
+        ipv4Packet->dest.IP1,
+        ipv4Packet->dest.IP2,
+        ipv4Packet->dest.IP3,
+        ipv4Packet->version,
+        ipv4Packet->ihl,
+        ipv4Packet->tos,
+        ntohs(ipv4Packet->totalLength),
+        ntohs(ipv4Packet->id),
+        (ntohs(ipv4Packet->fragmentFlags) & 0x1FFF) >> 13,
+        ntohs(ipv4Packet->fragmentFlags),
+        ipv4Packet->ttl,
+        ipv4Packet->protocol,
+        ntohs(ipv4Packet->crc)
+    ));
+}
+
+
+uint16_t IPv4_ComputeCRC(IPv4_Header_t *ipv4Header)
+{
+    uint32_t    crc = 0, 
+                length;
+    uint16_t    *data;
+    
+    data = (uint16_t *)ipv4Header;
+    length = ipv4Header->ihl * 4;
+    
+    while(length > 1)
+    {
+        crc += *data;
+        data++;
+        length -= 2;
+    }
+    if (length)
+    {
+        crc += *(uint8_t *)(data);
+    }
+    
+    crc = (crc >> 16) + (crc & 0xFFFF);
+    crc = crc + (crc >> 16);
+    
+    return (uint16_t)(~crc);
+}
--- a/IPv4.h	Sun Jun 12 11:23:03 2011 +0000
+++ b/IPv4.h	Sun Jun 12 19:17:11 2011 +0000
@@ -51,8 +51,8 @@
 extern Protocol_Handler_t ipv4;
 
 
-CAPI void        IPv4_DumpIPv4Header(const char *prefix, IPv4_Header_t *ipv4Packet);
-CAPI uint16_t    IPv4_ComputeCRC(IPv4_Header_t *ipv4Header);
+void        IPv4_DumpIPv4Header(const char *prefix, IPv4_Header_t *ipv4Packet);
+uint16_t    IPv4_ComputeCRC(IPv4_Header_t *ipv4Header);
 
 
 #endif /* __IPV4_H__ */
--- a/NetIF.c	Sun Jun 12 11:23:03 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,428 +0,0 @@
-/*
- * $Id: NetIF.c 29 2011-06-11 14:53:08Z benoit $
- * $Author: benoit $
- * $Date: 2011-06-11 16:53:08 +0200 (sam., 11 juin 2011) $
- * $Rev: 29 $
- * 
- * 
- * 
- * 
- * 
- */
- 
-#include "NetIF.h"
-#include "Ethernet.h"
-#include "ARP.h"
-#include "Debug.h"
-#include <string.h>
-
-
-#define    DEBUG_CURRENT_MODULE_NAME    "NetIF"
-#define    DEBUG_CURRENT_MODULE_ID        DEBUG_MODULE_NETIF
-
-
-struct PeriodicFunctionTimer
-{
-    char                *name;
-    PeriodicFunction_t    function;
-    FunctionPeriod_t    period;
-    int32_t                age;
-};
-typedef struct PeriodicFunctionTimer PeriodicFunctionTimer_t;
-
-
-static NetIF_t                    netIF_Table[NETIF_MAX_COUNT];
-static int32_t                    netIF_Count = 0;
-static RTOS_Mutex_t                netIF_TableMutex;
-
-static PeriodicFunctionTimer_t    netIF_PeriodicFunctionTable[NET_PERIODIC_FUNCTION_MAX_COUNT];
-static int32_t                    netIF_PeriodicFunctionCount = 0;
-static RTOS_Mutex_t                netIF_PeriodicFunctionTableMutex;
-
-static Bool_t                    netIFLayerInitialized = False;
-static Packet_t                    rxPacket,
-                                txPacket;
-static int32_t                    gatewayNetIFIndex = -1;
-
-
-static void  NetIF_Init(void);
-
-
-mbedNetResult_t                    mbedNet_LastError;
-const char                         *protocol_IDNames[Protocol_ID_Count] = 
-{
-    "Ethernet",
-    "ARP",
-    "IPv4",
-    "ICMPv4",
-    "UDPv4",
-    "TCPv4",
-};
-
-
-const char                        *api_IDNames[API_ID_Count] = 
-{
-    "sockets"
-};
-
-
-static void NetIF_Init(void)
-{
-    mbedNet_LastError = mbedNetResult_Success;
-    
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing NetIF layer"));
-    
-    netIF_Count = 0;
-    memset(netIF_Table, 0, sizeof(netIF_Table));
-    netIF_TableMutex = RTOS_MUTEX_CREATE();
-    
-    netIF_PeriodicFunctionCount = 0;
-    memset(netIF_PeriodicFunctionTable, 0, sizeof(netIF_PeriodicFunctionTable));
-    netIF_PeriodicFunctionTableMutex = RTOS_MUTEX_CREATE();
-    
-    memset(&rxPacket, 0, sizeof(rxPacket));
-    memset(&txPacket, 0, sizeof(txPacket));
-    
-    gatewayNetIFIndex = -1;
-    
-    netIFLayerInitialized = True;
-}
-
-
-NetIF_t *NetIF_RegisterInterface(IPv4_Addr_t *address, IPv4_Addr_t *netmask, IPv4_Addr_t *gateway, NetIF_Driver_t *driver , void *driverParameter)
-{
-    NetIF_t            *netIF = NULL;
-
-    if (netIFLayerInitialized == False)
-    {
-        NetIF_Init();
-    }
-
-    if (netIF_Count >= NETIF_MAX_COUNT)
-    {
-        DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Too many interfaces registered"));
-        mbedNet_LastError = mbedNetResult_TooManyInterfaces;
-        goto Exit;
-    }
-
-    if (driver == NULL)
-    {
-        DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Invalid driver specified"));
-        mbedNet_LastError = mbedNetResult_InvalidDriver;
-        goto Exit;
-    }
-
-    RTOS_MUTEX_LOCK(netIF_TableMutex);
-    netIF = netIF_Table + netIF_Count;
-    netIF->index = netIF_Count;
-    netIF->name = "en";
-    netIF->ipv4Address = *address;
-    netIF->ipv4Netmask = *netmask;
-    netIF->ipv4Network.addr = address->addr & netmask->addr;
-    netIF->ipv4Gateway = *gateway;
-    netIF->ipv4Broadcast.addr = (address->addr & netmask->addr) | (~netmask->addr);
-    netIF->driverParameter = driverParameter;
-    netIF->driver = driver;
-    netIF->driver->Init(netIF);
-    netIF->driver->protocolHandler->Init();
-    
-    if (gateway != NULL)
-    {
-        gatewayNetIFIndex = netIF_Count;
-    }
-    
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Interface '%s%d' registered (%d.%d.%d.%d/%d.%d.%d.%d gw %d.%d.%d.%d) using driver '%s'",
-        netIF->name,
-        netIF_Count,
-        netIF->ipv4Address.IP0, netIF->ipv4Address.IP1, netIF->ipv4Address.IP2, netIF->ipv4Address.IP3,
-        netIF->ipv4Netmask.IP0, netIF->ipv4Netmask.IP1, netIF->ipv4Netmask.IP2, netIF->ipv4Netmask.IP3,
-        netIF->ipv4Gateway.IP0, netIF->ipv4Gateway.IP1, netIF->ipv4Gateway.IP2, netIF->ipv4Gateway.IP3,
-        netIF->driver->name
-    ));
-    
-    netIF_Count++;
-    RTOS_MUTEX_UNLOCK(netIF_TableMutex);
-    
-Exit:
-    return netIF;
-}
-
-
-int32_t NetIF_ProcessFrames(void)
-{
-    NetIF_Index_t        netIFIndex;
-    NetIF_t                *netIF;
-    int32_t                result = 0, 
-                        readResult;
-
-    DEBUG_SOURCE(DEBUG_LEVEL_VERBOSE2, ("enter"));
-    RTOS_MUTEX_LOCK(netIF_TableMutex);
-    for (netIFIndex = 0; netIFIndex < netIF_Count; netIFIndex++)
-    {
-        netIF = netIF_Table + netIFIndex;
-        readResult = netIF->driver->Read(&rxPacket.data, &rxPacket.length);
-        if (readResult == 0)
-        {
-            rxPacket.depth = -1;
-            netIF->driver->protocolHandler->HandlePacket(netIF, &rxPacket);
-        }
-    }
-    RTOS_MUTEX_UNLOCK(netIF_TableMutex);
-    
-    DEBUG_SOURCE(DEBUG_LEVEL_VERBOSE2, ("leave"));
-    return result;
-}
-
-
-int32_t NetIF_RegisterPeriodicFunction(char *name, PeriodicFunction_t function, FunctionPeriod_t period)
-{
-    int32_t                        result = 0;
-    PeriodicFunctionTimer_t        *timerEntry;
-
-    if (netIF_PeriodicFunctionCount >= NET_PERIODIC_FUNCTION_MAX_COUNT)
-    {
-        DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Too many periodic functions registered"));
-        mbedNet_LastError = mbedNetResult_TooManyPeriodicFunctions;
-        goto Exit;
-    }
-    
-    RTOS_MUTEX_LOCK(netIF_PeriodicFunctionTableMutex);
-    timerEntry = netIF_PeriodicFunctionTable + netIF_PeriodicFunctionCount;
-    timerEntry->name = name;
-    timerEntry->function = function;
-    timerEntry->period = period;
-    timerEntry->age = 0;
-    
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Registered periodic function '%s' with period %d seconds",
-        name, 
-        period
-    ));
-    
-    netIF_PeriodicFunctionCount++;
-    RTOS_MUTEX_UNLOCK(netIF_PeriodicFunctionTableMutex);
-
-Exit:
-    return result;    
-}
-
-
-int32_t NetIF_ProcessTimers(int32_t elapsedTime)
-{
-    int32_t                        result = 0,
-                                timerIndex;
-    PeriodicFunctionTimer_t        *timerEntry;
-    static int64_t                seconds = 0;
-    
-    seconds++;
-    
-    RTOS_MUTEX_LOCK(netIF_PeriodicFunctionTableMutex);
-    for (timerIndex = 0; timerIndex < netIF_PeriodicFunctionCount; timerIndex++)
-    {
-        timerEntry = netIF_PeriodicFunctionTable + timerIndex;
-        if (elapsedTime == 0)
-        {
-            timerEntry->age = 0;
-            continue;
-        }
-        
-        timerEntry->age += elapsedTime;
-        if (timerEntry->age >= timerEntry->period)
-        {
-            timerEntry->age = 0;
-            timerEntry->function();
-        }
-    }
-    RTOS_MUTEX_UNLOCK(netIF_PeriodicFunctionTableMutex);
-    
-    return result;        
-}
-
-
-int32_t    NetIF_SendIPv4Packet(IPv4_Header_t *ipv4Header)
-{
-    int32_t                result = -1, 
-                        mtu,
-                        lengthToSend;
-    NetIF_Index_t        netIFIndex;
-    NetIF_t                *netIF = NULL;
-    Ethernet_Header_t    *ethernetHeader;
-    Bool_t                useGateway = False;
-
-    RTOS_MUTEX_LOCK(netIF_TableMutex);
-    
-    /* Look for netif having same network */
-    for (netIFIndex = 0; netIFIndex < netIF_Count; netIFIndex++)
-    {
-        netIF = netIF_Table + netIFIndex;
-        if ((netIF->ipv4Netmask.addr & ipv4Header->dest.addr) == netIF->ipv4Network.addr) break;
-        netIF = NULL;
-    }
-    
-    /* if not found, use gateway netif */
-    if ((netIF == NULL) && (gatewayNetIFIndex >= 0))
-    {
-        netIF = netIF_Table + gatewayNetIFIndex;
-        DEBUG_MODULE(DEBUG_LEVEL_INFO, ("using gateway %d.%d.%d.%d to talk to %d.%d.%d.%d",
-            netIF->ipv4Gateway.IP0,    
-            netIF->ipv4Gateway.IP1,    
-            netIF->ipv4Gateway.IP2,    
-            netIF->ipv4Gateway.IP3,    
-
-            ipv4Header->dest.IP0,
-            ipv4Header->dest.IP1,
-            ipv4Header->dest.IP2,
-            ipv4Header->dest.IP3
-        ));
-        useGateway = True;
-    }
-    
-    /* Still no interface able to send, then return error */
-    if (netIF == NULL)
-    {
-        DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("No route to host"));
-        mbedNet_LastError = mbedNetResult_NoRouteToHost;
-        goto Exit;
-    }
-    
-    /* Prepare to send the IPv4 packet */
-    mtu = netIF->driver->mtu;
-    
-    lengthToSend = (sizeof(Ethernet_Header_t) + ntohs(ipv4Header->totalLength));
-    /* Check that total length doesn't exceed MTU */
-    if (lengthToSend > mtu)
-    {
-        DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Too much data: %d bytes", lengthToSend));
-        mbedNet_LastError = mbedNetResult_TooMuchData;
-        goto Exit;
-    }
-    
-    /* Set source address and compute checksum of IPv4 header */
-    ipv4Header->source.addr = netIF->ipv4Address.addr;
-    ipv4Header->crc = 0;
-    ipv4Header->crc = IPv4_ComputeCRC(ipv4Header);
-    
-    /* Prepare packet with ethernet data */
-    txPacket.depth = -1;
-    txPacket.length = lengthToSend;
-    txPacket.data = netIF->driver->GetTxBuffer();
-    ethernetHeader = (Ethernet_Header_t *)txPacket.data;
-    
-    /* Copy destination MAC address */
-    if (useGateway)
-    {
-        while (ARP_ResolveIPv4Address(netIF, netIF->ipv4Gateway, &ethernetHeader->destination) == -1)
-        {
-            DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("%d.%d.%d.%d not in ARP cache",
-                netIF->ipv4Gateway.IP0,
-                netIF->ipv4Gateway.IP1,
-                netIF->ipv4Gateway.IP2,
-                netIF->ipv4Gateway.IP3
-            ));
-            NetIF_ProcessFrames();
-        }
-    }
-    else
-    {
-        while (ARP_ResolveIPv4Address(netIF, ipv4Header->dest, &ethernetHeader->destination))
-        {
-            DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("%d.%d.%d.%d not in ARP cache",
-                ipv4Header->dest.IP0,
-                ipv4Header->dest.IP1,
-                ipv4Header->dest.IP2,
-                ipv4Header->dest.IP3
-            ));
-            NetIF_ProcessFrames();
-        }
-    }
-    
-    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("IPv4 sending %d bytes %d.%d.%d.%d --> %d.%d.%d.%d using %s%d",
-        ntohs(ipv4Header->totalLength),
-        
-        ipv4Header->source.IP0,
-        ipv4Header->source.IP1,
-        ipv4Header->source.IP2,
-        ipv4Header->source.IP3,
-        
-        ipv4Header->dest.IP0,
-        ipv4Header->dest.IP1,
-        ipv4Header->dest.IP2,
-        ipv4Header->dest.IP3,
-        
-        netIF->name,
-        netIF->index
-
-    ));
-
-    /* Copy source MAC address */
-    memcpy(&ethernetHeader->source, (uint8_t *)netIF->driverParameter, 6);
-    ethernetHeader->protocol = htons(ETHERNET_PROTO_IPV4);
-    NetIF_ProtoPush(&txPacket, sizeof(Ethernet_Header_t), Protocol_ID_Ethernet);
-    
-    /* Copy ethernet payload */
-    //ipv4Header = (IPv4_Header_t *)txPacket.data;
-    memcpy(txPacket.data, ipv4Header, ntohs(ipv4Header->totalLength));
-    NetIF_ProtoPop(&txPacket);
-    
-    /* Send packet */
-    result = netIF->driver->Write(txPacket.data, txPacket.length);
-        
-Exit:
-    RTOS_MUTEX_UNLOCK(netIF_TableMutex);
-    return result;
-}
-
-
-void NetIF_ProtoPop(Packet_t *packet)
-{
-    int32_t    depth, headerSize, index;
-    
-    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length));
-    if (packet->depth >= 0)
-    {    
-        depth = packet->depth;
-        headerSize = packet->headerLenTable[depth];
-        
-        packet->data -= headerSize;
-        packet->length += headerSize;
-    
-        packet->depth--;
-    }
-    
-    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("  > Decapsulate: "));
-    DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE1)
-    {
-        for (index = 0; index <= packet->depth; index++)
-        {
-            DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("  > %d %s header:%d bytes", index, protocol_IDNames[packet->protocolTable[index]], packet->headerLenTable[index]));
-        }
-    }
-    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length));
-}
-
-
-void NetIF_ProtoPush(Packet_t *packet, int32_t headerSize, Protocol_ID_t protocol)
-{
-    int32_t    depth, index;
-    
-    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length));
-    
-    packet->depth++;
-    depth = packet->depth;
-    
-    packet->headerPtrTable[depth] = packet->data;
-    packet->headerLenTable[depth] = headerSize;
-    packet->protocolTable[depth] = protocol;
-    packet->data += headerSize;
-    packet->length -= headerSize;
-    
-    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("  > Encapsulate: "));
-    DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE1)
-    {
-        for (index = 0; index <= depth; index++)
-        {
-            DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("  > %d %s header:%d bytes", index, protocol_IDNames[packet->protocolTable[index]], packet->headerLenTable[index]));
-        }
-    }
-    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length));
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NetIF.cpp	Sun Jun 12 19:17:11 2011 +0000
@@ -0,0 +1,466 @@
+/*
+ * $Id: NetIF.c 29 2011-06-11 14:53:08Z benoit $
+ * $Author: benoit $
+ * $Date: 2011-06-11 16:53:08 +0200 (sam., 11 juin 2011) $
+ * $Rev: 29 $
+ * 
+ * 
+ * 
+ * 
+ * 
+ */
+ 
+#include "NetIF.h"
+#include "Ethernet.h"
+#include "ARP.h"
+#include "Debug.h"
+#include <string.h>
+
+
+#define    DEBUG_CURRENT_MODULE_NAME    "NetIF"
+#define    DEBUG_CURRENT_MODULE_ID        DEBUG_MODULE_NETIF
+
+
+struct PeriodicFunctionTimer
+{
+    char                *name;
+    PeriodicFunction_t    function;
+    FunctionPeriod_t    period;
+    int32_t                age;
+};
+typedef struct PeriodicFunctionTimer PeriodicFunctionTimer_t;
+
+
+static NetIF_t                    netIF_Table[NETIF_MAX_COUNT];
+static int32_t                    netIF_Count = 0;
+static RTOS_Mutex_t                netIF_TableMutex;
+
+static PeriodicFunctionTimer_t    netIF_PeriodicFunctionTable[NET_PERIODIC_FUNCTION_MAX_COUNT];
+static int32_t                    netIF_PeriodicFunctionCount = 0;
+static RTOS_Mutex_t                netIF_PeriodicFunctionTableMutex;
+
+static Bool_t                    netIFLayerInitialized = False;
+static Packet_t                    rxPacket,
+                                txPacket;
+static int32_t                    gatewayNetIFIndex = -1;
+
+
+static void  NetIF_Init(void);
+
+
+mbedNetResult_t                    mbedNet_LastError;
+const char                         *protocol_IDNames[Protocol_ID_Count] = 
+{
+    "Ethernet",
+    "ARP",
+    "IPv4",
+    "ICMPv4",
+    "UDPv4",
+    "TCPv4",
+};
+
+
+const char                        *api_IDNames[API_ID_Count] = 
+{
+    "sockets"
+};
+
+
+static void NetIF_Init(void)
+{
+    mbedNet_LastError = mbedNetResult_Success;
+    
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing NetIF layer"));
+    
+    netIF_Count = 0;
+    memset(netIF_Table, 0, sizeof(netIF_Table));
+    netIF_TableMutex = RTOS_MUTEX_CREATE();
+    
+    netIF_PeriodicFunctionCount = 0;
+    memset(netIF_PeriodicFunctionTable, 0, sizeof(netIF_PeriodicFunctionTable));
+    netIF_PeriodicFunctionTableMutex = RTOS_MUTEX_CREATE();
+    
+    memset(&rxPacket, 0, sizeof(rxPacket));
+    memset(&txPacket, 0, sizeof(txPacket));
+    
+    gatewayNetIFIndex = -1;
+    
+    netIFLayerInitialized = True;
+}
+
+
+NetIF_t *NetIF_RegisterInterface(IPv4_Addr_t *address, IPv4_Addr_t *netmask, IPv4_Addr_t *gateway, NetIF_Driver_t *driver , void *driverParameter)
+{
+    NetIF_t            *netIF = NULL;
+
+    if (netIFLayerInitialized == False)
+    {
+        NetIF_Init();
+    }
+
+    if (netIF_Count >= NETIF_MAX_COUNT)
+    {
+        DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Too many interfaces registered"));
+        mbedNet_LastError = mbedNetResult_TooManyInterfaces;
+        goto Exit;
+    }
+
+    if (driver == NULL)
+    {
+        DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Invalid driver specified"));
+        mbedNet_LastError = mbedNetResult_InvalidDriver;
+        goto Exit;
+    }
+
+    RTOS_MUTEX_LOCK(netIF_TableMutex);
+    netIF = netIF_Table + netIF_Count;
+    netIF->index = netIF_Count;
+    netIF->name = "en";
+    netIF->ipv4Address = *address;
+    netIF->ipv4Netmask = *netmask;
+    netIF->ipv4Network.addr = address->addr & netmask->addr;
+    netIF->ipv4Gateway = *gateway;
+    netIF->ipv4Broadcast.addr = (address->addr & netmask->addr) | (~netmask->addr);
+    netIF->driverParameter = driverParameter;
+    netIF->driver = driver;
+    netIF->driver->Init(netIF);
+    netIF->driver->protocolHandler->Init();
+    
+    if (gateway != NULL)
+    {
+        gatewayNetIFIndex = netIF_Count;
+    }
+    
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Interface '%s%d' registered (%d.%d.%d.%d/%d.%d.%d.%d gw %d.%d.%d.%d) using driver '%s'",
+        netIF->name,
+        netIF_Count,
+        netIF->ipv4Address.IP0, netIF->ipv4Address.IP1, netIF->ipv4Address.IP2, netIF->ipv4Address.IP3,
+        netIF->ipv4Netmask.IP0, netIF->ipv4Netmask.IP1, netIF->ipv4Netmask.IP2, netIF->ipv4Netmask.IP3,
+        netIF->ipv4Gateway.IP0, netIF->ipv4Gateway.IP1, netIF->ipv4Gateway.IP2, netIF->ipv4Gateway.IP3,
+        netIF->driver->name
+    ));
+    
+    netIF_Count++;
+    RTOS_MUTEX_UNLOCK(netIF_TableMutex);
+    
+Exit:
+    return netIF;
+}
+
+
+int32_t NetIF_ProcessFrames(void)
+{
+    NetIF_Index_t        netIFIndex;
+    NetIF_t                *netIF;
+    int32_t                result = 0, 
+                        readResult;
+
+    DEBUG_SOURCE(DEBUG_LEVEL_VERBOSE2, ("enter"));
+    RTOS_MUTEX_LOCK(netIF_TableMutex);
+    for (netIFIndex = 0; netIFIndex < netIF_Count; netIFIndex++)
+    {
+        netIF = netIF_Table + netIFIndex;
+        readResult = netIF->driver->Read(&rxPacket.data, &rxPacket.length);
+        if (readResult == 0)
+        {
+            rxPacket.depth = -1;
+            netIF->driver->protocolHandler->HandlePacket(netIF, &rxPacket);
+        }
+    }
+    RTOS_MUTEX_UNLOCK(netIF_TableMutex);
+    
+    DEBUG_SOURCE(DEBUG_LEVEL_VERBOSE2, ("leave"));
+    return result;
+}
+
+
+int32_t NetIF_RegisterPeriodicFunction(char *name, PeriodicFunction_t function, FunctionPeriod_t period)
+{
+    int32_t                        result = 0;
+    PeriodicFunctionTimer_t        *timerEntry;
+
+    if (netIF_PeriodicFunctionCount >= NET_PERIODIC_FUNCTION_MAX_COUNT)
+    {
+        DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Too many periodic functions registered"));
+        mbedNet_LastError = mbedNetResult_TooManyPeriodicFunctions;
+        goto Exit;
+    }
+    
+    RTOS_MUTEX_LOCK(netIF_PeriodicFunctionTableMutex);
+    timerEntry = netIF_PeriodicFunctionTable + netIF_PeriodicFunctionCount;
+    timerEntry->name = name;
+    timerEntry->function = function;
+    timerEntry->period = period;
+    timerEntry->age = 0;
+    
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Registered periodic function '%s' with period %d seconds",
+        name, 
+        period
+    ));
+    
+    netIF_PeriodicFunctionCount++;
+    RTOS_MUTEX_UNLOCK(netIF_PeriodicFunctionTableMutex);
+
+Exit:
+    return result;    
+}
+
+
+int32_t NetIF_ProcessTimers(int32_t elapsedTime)
+{
+    int32_t                        result = 0,
+                                timerIndex;
+    PeriodicFunctionTimer_t        *timerEntry;
+    static int64_t                seconds = 0;
+    
+    seconds++;
+    
+    RTOS_MUTEX_LOCK(netIF_PeriodicFunctionTableMutex);
+    for (timerIndex = 0; timerIndex < netIF_PeriodicFunctionCount; timerIndex++)
+    {
+        timerEntry = netIF_PeriodicFunctionTable + timerIndex;
+        if (elapsedTime == 0)
+        {
+            timerEntry->age = 0;
+            continue;
+        }
+        
+        timerEntry->age += elapsedTime;
+        if (timerEntry->age >= timerEntry->period)
+        {
+            timerEntry->age = 0;
+            timerEntry->function();
+        }
+    }
+    RTOS_MUTEX_UNLOCK(netIF_PeriodicFunctionTableMutex);
+    
+    return result;        
+}
+
+
+int32_t    NetIF_SendIPv4Packet(IPv4_Header_t *ipv4Header)
+{
+    int32_t                result = -1, 
+                        mtu,
+                        lengthToSend;
+    NetIF_Index_t        netIFIndex;
+    NetIF_t                *netIF = NULL;
+    Ethernet_Header_t    *ethernetHeader;
+    Bool_t                useGateway = False;
+
+    RTOS_MUTEX_LOCK(netIF_TableMutex);
+    
+	/* Look for netif having same network */
+    for (netIFIndex = 0; netIFIndex < netIF_Count; netIFIndex++)
+    {
+        netIF = netIF_Table + netIFIndex;
+        if ( (netIF->up) && ((netIF->ipv4Netmask.addr & ipv4Header->dest.addr) == netIF->ipv4Network.addr)) break;
+        netIF = NULL;
+    }
+    
+    /* if not found, use gateway netif */
+    if ((netIF == NULL) && (gatewayNetIFIndex >= 0))
+    {
+        netIF = netIF_Table + gatewayNetIFIndex;
+        DEBUG_MODULE(DEBUG_LEVEL_INFO, ("using gateway %d.%d.%d.%d to talk to %d.%d.%d.%d",
+            netIF->ipv4Gateway.IP0,    
+            netIF->ipv4Gateway.IP1,    
+            netIF->ipv4Gateway.IP2,    
+            netIF->ipv4Gateway.IP3,    
+
+            ipv4Header->dest.IP0,
+            ipv4Header->dest.IP1,
+            ipv4Header->dest.IP2,
+            ipv4Header->dest.IP3
+        ));
+        useGateway = True;
+    }
+    
+    /* Still no interface able to send, then return error */
+    if (netIF == NULL)
+    {
+        DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("No route to host"));
+        mbedNet_LastError = mbedNetResult_NoRouteToHost;
+        goto Exit;
+    }
+    
+    /* Prepare to send the IPv4 packet */
+    mtu = netIF->driver->mtu;
+    
+    lengthToSend = (sizeof(Ethernet_Header_t) + ntohs(ipv4Header->totalLength));
+    /* Check that total length doesn't exceed MTU */
+    if (lengthToSend > mtu)
+    {
+        DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Too much data: %d bytes", lengthToSend));
+        mbedNet_LastError = mbedNetResult_TooMuchData;
+        goto Exit;
+    }
+    
+    /* Set source address and compute checksum of IPv4 header */
+    ipv4Header->source.addr = netIF->ipv4Address.addr;
+    ipv4Header->crc = 0;
+    ipv4Header->crc = IPv4_ComputeCRC(ipv4Header);
+    
+    /* Prepare packet with ethernet data */
+    txPacket.depth = -1;
+    txPacket.length = lengthToSend;
+    txPacket.data = netIF->driver->GetTxBuffer();
+    ethernetHeader = (Ethernet_Header_t *)txPacket.data;
+    
+    /* Copy destination MAC address */
+    if (useGateway)
+    {
+        while (ARP_ResolveIPv4Address(netIF, netIF->ipv4Gateway, &ethernetHeader->destination) == -1)
+        {
+            DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("%d.%d.%d.%d not in ARP cache",
+                netIF->ipv4Gateway.IP0,
+                netIF->ipv4Gateway.IP1,
+                netIF->ipv4Gateway.IP2,
+                netIF->ipv4Gateway.IP3
+            ));
+            NetIF_ProcessFrames();
+        }
+    }
+    else
+    {
+        while (ARP_ResolveIPv4Address(netIF, ipv4Header->dest, &ethernetHeader->destination))
+        {
+            DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("%d.%d.%d.%d not in ARP cache",
+                ipv4Header->dest.IP0,
+                ipv4Header->dest.IP1,
+                ipv4Header->dest.IP2,
+                ipv4Header->dest.IP3
+            ));
+            NetIF_ProcessFrames();
+        }
+    }
+    
+    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("IPv4 sending %d bytes %d.%d.%d.%d --> %d.%d.%d.%d using %s%d",
+        ntohs(ipv4Header->totalLength),
+        
+        ipv4Header->source.IP0,
+        ipv4Header->source.IP1,
+        ipv4Header->source.IP2,
+        ipv4Header->source.IP3,
+        
+        ipv4Header->dest.IP0,
+        ipv4Header->dest.IP1,
+        ipv4Header->dest.IP2,
+        ipv4Header->dest.IP3,
+        
+        netIF->name,
+        netIF->index
+
+    ));
+
+    /* Copy source MAC address */
+    memcpy(&ethernetHeader->source, (uint8_t *)netIF->driverParameter, 6);
+    ethernetHeader->protocol = htons(ETHERNET_PROTO_IPV4);
+    NetIF_ProtoPush(&txPacket, sizeof(Ethernet_Header_t), Protocol_ID_Ethernet);
+    
+    /* Copy ethernet payload */
+    //ipv4Header = (IPv4_Header_t *)txPacket.data;
+    memcpy(txPacket.data, ipv4Header, ntohs(ipv4Header->totalLength));
+    NetIF_ProtoPop(&txPacket);
+    
+    /* Send packet */
+    result = netIF->driver->Write(txPacket.data, txPacket.length);
+        
+Exit:
+    RTOS_MUTEX_UNLOCK(netIF_TableMutex);
+    return result;
+}
+
+
+int32_t NetIF_Up(NetIF_t *netIF)
+{
+	int32_t	result = 0;
+
+	if (netIF->up)
+	{
+		result = -1;
+		mbedNet_LastError = mbedNetResult_InterfaceAlreadyUp;
+		goto Exit;
+	}
+	
+	netIF->driver->Enable();
+	netIF->up = True;
+	
+Exit:
+	return result;
+}
+
+
+int32_t NetIF_Down(NetIF_t *netIF)
+{
+	int32_t	result = 0;
+
+	if (!netIF->up)
+	{
+		result = -1;
+		mbedNet_LastError = mbedNetResult_InterfaceAlreadyDown;
+		goto Exit;
+	}
+	
+	netIF->driver->Disable();
+	netIF->up = False;
+	
+Exit:
+	return result;
+}
+
+
+void NetIF_ProtoPop(Packet_t *packet)
+{
+    static int32_t    depth, headerSize, index;
+    
+    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length));
+    if (packet->depth >= 0)
+    {    
+        depth = packet->depth;
+        headerSize = packet->headerLenTable[depth];
+        
+        packet->data -= headerSize;
+        packet->length += headerSize;
+    
+        packet->depth--;
+    }
+    
+    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("  > Decapsulate: "));
+    DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE1)
+    {
+        for (index = 0; index <= packet->depth; index++)
+        {
+            DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("  > %d %s header:%d bytes", index, protocol_IDNames[packet->protocolTable[index]], packet->headerLenTable[index]));
+        }
+    }
+    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length));
+}
+
+
+void NetIF_ProtoPush(Packet_t *packet, int32_t headerSize, Protocol_ID_t protocol)
+{
+    static int32_t    depth, index;
+    
+    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length));
+    
+    packet->depth++;
+    depth = packet->depth;
+    
+    packet->headerPtrTable[depth] = packet->data;
+    packet->headerLenTable[depth] = headerSize;
+    packet->protocolTable[depth] = protocol;
+    packet->data += headerSize;
+    packet->length -= headerSize;
+    
+    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("  > Encapsulate: "));
+    DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE1)
+    {
+        for (index = 0; index <= depth; index++)
+        {
+            DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("  > %d %s header:%d bytes", index, protocol_IDNames[packet->protocolTable[index]], packet->headerLenTable[index]));
+        }
+    }
+    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length));
+}
+
--- a/NetIF.h	Sun Jun 12 11:23:03 2011 +0000
+++ b/NetIF.h	Sun Jun 12 19:17:11 2011 +0000
@@ -20,10 +20,14 @@
 typedef struct IPv4_Header IPv4_Header_t;
 struct NetIF;
 typedef struct NetIF NetIF_t;
-typedef CAPI int32_t (*enet_drv_init_t)(NetIF_t *);
-typedef CAPI int32_t (*enet_drv_read_t)(uint8_t **, int32_t *);
-typedef CAPI int32_t (*enet_drv_write_t)(uint8_t *, int32_t);
-typedef CAPI uint8_t *(*enet_drv_get_tx_buffer_t)(void);
+struct Protocol_Handler;
+typedef struct Protocol_Handler Protocol_Handler_t;
+typedef int32_t (*enet_drv_init_t)(NetIF_t *);
+typedef int32_t (*enet_drv_read_t)(uint8_t **, int32_t *);
+typedef int32_t (*enet_drv_write_t)(uint8_t *, int32_t);
+typedef void (*enet_drv_enable_t)(void);
+typedef void (*enet_drv_disable_t)(void);
+typedef uint8_t *(*enet_drv_get_tx_buffer_t)(void);
 
 
 
@@ -69,13 +73,11 @@
 typedef struct Net_API Net_API_t;
 
 
-struct Protocol_Handler;
-typedef struct Protocol_Handler Protocol_Handler_t;
-typedef CAPI int32_t (*Protocol_RegisterFunction_t)(Protocol_Handler_t *);
-typedef CAPI void (*Protocol_HandlerFunction_t)(NetIF_t *, Packet_t *);
-typedef CAPI void (*Protocol_InitFunction_t)(void);
-typedef CAPI int32_t (*API_RegisterFunction_t)(Net_API_t *);
-typedef CAPI void (*PeriodicFunction_t)(void);
+typedef int32_t (*Protocol_RegisterFunction_t)(Protocol_Handler_t *);
+typedef void (*Protocol_HandlerFunction_t)(NetIF_t *, Packet_t *);
+typedef void (*Protocol_InitFunction_t)(void);
+typedef int32_t (*API_RegisterFunction_t)(Net_API_t *);
+typedef void (*PeriodicFunction_t)(void);
 typedef int16_t FunctionPeriod_t;
 
 
@@ -83,11 +85,13 @@
 struct NetIF_Driver
 {
     char                        *name;
-    enet_drv_init_t                Init;
-    enet_drv_read_t                Read;
+    enet_drv_init_t             Init;
+    enet_drv_read_t             Read;
     enet_drv_write_t            Write;
+	enet_drv_enable_t			Enable;
+	enet_drv_disable_t			Disable;
     enet_drv_get_tx_buffer_t    GetTxBuffer;
-    Protocol_Handler_t            *protocolHandler;
+    Protocol_Handler_t          *protocolHandler;
     uint16_t                    mtu;
 };
 typedef struct NetIF_Driver NetIF_Driver_t;
@@ -114,15 +118,16 @@
 typedef int32_t    NetIF_Index_t;
 struct NetIF
 {
-    NetIF_Index_t                index;
+    NetIF_Index_t                  index;
     const char                     *name;
     IPv4_Addr_t                    ipv4Address;
     IPv4_Addr_t                    ipv4Netmask;
     IPv4_Addr_t                    ipv4Network;
     IPv4_Addr_t                    ipv4Gateway;
     IPv4_Addr_t                    ipv4Broadcast;
-    NetIF_Driver_t                *driver;
-    void                        *driverParameter;
+    NetIF_Driver_t                 *driver;
+    void                           *driverParameter;
+	Bool_t							up;
 };
 
 
@@ -130,14 +135,14 @@
 extern const char                 *protocol_IDNames[Protocol_ID_Count];
 
 
-CAPI NetIF_t    *NetIF_RegisterInterface(IPv4_Addr_t *address, IPv4_Addr_t *netmask, IPv4_Addr_t *gateway, NetIF_Driver_t *driver, void *driverParameter);
-CAPI int32_t    NetIF_ProcessFrames(void);
-CAPI int32_t    NetIF_RegisterPeriodicFunction(char *name, PeriodicFunction_t function, FunctionPeriod_t period);
-CAPI int32_t    NetIF_ProcessTimers(int32_t elapsedTime);
-CAPI int32_t    NetIF_SendIPv4Packet(IPv4_Header_t *ipv4Header);
-CAPI int32_t    NetIF_Enable(NetIF_t *netIF);
-CAPI int32_t    NetIF_Disable(NetIF_t *netIF);
-CAPI void         NetIF_ProtoPop(Packet_t *packet);
-CAPI void        NetIF_ProtoPush(Packet_t *packet, int32_t headerSize, Protocol_ID_t protocol);
+NetIF_t    *NetIF_RegisterInterface(IPv4_Addr_t *address, IPv4_Addr_t *netmask, IPv4_Addr_t *gateway, NetIF_Driver_t *driver, void *driverParameter);
+int32_t    NetIF_ProcessFrames(void);
+int32_t    NetIF_RegisterPeriodicFunction(char *name, PeriodicFunction_t function, FunctionPeriod_t period);
+int32_t    NetIF_ProcessTimers(int32_t elapsedTime);
+int32_t    NetIF_SendIPv4Packet(IPv4_Header_t *ipv4Header);
+int32_t    NetIF_Up(NetIF_t *netIF);
+int32_t    NetIF_Down(NetIF_t *netIF);
+void       NetIF_ProtoPop(Packet_t *packet);
+void       NetIF_ProtoPush(Packet_t *packet, int32_t headerSize, Protocol_ID_t protocol);
 
 #endif /* __NETIF_H__ */
--- a/Queue.c	Sun Jun 12 11:23:03 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-/*
- * $Id: Queue.c 29 2011-06-11 14:53:08Z benoit $
- * $Author: benoit $
- * $Date: 2011-06-11 16:53:08 +0200 (sam., 11 juin 2011) $
- * $Rev: 29 $
- * 
- * 
- * 
- * 
- * 
- */
- 
-#include "Queue.h"
-#include "Debug.h"
-#include <stdlib.h>
-#include <string.h>
-
-
-#define    DEBUG_CURRENT_MODULE_NAME    "Queue"
-#define    DEBUG_CURRENT_MODULE_ID        DEBUG_MODULE_QUEUE
-
-
-Queue_t *Queue_Alloc(int16_t size)
-{
-    Queue_t        *queue;
-    
-    queue = (Queue_t *)malloc(sizeof(Queue_t));
-    if (queue == NULL)
-    {
-        DEBUG_MODULE(DEBUG_LEVEL_WARNING, ("Not enough memory"));
-        mbedNet_LastError = mbedNetResult_NotEnoughMemory;
-        goto Exit;
-    }
-    memset(queue, 0, sizeof(Queue_t));
-    
-    queue->size = size + 1;
-    
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("%d-%d Allocated queue of %d items", queue->popIndex, queue->pushIndex, size));
-    
-Exit:
-    return queue;
-}
-
-
-int32_t Queue_Push(Queue_t *queue, void *entry)
-{
-    int32_t        result = 0;
-    int16_t        index;
-    
-    if (queue->popIndex == ((queue->pushIndex + 1) % queue->size))
-    {
-        DEBUG_MODULE(DEBUG_LEVEL_INFO, ("%d-%d Queue is full", queue->popIndex, queue->pushIndex));
-        result = -1;
-        mbedNet_LastError = mbedNetResult_QueueFull;
-        goto Exit;
-    }
-    
-    index = queue->pushIndex;
-    queue->entries[index] = entry;
-    index++;
-    if (index == queue->size) index = 0;
-    queue->pushIndex = index;
-    
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("%d-%d Pushing one entry from queue", queue->popIndex, queue->pushIndex));
-    
-Exit:
-    return result;
-}
-
-
-int32_t Queue_Pop(Queue_t *queue, void **entry)
-{
-    int32_t        result = 0;
-    int16_t        index;
-    
-    if (queue->popIndex == queue->pushIndex)
-    {
-        DEBUG_MODULE(DEBUG_LEVEL_INFO, ("%d-%d Queue is empty", queue->popIndex, queue->pushIndex));
-        result = -1;
-        mbedNet_LastError = mbedNetResult_QueueEmpty;
-        goto Exit;
-    }
-    
-
-    index = queue->popIndex;
-    *entry = queue->entries[index];
-    index++;
-    if (index == queue->size) index = 0;
-    queue->popIndex = index;
-
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("%d-%d Popping one entry from queue", queue->popIndex, queue->pushIndex));
-        
-Exit:
-    return result;
-}
-
-
-int32_t Queue_Peek(Queue_t *queue, void **entry)
-{
-    int32_t        result = 0;
-    int16_t        index;
-    
-    if (queue->popIndex == queue->pushIndex)
-    {
-        DEBUG_MODULE(DEBUG_LEVEL_INFO, ("%d-%d Queue is empty", queue->popIndex, queue->pushIndex));
-        result = -1;
-        mbedNet_LastError = mbedNetResult_QueueEmpty;
-        goto Exit;
-    }
-    
-    index = queue->popIndex;
-    *entry = queue->entries[index];
-
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("%d-%d Peeking first entry from queue", queue->popIndex, queue->pushIndex));
-        
-Exit:
-    return result;
-}
-
-
-int32_t Queue_Free(Queue_t *queue)
-{
-    int32_t        result = 0;
-    
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("%d-%d Free queue", queue->popIndex, queue->pushIndex));
-    free(queue);
-    
-    return result;
-}
-
-
-Bool_t Queue_IsEmpty(const Queue_t *queue)
-{
-    return (queue->popIndex == queue->pushIndex) ? True : False;
-}
-
-
-Bool_t Queue_IsFull(const Queue_t *queue)
-{
-    return (queue->popIndex == ((queue->pushIndex + 1) % queue->size)) ? True : False;
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Queue.cpp	Sun Jun 12 19:17:11 2011 +0000
@@ -0,0 +1,142 @@
+/*
+ * $Id: Queue.c 29 2011-06-11 14:53:08Z benoit $
+ * $Author: benoit $
+ * $Date: 2011-06-11 16:53:08 +0200 (sam., 11 juin 2011) $
+ * $Rev: 29 $
+ * 
+ * 
+ * 
+ * 
+ * 
+ */
+ 
+#include "Queue.h"
+#include "Debug.h"
+#include <stdlib.h>
+#include <string.h>
+
+
+#define    DEBUG_CURRENT_MODULE_NAME    "Queue"
+#define    DEBUG_CURRENT_MODULE_ID        DEBUG_MODULE_QUEUE
+
+
+Queue_t *Queue_Alloc(int16_t size)
+{
+    Queue_t        *queue;
+    
+    queue = (Queue_t *)malloc(sizeof(Queue_t));
+    if (queue == NULL)
+    {
+        DEBUG_MODULE(DEBUG_LEVEL_WARNING, ("Not enough memory"));
+        mbedNet_LastError = mbedNetResult_NotEnoughMemory;
+        goto Exit;
+    }
+    memset(queue, 0, sizeof(Queue_t));
+    
+    queue->size = size + 1;
+    
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("%d-%d Allocated queue of %d items", queue->popIndex, queue->pushIndex, size));
+    
+Exit:
+    return queue;
+}
+
+
+int32_t Queue_Push(Queue_t *queue, void *entry)
+{
+    int32_t        result = 0;
+    int16_t        index;
+    
+    if (queue->popIndex == ((queue->pushIndex + 1) % queue->size))
+    {
+        DEBUG_MODULE(DEBUG_LEVEL_INFO, ("%d-%d Queue is full", queue->popIndex, queue->pushIndex));
+        result = -1;
+        mbedNet_LastError = mbedNetResult_QueueFull;
+        goto Exit;
+    }
+    
+    index = queue->pushIndex;
+    queue->entries[index] = entry;
+    index++;
+    if (index == queue->size) index = 0;
+    queue->pushIndex = index;
+    
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("%d-%d Pushing one entry from queue", queue->popIndex, queue->pushIndex));
+    
+Exit:
+    return result;
+}
+
+
+int32_t Queue_Pop(Queue_t *queue, void **entry)
+{
+    int32_t        result = 0;
+    int16_t        index;
+    
+    if (queue->popIndex == queue->pushIndex)
+    {
+        DEBUG_MODULE(DEBUG_LEVEL_INFO, ("%d-%d Queue is empty", queue->popIndex, queue->pushIndex));
+        result = -1;
+        mbedNet_LastError = mbedNetResult_QueueEmpty;
+        goto Exit;
+    }
+    
+
+    index = queue->popIndex;
+    *entry = queue->entries[index];
+    index++;
+    if (index == queue->size) index = 0;
+    queue->popIndex = index;
+
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("%d-%d Popping one entry from queue", queue->popIndex, queue->pushIndex));
+        
+Exit:
+    return result;
+}
+
+
+int32_t Queue_Peek(Queue_t *queue, void **entry)
+{
+    int32_t        result = 0;
+    int16_t        index;
+    
+    if (queue->popIndex == queue->pushIndex)
+    {
+        DEBUG_MODULE(DEBUG_LEVEL_INFO, ("%d-%d Queue is empty", queue->popIndex, queue->pushIndex));
+        result = -1;
+        mbedNet_LastError = mbedNetResult_QueueEmpty;
+        goto Exit;
+    }
+    
+    index = queue->popIndex;
+    *entry = queue->entries[index];
+
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("%d-%d Peeking first entry from queue", queue->popIndex, queue->pushIndex));
+        
+Exit:
+    return result;
+}
+
+
+int32_t Queue_Free(Queue_t *queue)
+{
+    int32_t        result = 0;
+    
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("%d-%d Free queue", queue->popIndex, queue->pushIndex));
+    free(queue);
+    
+    return result;
+}
+
+
+Bool_t Queue_IsEmpty(const Queue_t *queue)
+{
+    return (queue->popIndex == queue->pushIndex) ? True : False;
+}
+
+
+Bool_t Queue_IsFull(const Queue_t *queue)
+{
+    return (queue->popIndex == ((queue->pushIndex + 1) % queue->size)) ? True : False;
+}
+
--- a/Queue.h	Sun Jun 12 11:23:03 2011 +0000
+++ b/Queue.h	Sun Jun 12 19:17:11 2011 +0000
@@ -27,13 +27,13 @@
 typedef struct Queue Queue_t;
 
 
-CAPI Queue_t    *Queue_Alloc(int16_t size);
-CAPI int32_t     Queue_Push(Queue_t *queue, void *entry);
-CAPI int32_t     Queue_Pop(Queue_t *queue, void **entry);
-CAPI int32_t     Queue_Peek(Queue_t *queue, void **entry);
-CAPI int32_t     Queue_Free(Queue_t *queue);
-CAPI Bool_t        Queue_IsEmpty(const Queue_t *queue);
-CAPI Bool_t        Queue_IsFull(const Queue_t *queue);
+Queue_t    *Queue_Alloc(int16_t size);
+int32_t     Queue_Push(Queue_t *queue, void *entry);
+int32_t     Queue_Pop(Queue_t *queue, void **entry);
+int32_t     Queue_Peek(Queue_t *queue, void **entry);
+int32_t     Queue_Free(Queue_t *queue);
+Bool_t      Queue_IsEmpty(const Queue_t *queue);
+Bool_t      Queue_IsFull(const Queue_t *queue);
 
 
 #endif /* __QUEUE_H__ */
--- a/Sockets.c	Sun Jun 12 11:23:03 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,607 +0,0 @@
-/*
- * $Id: Sockets.c 29 2011-06-11 14:53:08Z benoit $
- * $Author: benoit $
- * $Date: 2011-06-11 16:53:08 +0200 (sam., 11 juin 2011) $
- * $Rev: 29 $
- * 
- * 
- * 
- * 
- * 
- */
- 
-#include "NetIF.h"
-#include "Sockets.h"
-#include "IPv4.h"
-#include "UDPv4.h"
-#include "Debug.h"
-#include "Queue.h"
-#include <string.h>
-#include <stdlib.h>
-
-
-#define    DEBUG_CURRENT_MODULE_NAME    "sockets"
-#define    DEBUG_CURRENT_MODULE_ID        DEBUG_MODULE_SOCKETS
-
-
-#define    UDPV4_DATA_OFFSET            8
-
-
-struct DataBlock
-{
-    uint8_t        *dataPtr,
-                *readPtr;
-    int16_t        totalSize, 
-                remainingSize;
-};
-typedef struct DataBlock DataBlock_t;
-
-
-enum State
-{
-    State_Close = 0,
-    State_Open,
-    State_Bound,
-};
-typedef enum State State_t;
-
-
-struct Socket_Entry
-{
-    //Bool_t                inUse;
-    Socket_Family_t        family;
-    Socket_Protocol_t    protocol;
-    int32_t                options;
-    State_t                state;
-    Socket_Addr_t        *localAddr,
-                        *remoteAddr;
-    Queue_t                *dataQueue;
-    int32_t                index;
-};
-typedef struct Socket_Entry Socket_Entry_t;
-
-
-static Socket_Entry_t    socketEntryTable[SOCKET_MAX_COUNT];
-static Bool_t            socketAPIInitialized = False;
-
-
-static void             Init(void);
-static int32_t             Hook(NetIF_t *netIF, Protocol_ID_t protocolID, Packet_t *packet);
-static void             Hook_UDPv4(NetIF_t *netIF, Packet_t *packet, Socket_Entry_t *entry);
-static Socket_Entry_t    *GetSocketEntry(Socket_t socket);
-static int32_t            BindUDPv4(Socket_Entry_t    *entry, Socket_AddrIn_t *addrIn);
-static int32_t            Recv_Data(Socket_Entry_t *entry, uint8_t *data, int32_t length);
-static int32_t            SendToUDPv4(Socket_Entry_t *entry, uint8_t *data, int32_t length, Socket_AddrIn_t *remoteAddr);
-
-
-Net_API_t    sockets = 
-{
-    API_ID_Sockets,
-    Init,
-    Hook
-};
-
-
-static void Init(void)
-{
-    if (socketAPIInitialized) goto Exit;
-    
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing"));
-    memset(socketEntryTable, 0, sizeof(socketEntryTable));
-    socketAPIInitialized = True;
-    
-Exit:
-    return;
-}
-
-
-static int32_t Hook(NetIF_t *netIF, Protocol_ID_t protocolID, Packet_t *packet)
-{
-    int32_t                index = 0;
-    Socket_Entry_t        *entry = NULL;
-
-    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("Hook(%s%d, %s, %d bytes)",
-        netIF->name,
-        netIF->index,
-        protocol_IDNames[protocolID],
-        packet->length
-    ));
-    
-    for (index = 0; index < SOCKET_MAX_COUNT; index++)
-    {
-        entry = socketEntryTable + index;
-        if (entry->state != State_Bound) continue;
-        switch(protocolID)
-        {
-            case Protocol_ID_UDPv4:
-                if (entry->protocol == SOCK_DGRAM) Hook_UDPv4(netIF, packet, entry);
-                break;
-                
-            default:
-                continue;
-        }
-    }
-        
-    return 0;
-}
-
-static void Hook_UDPv4(NetIF_t *netIF, Packet_t *packet, Socket_Entry_t *entry)
-{
-    IPv4_Header_t        *ipv4Header;
-    UDPv4_Header_t        *udpv4Header;
-    Socket_AddrIn_t        *localAddrIn, *remoteAddrIn;
-    int32_t                depth;
-    DataBlock_t            *dataBlock;
-
-
-    depth = packet->depth;
-    ipv4Header = (IPv4_Header_t *)packet->headerPtrTable[depth];
-    udpv4Header = (UDPv4_Header_t *)(ipv4Header + 1);
-    localAddrIn = (Socket_AddrIn_t *)entry->localAddr;
-    remoteAddrIn = (Socket_AddrIn_t *)entry->remoteAddr;
-    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("ports: %d.%d.%d.%d:%d to %d.%d.%d.%d:%d size:%d",
-        ipv4Header->source.IP0,
-        ipv4Header->source.IP1,
-        ipv4Header->source.IP2,
-        ipv4Header->source.IP3,
-        ntohs(udpv4Header->destPort),
-        localAddrIn->address.IP0,
-        localAddrIn->address.IP1,
-        localAddrIn->address.IP2,
-        localAddrIn->address.IP3,
-        ntohs(localAddrIn->port),
-        ntohs(udpv4Header->length)
-    ));
-    if ((localAddrIn->port == udpv4Header->destPort) && ( (localAddrIn->address.addr == IPADDR_ANY) || (ipv4Header->dest.addr == localAddrIn->address.addr) ) )
-    {
-        if (!Queue_IsFull(entry->dataQueue))
-        {
-            remoteAddrIn->address = ipv4Header->source;
-            remoteAddrIn->port = udpv4Header->sourcePort;
-            dataBlock = (DataBlock_t *)malloc(sizeof(DataBlock_t));
-            if (dataBlock == NULL)
-            {
-                mbedNet_LastError = mbedNetResult_NotEnoughMemory;
-                goto Exit;
-            }
-            dataBlock->totalSize = ntohs(udpv4Header->length) - sizeof(UDPv4_Header_t);
-            dataBlock->remainingSize = dataBlock->totalSize;
-            dataBlock->dataPtr = (uint8_t *)malloc(dataBlock->totalSize);
-            if (dataBlock->dataPtr == NULL)
-            {
-                free(dataBlock);
-                mbedNet_LastError = mbedNetResult_NotEnoughMemory;
-                goto Exit;
-            }
-            dataBlock->readPtr = dataBlock->dataPtr;
-            memcpy(dataBlock->dataPtr, packet->data + sizeof(UDPv4_Header_t), dataBlock->totalSize);
-            Queue_Push(entry->dataQueue, (void *)dataBlock);
-            DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("Added block of %d bytes to socket %d", dataBlock->totalSize, entry->index));
-        }
-    }
-    
-Exit:
-    return;
-}
-
-static int32_t BindUDPv4(Socket_Entry_t    *entry, Socket_AddrIn_t *addrIn)
-{
-    int32_t                result = -1;
-    Socket_AddrIn_t        *localAddrIn, 
-                        *remoteAddrIn;
-
-    entry->localAddr = (Socket_Addr_t *)malloc(sizeof(Socket_AddrIn_t));
-    if (entry->localAddr == NULL)
-    {
-        mbedNet_LastError = mbedNetResult_NotEnoughMemory;
-        goto Exit;
-    }
-    entry->remoteAddr = (Socket_Addr_t *)malloc(sizeof(Socket_AddrIn_t));
-    if (entry->remoteAddr == NULL)
-    {
-        free(entry->localAddr);
-        mbedNet_LastError = mbedNetResult_NotEnoughMemory;
-        goto Exit;
-    }
-    localAddrIn = (Socket_AddrIn_t *)entry->localAddr;
-    remoteAddrIn = (Socket_AddrIn_t *)entry->remoteAddr;
-    memcpy(localAddrIn, addrIn, sizeof(Socket_AddrIn_t));
-    memset(remoteAddrIn, 0, sizeof(Socket_AddrIn_t));
-    remoteAddrIn->family = addrIn->family;
-    remoteAddrIn->len = addrIn->len;
-    localAddrIn->port = addrIn->port;
-    
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Binding socket %d to %d.%d.%d.%d:%d", 
-        entry->index, 
-        addrIn->address.IP0, 
-        addrIn->address.IP1, 
-        addrIn->address.IP2, 
-        addrIn->address.IP3, 
-        ntohs(addrIn->port)
-    ));
-    
-Exit:
-    return result;
-}
-
-
-static int32_t Recv_Data(Socket_Entry_t *entry, uint8_t *data, int32_t length)
-{
-    int32_t            count = 0;
-    DataBlock_t        *dataBlock = NULL;
-
-    Queue_Peek(entry->dataQueue, (void **)&dataBlock);
-    if (dataBlock->remainingSize <= length)
-    {
-        count = dataBlock->remainingSize;
-        Queue_Pop(entry->dataQueue, (void **)&dataBlock);
-        memcpy(data, dataBlock->readPtr, count);
-        free(dataBlock->dataPtr);
-        free(dataBlock);
-    }
-    else
-    {
-        count = length;
-        memcpy(data, dataBlock->readPtr, count);
-        dataBlock->readPtr += count;
-        dataBlock->remainingSize -= count;
-    }
-    return count;
-}
-
-
-static int32_t SendToUDPv4(Socket_Entry_t *entry, uint8_t *data, int32_t length, Socket_AddrIn_t *remoteAddr)
-{
-    int32_t                count = -1,
-                        totalLength;
-    IPv4_Header_t        *ipv4Header;
-    UDPv4_Header_t        *udpv4Header;
-    Socket_AddrIn_t        *localAddrIn,
-                        *remoteAddrIn;
-    
-    localAddrIn = (Socket_AddrIn_t *)entry->localAddr;
-    remoteAddrIn = (Socket_AddrIn_t *)entry->remoteAddr;
-    totalLength = length + sizeof(UDPv4_Header_t) + sizeof(IPv4_Header_t);
-    ipv4Header = (IPv4_Header_t *)malloc(totalLength);
-    if (ipv4Header == NULL)
-    {
-        DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Not enough memory (needed %d bytes)", totalLength));
-        mbedNet_LastError = mbedNetResult_NotEnoughMemory;
-        goto Exit;
-    }
-    
-    memset(ipv4Header, 0, totalLength);
-    
-    DEBUG_SOURCE(DEBUG_LEVEL_VERBOSE0, ("UDPv4 sending %d bytes to %d.%d.%d.%d:%d",
-        length,
-        remoteAddr->address.IP0,
-        remoteAddr->address.IP1,
-        remoteAddr->address.IP2,
-        remoteAddr->address.IP3,
-        ntohs(remoteAddr->port)
-
-    ));
-    
-    udpv4Header = (UDPv4_Header_t *)(ipv4Header + 1);
-    
-    ipv4Header->ihl = 5;
-    ipv4Header->version = IPV4_VERSION;
-    ipv4Header->tos = 0;
-    ipv4Header->totalLength = htons(5 * 4 + totalLength);
-    ipv4Header->id = 0;
-    ipv4Header->fragmentFlags = 0;
-    ipv4Header->ttl = NET_DEFAULT_TTL;
-    ipv4Header->protocol = IPV4_PROTO_UDPV4;
-    ipv4Header->dest = remoteAddr->address;
-    
-    udpv4Header->sourcePort = localAddrIn->port;
-    udpv4Header->destPort = remoteAddrIn->port;
-    udpv4Header->length = htons(length + sizeof(UDPv4_Header_t));
-    
-    memcpy(udpv4Header + 1, data, length);
-    
-    DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE0)
-    {
-        IPv4_DumpIPv4Header("Sockets:", ipv4Header);
-    }
-    
-    count = NetIF_SendIPv4Packet(ipv4Header);
-    free(ipv4Header);
-
-Exit:
-    return count;
-}
-
-
-Socket_t Sockets_Open(Socket_Family_t family, Socket_Protocol_t protocol, int32_t options)
-{
-    int32_t            result = 0,
-                    index = 0;
-    Socket_Entry_t    *entry = NULL;
-
-    if (family != AF_INET)
-    {
-        DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Protocol family not supported"));
-        mbedNet_LastError = mbedNetResult_NotIplemented;
-        result = -1;
-        goto Exit;
-    }
-
-    for (index = 0; index < SOCKET_MAX_COUNT; index++)
-    {
-        if (socketEntryTable[index].state != State_Close) continue;
-        entry = socketEntryTable + index;
-        break;
-    }
-
-    if (entry == NULL)
-    {
-        DEBUG_MODULE(DEBUG_LEVEL_WARNING, ("Too many open sockets"));
-        mbedNet_LastError = mbedNetResult_TooManyOpenSockets;
-        result = -1;
-        goto Exit;
-    }
-    
-    entry->family = family;
-    entry->protocol = protocol;
-    entry->options = options;
-    entry->state = State_Open;
-    entry->dataQueue = NULL;
-    entry->index = index;
-    result = index;
-
-Exit:
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("opened socket %d", index));
-    return result;
-}
-
-
-int32_t Sockets_Bind(Socket_t socket, Socket_Addr_t *addr, int32_t addrLen)
-{
-    int32_t            result = -1;
-    Socket_Entry_t    *entry;
-
-    if ((entry = GetSocketEntry(socket)) == NULL) goto Exit;
-    
-    if (entry == NULL)
-    {
-        DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Socket %d not found", socket));
-        mbedNet_LastError = mbedNetResult_NotEnoughMemory;
-        result = -1;
-        goto Exit;
-    }
-
-    /* Allocate address entry */
-    switch(entry->family)
-    {
-        case AF_INET:
-            switch(entry->protocol)
-            {
-                case SOCK_DGRAM:
-                    if (addrLen != sizeof(Socket_AddrIn_t))
-                    {
-                        mbedNet_LastError = mbedNetResult_InvalidParameter;
-                        result = -1;
-                        goto Exit;
-                    }
-                    result = BindUDPv4(entry, (Socket_AddrIn_t *)addr);
-                    break;
-                    
-                case SOCK_STREAM:
-                    DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Protocol not supported"));
-                    mbedNet_LastError = mbedNetResult_NotIplemented;
-                    result = -1;
-                    goto Exit;
-                    
-                case SOCK_RAW:
-                    DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Protocol not supported"));
-                    mbedNet_LastError = mbedNetResult_NotIplemented;
-                    result = -1;
-                    goto Exit;
-                    
-                default:
-                    DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Unknown socket protocol"));
-                    mbedNet_LastError = mbedNetResult_InvalidParameter;
-                    result = -1;
-                    goto Exit;
-            }
-            break;
-            
-        default:
-            DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Protocol family not supported"));
-            mbedNet_LastError = mbedNetResult_NotIplemented;
-            result = -1;
-            goto Exit;
-    }
-    
-    entry->dataQueue = Queue_Alloc(SOCKET_DATAQUEUE_ENTRY_COUNT);
-    
-    if (entry == NULL)
-    {
-        free(entry->localAddr);
-        free(entry->remoteAddr);
-        DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Not enough memory to allocate data queue"));
-        mbedNet_LastError = mbedNetResult_NotEnoughMemory;
-        result = -1;
-        goto Exit;
-    }
-        
-    entry->state = State_Bound;
-    
-    result = 0;
-    
-Exit:
-    return result;
-}
-
-
-int32_t Sockets_Send(Socket_t socket, uint8_t *data, int32_t length, int32_t flags)
-{
-    int32_t            count = -1;
-    Socket_Entry_t    *entry;
-
-    entry = GetSocketEntry(socket);
-    if (entry == NULL) goto Exit;
-
-    if (entry->protocol == SOCK_DGRAM)
-    {
-        mbedNet_LastError = mbedNetResult_DestinationAddressRequired;
-        goto Exit;
-    }
-
-    mbedNet_LastError = mbedNetResult_NotIplemented;
-
-Exit:
-    return count;
-}
-
-
-int32_t Sockets_SendTo(Socket_t socket, uint8_t *data, int32_t length, int32_t flags, const Socket_Addr_t *remoteAddr, int32_t addrLen)
-{
-    int32_t            count = -1;
-    Socket_Entry_t    *entry;
-
-
-    entry = GetSocketEntry(socket);
-    if (entry == NULL) 
-    {
-        DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("socket not found!"));
-        goto Exit;
-    }
-
-    switch(entry->family)
-    {
-        case AF_INET:
-            switch(entry->protocol)
-            {
-                case SOCK_DGRAM:
-                    if (addrLen != sizeof(Socket_AddrIn_t))
-                    {
-                        DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Invalid socket address length"));
-                        mbedNet_LastError = mbedNetResult_InvalidParameter;
-                        goto Exit;
-                    }
-                    count = SendToUDPv4(entry, data, length, (Socket_AddrIn_t *)remoteAddr);
-                    break;
-                
-                default:
-                    DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Protocol not implemented"));
-                    mbedNet_LastError = mbedNetResult_NotIplemented;
-                    goto Exit;
-            }
-            break;
-            
-        default:
-            DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Protocol family not implemented"));
-            mbedNet_LastError = mbedNetResult_NotIplemented;
-            goto Exit;
-    }
-
-Exit:
-    return count;
-}
-
-
-int32_t Sockets_Recv(Socket_t socket, uint8_t *data, int32_t length, int32_t flags)
-{
-    int32_t                count = -1;
-    Socket_Entry_t        *entry;
-    
-    entry = GetSocketEntry(socket);
-    if (entry == NULL) goto Exit;
-
-    if (Queue_IsEmpty(entry->dataQueue))
-    {
-        mbedNet_LastError = mbedNetResult_WouldBlock;
-        goto Exit;
-    }
-
-    count = Recv_Data(entry, data, length);
-        
-Exit:
-    return count;
-}
-
-
-int32_t Sockets_RecvFrom(Socket_t socket, uint8_t *data, int32_t length, int32_t flags, Socket_Addr_t *remoteAddr, int32_t *addrLen)
-{
-    int32_t            count = -1;
-    Socket_Entry_t    *entry;
-    
-    entry = GetSocketEntry(socket);
-    if (entry == NULL) goto Exit;
-
-    if (Queue_IsEmpty(entry->dataQueue))
-    {
-        mbedNet_LastError = mbedNetResult_WouldBlock;
-        goto Exit;
-    }
-    
-    if (remoteAddr != NULL)
-    {
-        if (entry->localAddr->len > *addrLen)
-        {
-            mbedNet_LastError = mbedNetResult_BufferTooSmall;
-            goto Exit;
-        }
-        memcpy(remoteAddr, entry->remoteAddr, entry->remoteAddr->len);
-    }
-        
-    count = Recv_Data(entry, data, length);
-
-Exit:
-    return count;
-}
-
-
-int32_t Sockets_Close(Socket_t socket)
-{
-    int32_t            result = -1;
-    Socket_Entry_t    *entry;
-    void            *ptr;
-
-    if ((entry = GetSocketEntry(socket)) == NULL) goto Exit;
-    
-    entry->state = State_Close;
-    free(entry->localAddr);
-    entry->localAddr = NULL;
-    free(entry->remoteAddr);
-    entry->remoteAddr = NULL;
-    /* Free pending data blocks */
-    while(Queue_Peek(entry->dataQueue, &ptr) != -1)
-    {
-        free(ptr);
-    }
-    Queue_Free(entry->dataQueue);
-    entry->dataQueue = NULL;
-    result = 0;
-    
-Exit:
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("closed socket %d", socket));
-    return result;
-}
-
-
-
-static Socket_Entry_t *GetSocketEntry(Socket_t socket)
-{
-    Socket_Entry_t    *entry = NULL;
-
-    if ((socket < 0) || (socket >= SOCKET_MAX_COUNT))
-    {
-        DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Invalid socket handle"));
-        mbedNet_LastError = mbedNetResult_InvalidSocketHandle;
-        goto Exit;
-    }
-    entry = socketEntryTable + socket;
-
-    if (entry->state == State_Close)
-    {
-        DEBUG_MODULE(DEBUG_LEVEL_WARNING, ("Socket already closed"));
-        mbedNet_LastError = mbedNetResult_SocketAlreadyClosed;
-        entry = NULL;
-        goto Exit;
-    }
-Exit:
-    return entry;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sockets.cpp	Sun Jun 12 19:17:11 2011 +0000
@@ -0,0 +1,607 @@
+/*
+ * $Id: Sockets.c 29 2011-06-11 14:53:08Z benoit $
+ * $Author: benoit $
+ * $Date: 2011-06-11 16:53:08 +0200 (sam., 11 juin 2011) $
+ * $Rev: 29 $
+ * 
+ * 
+ * 
+ * 
+ * 
+ */
+ 
+#include "NetIF.h"
+#include "Sockets.h"
+#include "IPv4.h"
+#include "UDPv4.h"
+#include "Debug.h"
+#include "Queue.h"
+#include <string.h>
+#include <stdlib.h>
+
+
+#define    DEBUG_CURRENT_MODULE_NAME    "sockets"
+#define    DEBUG_CURRENT_MODULE_ID        DEBUG_MODULE_SOCKETS
+
+
+#define    UDPV4_DATA_OFFSET            8
+
+
+struct DataBlock
+{
+    uint8_t        *dataPtr,
+                *readPtr;
+    int16_t        totalSize, 
+                remainingSize;
+};
+typedef struct DataBlock DataBlock_t;
+
+
+enum State
+{
+    State_Close = 0,
+    State_Open,
+    State_Bound,
+};
+typedef enum State State_t;
+
+
+struct Socket_Entry
+{
+    //Bool_t                inUse;
+    Socket_Family_t        family;
+    Socket_Protocol_t    protocol;
+    int32_t                options;
+    State_t                state;
+    Socket_Addr_t        *localAddr,
+                        *remoteAddr;
+    Queue_t                *dataQueue;
+    int32_t                index;
+};
+typedef struct Socket_Entry Socket_Entry_t;
+
+
+static Socket_Entry_t    socketEntryTable[SOCKET_MAX_COUNT];
+static Bool_t            socketAPIInitialized = False;
+
+
+static void             Init(void);
+static int32_t             Hook(NetIF_t *netIF, Protocol_ID_t protocolID, Packet_t *packet);
+static void             Hook_UDPv4(NetIF_t *netIF, Packet_t *packet, Socket_Entry_t *entry);
+static Socket_Entry_t    *GetSocketEntry(Socket_t socket);
+static int32_t            BindUDPv4(Socket_Entry_t    *entry, Socket_AddrIn_t *addrIn);
+static int32_t            Recv_Data(Socket_Entry_t *entry, uint8_t *data, int32_t length);
+static int32_t            SendToUDPv4(Socket_Entry_t *entry, uint8_t *data, int32_t length, Socket_AddrIn_t *remoteAddr);
+
+
+Net_API_t    sockets = 
+{
+    API_ID_Sockets,
+    Init,
+    Hook
+};
+
+
+static void Init(void)
+{
+    if (socketAPIInitialized) goto Exit;
+    
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing"));
+    memset(socketEntryTable, 0, sizeof(socketEntryTable));
+    socketAPIInitialized = True;
+    
+Exit:
+    return;
+}
+
+
+static int32_t Hook(NetIF_t *netIF, Protocol_ID_t protocolID, Packet_t *packet)
+{
+    int32_t                index = 0;
+    Socket_Entry_t        *entry = NULL;
+
+    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("Hook(%s%d, %s, %d bytes)",
+        netIF->name,
+        netIF->index,
+        protocol_IDNames[protocolID],
+        packet->length
+    ));
+    
+    for (index = 0; index < SOCKET_MAX_COUNT; index++)
+    {
+        entry = socketEntryTable + index;
+        if (entry->state != State_Bound) continue;
+        switch(protocolID)
+        {
+            case Protocol_ID_UDPv4:
+                if (entry->protocol == SOCK_DGRAM) Hook_UDPv4(netIF, packet, entry);
+                break;
+                
+            default:
+                continue;
+        }
+    }
+        
+    return 0;
+}
+
+static void Hook_UDPv4(NetIF_t *netIF, Packet_t *packet, Socket_Entry_t *entry)
+{
+    IPv4_Header_t        *ipv4Header;
+    UDPv4_Header_t        *udpv4Header;
+    Socket_AddrIn_t        *localAddrIn, *remoteAddrIn;
+    int32_t                depth;
+    DataBlock_t            *dataBlock;
+
+
+    depth = packet->depth;
+    ipv4Header = (IPv4_Header_t *)packet->headerPtrTable[depth];
+    udpv4Header = (UDPv4_Header_t *)(ipv4Header + 1);
+    localAddrIn = (Socket_AddrIn_t *)entry->localAddr;
+    remoteAddrIn = (Socket_AddrIn_t *)entry->remoteAddr;
+    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("ports: %d.%d.%d.%d:%d to %d.%d.%d.%d:%d size:%d",
+        ipv4Header->source.IP0,
+        ipv4Header->source.IP1,
+        ipv4Header->source.IP2,
+        ipv4Header->source.IP3,
+        ntohs(udpv4Header->destPort),
+        localAddrIn->address.IP0,
+        localAddrIn->address.IP1,
+        localAddrIn->address.IP2,
+        localAddrIn->address.IP3,
+        ntohs(localAddrIn->port),
+        ntohs(udpv4Header->length)
+    ));
+    if ((localAddrIn->port == udpv4Header->destPort) && ( (localAddrIn->address.addr == IPADDR_ANY) || (ipv4Header->dest.addr == localAddrIn->address.addr) ) )
+    {
+        if (!Queue_IsFull(entry->dataQueue))
+        {
+            remoteAddrIn->address = ipv4Header->source;
+            remoteAddrIn->port = udpv4Header->sourcePort;
+            dataBlock = (DataBlock_t *)malloc(sizeof(DataBlock_t));
+            if (dataBlock == NULL)
+            {
+                mbedNet_LastError = mbedNetResult_NotEnoughMemory;
+                goto Exit;
+            }
+            dataBlock->totalSize = ntohs(udpv4Header->length) - sizeof(UDPv4_Header_t);
+            dataBlock->remainingSize = dataBlock->totalSize;
+            dataBlock->dataPtr = (uint8_t *)malloc(dataBlock->totalSize);
+            if (dataBlock->dataPtr == NULL)
+            {
+                free(dataBlock);
+                mbedNet_LastError = mbedNetResult_NotEnoughMemory;
+                goto Exit;
+            }
+            dataBlock->readPtr = dataBlock->dataPtr;
+            memcpy(dataBlock->dataPtr, packet->data + sizeof(UDPv4_Header_t), dataBlock->totalSize);
+            Queue_Push(entry->dataQueue, (void *)dataBlock);
+            DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("Added block of %d bytes to socket %d", dataBlock->totalSize, entry->index));
+        }
+    }
+    
+Exit:
+    return;
+}
+
+static int32_t BindUDPv4(Socket_Entry_t    *entry, Socket_AddrIn_t *addrIn)
+{
+    int32_t                result = -1;
+    Socket_AddrIn_t        *localAddrIn, 
+                        *remoteAddrIn;
+
+    entry->localAddr = (Socket_Addr_t *)malloc(sizeof(Socket_AddrIn_t));
+    if (entry->localAddr == NULL)
+    {
+        mbedNet_LastError = mbedNetResult_NotEnoughMemory;
+        goto Exit;
+    }
+    entry->remoteAddr = (Socket_Addr_t *)malloc(sizeof(Socket_AddrIn_t));
+    if (entry->remoteAddr == NULL)
+    {
+        free(entry->localAddr);
+        mbedNet_LastError = mbedNetResult_NotEnoughMemory;
+        goto Exit;
+    }
+    localAddrIn = (Socket_AddrIn_t *)entry->localAddr;
+    remoteAddrIn = (Socket_AddrIn_t *)entry->remoteAddr;
+    memcpy(localAddrIn, addrIn, sizeof(Socket_AddrIn_t));
+    memset(remoteAddrIn, 0, sizeof(Socket_AddrIn_t));
+    remoteAddrIn->family = addrIn->family;
+    remoteAddrIn->len = addrIn->len;
+    localAddrIn->port = addrIn->port;
+    
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Binding socket %d to %d.%d.%d.%d:%d", 
+        entry->index, 
+        addrIn->address.IP0, 
+        addrIn->address.IP1, 
+        addrIn->address.IP2, 
+        addrIn->address.IP3, 
+        ntohs(addrIn->port)
+    ));
+    
+Exit:
+    return result;
+}
+
+
+static int32_t Recv_Data(Socket_Entry_t *entry, uint8_t *data, int32_t length)
+{
+    int32_t            count = 0;
+    DataBlock_t        *dataBlock = NULL;
+
+    Queue_Peek(entry->dataQueue, (void **)&dataBlock);
+    if (dataBlock->remainingSize <= length)
+    {
+        count = dataBlock->remainingSize;
+        Queue_Pop(entry->dataQueue, (void **)&dataBlock);
+        memcpy(data, dataBlock->readPtr, count);
+        free(dataBlock->dataPtr);
+        free(dataBlock);
+    }
+    else
+    {
+        count = length;
+        memcpy(data, dataBlock->readPtr, count);
+        dataBlock->readPtr += count;
+        dataBlock->remainingSize -= count;
+    }
+    return count;
+}
+
+
+static int32_t SendToUDPv4(Socket_Entry_t *entry, uint8_t *data, int32_t length, Socket_AddrIn_t *remoteAddr)
+{
+    int32_t                count = -1,
+                        totalLength;
+    IPv4_Header_t        *ipv4Header;
+    UDPv4_Header_t        *udpv4Header;
+    Socket_AddrIn_t        *localAddrIn,
+                        *remoteAddrIn;
+    
+    localAddrIn = (Socket_AddrIn_t *)entry->localAddr;
+    remoteAddrIn = (Socket_AddrIn_t *)entry->remoteAddr;
+    totalLength = length + sizeof(UDPv4_Header_t) + sizeof(IPv4_Header_t);
+    ipv4Header = (IPv4_Header_t *)malloc(totalLength);
+    if (ipv4Header == NULL)
+    {
+        DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Not enough memory (needed %d bytes)", totalLength));
+        mbedNet_LastError = mbedNetResult_NotEnoughMemory;
+        goto Exit;
+    }
+    
+    memset(ipv4Header, 0, totalLength);
+    
+    DEBUG_SOURCE(DEBUG_LEVEL_VERBOSE0, ("UDPv4 sending %d bytes to %d.%d.%d.%d:%d",
+        length,
+        remoteAddr->address.IP0,
+        remoteAddr->address.IP1,
+        remoteAddr->address.IP2,
+        remoteAddr->address.IP3,
+        ntohs(remoteAddr->port)
+
+    ));
+    
+    udpv4Header = (UDPv4_Header_t *)(ipv4Header + 1);
+    
+    ipv4Header->ihl = 5;
+    ipv4Header->version = IPV4_VERSION;
+    ipv4Header->tos = 0;
+    ipv4Header->totalLength = htons(5 * 4 + totalLength);
+    ipv4Header->id = 0;
+    ipv4Header->fragmentFlags = 0;
+    ipv4Header->ttl = NET_DEFAULT_TTL;
+    ipv4Header->protocol = IPV4_PROTO_UDPV4;
+    ipv4Header->dest = remoteAddr->address;
+    
+    udpv4Header->sourcePort = localAddrIn->port;
+    udpv4Header->destPort = remoteAddrIn->port;
+    udpv4Header->length = htons(length + sizeof(UDPv4_Header_t));
+    
+    memcpy(udpv4Header + 1, data, length);
+    
+    DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE0)
+    {
+        IPv4_DumpIPv4Header("Sockets:", ipv4Header);
+    }
+    
+    count = NetIF_SendIPv4Packet(ipv4Header);
+    free(ipv4Header);
+
+Exit:
+    return count;
+}
+
+
+Socket_t Sockets_Open(Socket_Family_t family, Socket_Protocol_t protocol, int32_t options)
+{
+    int32_t            result = 0,
+                    index = 0;
+    Socket_Entry_t    *entry = NULL;
+
+    if (family != AF_INET)
+    {
+        DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Protocol family not supported"));
+        mbedNet_LastError = mbedNetResult_NotIplemented;
+        result = -1;
+        goto Exit;
+    }
+
+    for (index = 0; index < SOCKET_MAX_COUNT; index++)
+    {
+        if (socketEntryTable[index].state != State_Close) continue;
+        entry = socketEntryTable + index;
+        break;
+    }
+
+    if (entry == NULL)
+    {
+        DEBUG_MODULE(DEBUG_LEVEL_WARNING, ("Too many open sockets"));
+        mbedNet_LastError = mbedNetResult_TooManyOpenSockets;
+        result = -1;
+        goto Exit;
+    }
+    
+    entry->family = family;
+    entry->protocol = protocol;
+    entry->options = options;
+    entry->state = State_Open;
+    entry->dataQueue = NULL;
+    entry->index = index;
+    result = index;
+
+Exit:
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("opened socket %d", index));
+    return result;
+}
+
+
+int32_t Sockets_Bind(Socket_t socket, Socket_Addr_t *addr, int32_t addrLen)
+{
+    int32_t            result = -1;
+    Socket_Entry_t    *entry;
+
+    if ((entry = GetSocketEntry(socket)) == NULL) goto Exit;
+    
+    if (entry == NULL)
+    {
+        DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Socket %d not found", socket));
+        mbedNet_LastError = mbedNetResult_NotEnoughMemory;
+        result = -1;
+        goto Exit;
+    }
+
+    /* Allocate address entry */
+    switch(entry->family)
+    {
+        case AF_INET:
+            switch(entry->protocol)
+            {
+                case SOCK_DGRAM:
+                    if (addrLen != sizeof(Socket_AddrIn_t))
+                    {
+                        mbedNet_LastError = mbedNetResult_InvalidParameter;
+                        result = -1;
+                        goto Exit;
+                    }
+                    result = BindUDPv4(entry, (Socket_AddrIn_t *)addr);
+                    break;
+                    
+                case SOCK_STREAM:
+                    DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Protocol not supported"));
+                    mbedNet_LastError = mbedNetResult_NotIplemented;
+                    result = -1;
+                    goto Exit;
+                    
+                case SOCK_RAW:
+                    DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Protocol not supported"));
+                    mbedNet_LastError = mbedNetResult_NotIplemented;
+                    result = -1;
+                    goto Exit;
+                    
+                default:
+                    DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Unknown socket protocol"));
+                    mbedNet_LastError = mbedNetResult_InvalidParameter;
+                    result = -1;
+                    goto Exit;
+            }
+            break;
+            
+        default:
+            DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Protocol family not supported"));
+            mbedNet_LastError = mbedNetResult_NotIplemented;
+            result = -1;
+            goto Exit;
+    }
+    
+    entry->dataQueue = Queue_Alloc(SOCKET_DATAQUEUE_ENTRY_COUNT);
+    
+    if (entry == NULL)
+    {
+        free(entry->localAddr);
+        free(entry->remoteAddr);
+        DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Not enough memory to allocate data queue"));
+        mbedNet_LastError = mbedNetResult_NotEnoughMemory;
+        result = -1;
+        goto Exit;
+    }
+        
+    entry->state = State_Bound;
+    
+    result = 0;
+    
+Exit:
+    return result;
+}
+
+
+int32_t Sockets_Send(Socket_t socket, uint8_t *data, int32_t length, int32_t flags)
+{
+    int32_t            count = -1;
+    Socket_Entry_t    *entry;
+
+    entry = GetSocketEntry(socket);
+    if (entry == NULL) goto Exit;
+
+    if (entry->protocol == SOCK_DGRAM)
+    {
+        mbedNet_LastError = mbedNetResult_DestinationAddressRequired;
+        goto Exit;
+    }
+
+    mbedNet_LastError = mbedNetResult_NotIplemented;
+
+Exit:
+    return count;
+}
+
+
+int32_t Sockets_SendTo(Socket_t socket, uint8_t *data, int32_t length, int32_t flags, const Socket_Addr_t *remoteAddr, int32_t addrLen)
+{
+    int32_t            count = -1;
+    Socket_Entry_t    *entry;
+
+
+    entry = GetSocketEntry(socket);
+    if (entry == NULL) 
+    {
+        DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("socket not found!"));
+        goto Exit;
+    }
+
+    switch(entry->family)
+    {
+        case AF_INET:
+            switch(entry->protocol)
+            {
+                case SOCK_DGRAM:
+                    if (addrLen != sizeof(Socket_AddrIn_t))
+                    {
+                        DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Invalid socket address length"));
+                        mbedNet_LastError = mbedNetResult_InvalidParameter;
+                        goto Exit;
+                    }
+                    count = SendToUDPv4(entry, data, length, (Socket_AddrIn_t *)remoteAddr);
+                    break;
+                
+                default:
+                    DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Protocol not implemented"));
+                    mbedNet_LastError = mbedNetResult_NotIplemented;
+                    goto Exit;
+            }
+            break;
+            
+        default:
+            DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Protocol family not implemented"));
+            mbedNet_LastError = mbedNetResult_NotIplemented;
+            goto Exit;
+    }
+
+Exit:
+    return count;
+}
+
+
+int32_t Sockets_Recv(Socket_t socket, uint8_t *data, int32_t length, int32_t flags)
+{
+    int32_t                count = -1;
+    Socket_Entry_t        *entry;
+    
+    entry = GetSocketEntry(socket);
+    if (entry == NULL) goto Exit;
+
+    if (Queue_IsEmpty(entry->dataQueue))
+    {
+        mbedNet_LastError = mbedNetResult_WouldBlock;
+        goto Exit;
+    }
+
+    count = Recv_Data(entry, data, length);
+        
+Exit:
+    return count;
+}
+
+
+int32_t Sockets_RecvFrom(Socket_t socket, uint8_t *data, int32_t length, int32_t flags, Socket_Addr_t *remoteAddr, int32_t *addrLen)
+{
+    int32_t            count = -1;
+    Socket_Entry_t    *entry;
+    
+    entry = GetSocketEntry(socket);
+    if (entry == NULL) goto Exit;
+
+    if (Queue_IsEmpty(entry->dataQueue))
+    {
+        mbedNet_LastError = mbedNetResult_WouldBlock;
+        goto Exit;
+    }
+    
+    if (remoteAddr != NULL)
+    {
+        if (entry->localAddr->len > *addrLen)
+        {
+            mbedNet_LastError = mbedNetResult_BufferTooSmall;
+            goto Exit;
+        }
+        memcpy(remoteAddr, entry->remoteAddr, entry->remoteAddr->len);
+    }
+        
+    count = Recv_Data(entry, data, length);
+
+Exit:
+    return count;
+}
+
+
+int32_t Sockets_Close(Socket_t socket)
+{
+    int32_t            result = -1;
+    Socket_Entry_t    *entry;
+    void            *ptr;
+
+    if ((entry = GetSocketEntry(socket)) == NULL) goto Exit;
+    
+    entry->state = State_Close;
+    free(entry->localAddr);
+    entry->localAddr = NULL;
+    free(entry->remoteAddr);
+    entry->remoteAddr = NULL;
+    /* Free pending data blocks */
+    while(Queue_Peek(entry->dataQueue, &ptr) != -1)
+    {
+        free(ptr);
+    }
+    Queue_Free(entry->dataQueue);
+    entry->dataQueue = NULL;
+    result = 0;
+    
+Exit:
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("closed socket %d", socket));
+    return result;
+}
+
+
+
+static Socket_Entry_t *GetSocketEntry(Socket_t socket)
+{
+    Socket_Entry_t    *entry = NULL;
+
+    if ((socket < 0) || (socket >= SOCKET_MAX_COUNT))
+    {
+        DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Invalid socket handle"));
+        mbedNet_LastError = mbedNetResult_InvalidSocketHandle;
+        goto Exit;
+    }
+    entry = socketEntryTable + socket;
+
+    if (entry->state == State_Close)
+    {
+        DEBUG_MODULE(DEBUG_LEVEL_WARNING, ("Socket already closed"));
+        mbedNet_LastError = mbedNetResult_SocketAlreadyClosed;
+        entry = NULL;
+        goto Exit;
+    }
+Exit:
+    return entry;
+}
--- a/Sockets.h	Sun Jun 12 11:23:03 2011 +0000
+++ b/Sockets.h	Sun Jun 12 19:17:11 2011 +0000
@@ -66,13 +66,13 @@
 extern Net_API_t    sockets;
 
 
-CAPI Socket_t    Sockets_Open(Socket_Family_t family, Socket_Protocol_t protocol, int32_t options);
-CAPI int32_t    Sockets_Bind(Socket_t socket, Socket_Addr_t *addr, int32_t addrLen);
-CAPI int32_t    Sockets_Send(Socket_t socket, uint8_t *data, int32_t length, int32_t flags);
-CAPI int32_t    Sockets_SendTo(Socket_t socket, uint8_t *data, int32_t length, int32_t flags, const Socket_Addr_t *remoteAddr, int32_t addrLen);
-CAPI int32_t    Sockets_Recv(Socket_t socket, uint8_t *data, int32_t length, int32_t flags);
-CAPI int32_t    Sockets_RecvFrom(Socket_t socket, uint8_t *data, int32_t length, int32_t flags, Socket_Addr_t *remoteAddr, int32_t *addrLen);
-CAPI int32_t    Sockets_Close(Socket_t socket);
+Socket_t    Sockets_Open(Socket_Family_t family, Socket_Protocol_t protocol, int32_t options);
+int32_t    Sockets_Bind(Socket_t socket, Socket_Addr_t *addr, int32_t addrLen);
+int32_t    Sockets_Send(Socket_t socket, uint8_t *data, int32_t length, int32_t flags);
+int32_t    Sockets_SendTo(Socket_t socket, uint8_t *data, int32_t length, int32_t flags, const Socket_Addr_t *remoteAddr, int32_t addrLen);
+int32_t    Sockets_Recv(Socket_t socket, uint8_t *data, int32_t length, int32_t flags);
+int32_t    Sockets_RecvFrom(Socket_t socket, uint8_t *data, int32_t length, int32_t flags, Socket_Addr_t *remoteAddr, int32_t *addrLen);
+int32_t    Sockets_Close(Socket_t socket);
 
 
 #endif /* __SOCKET_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TCPv4.cpp	Sun Jun 12 19:17:11 2011 +0000
@@ -0,0 +1,98 @@
+/*
+ * $Id: TCPv4.c 29 2011-06-11 14:53:08Z benoit $
+ * $Author: benoit $
+ * $Date: 2011-06-11 16:53:08 +0200 (sam., 11 juin 2011) $
+ * $Rev: 29 $
+ * 
+ * 
+ * 
+ * 
+ * 
+ */
+ 
+#include "TCPv4.h"
+#include "Debug.h"
+
+
+#define	DEBUG_CURRENT_MODULE_NAME	"TCPv4"
+#define	DEBUG_CURRENT_MODULE_ID		DEBUG_MODULE_TCPV4
+
+
+static void Init(void);
+static void Handler(NetIF_t *netIF, Packet_t *packet);
+static int32_t RegisterAPI(Net_API_t *api);
+
+
+Protocol_Handler_t	tcpv4 = 
+{ 
+	PROTOCOL_INDEX_NOT_INITIALIZED, 	/* Always PROTOCOL_INDEX_NOT_INITIALIZED at initialization */
+	Protocol_ID_TCPv4, 					/* Protocol ID */
+	IPV4_PROTO_TCPV4, 					/* Protocol number */
+	Init, 								/* Protocol initialisation function */
+	Handler, 							/* Protocol handler */
+	NULL, 								/* Protocol registration function */
+	RegisterAPI,						/* API registration function */
+};
+
+
+static void Init(void)
+{
+	DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing TCPv4 layer"));
+}
+
+
+static void Handler(NetIF_t *netIF, Packet_t *packet)
+{
+	//TCPv4_Header_t	*tcpv4Header;
+	IPv4_Header_t	*ipv4Header;
+	int32_t			depth;
+	
+	depth = packet->depth;
+	//tcpv4Header = (TCPv4_Header_t *)packet->data;
+	ipv4Header = (IPv4_Header_t *)packet->headerPtrTable[depth];
+	
+	TCPv4_DumpHeader(NULL, ipv4Header);
+	Debug_DumpBufferHex((uint8_t *)ipv4Header, 52);
+}
+
+
+static int32_t RegisterAPI(Net_API_t *api)
+{
+	return -1;
+}
+
+
+void TCPv4_DumpHeader(const char *prefix, IPv4_Header_t *ipv4Header)
+{
+	TCPv4_Header_t	*tcpv4Header = (TCPv4_Header_t *)(ipv4Header + 1);
+
+	DEBUG_RAW(("%sTCPv4 %d.%d.%d.%d:%d --> %d.%d.%d.%d:%d seq:%ld ack:%ld off:%d flags:%c%c%c%c%c%c window:%d crc:%04X ptr:%d",
+		prefix != NULL ? prefix : "",
+		ipv4Header->source.IP0,
+		ipv4Header->source.IP1,
+		ipv4Header->source.IP2,
+		ipv4Header->source.IP3,
+		ntohs(tcpv4Header->sourcePort),
+		ipv4Header->dest.IP0,
+		ipv4Header->dest.IP1,
+		ipv4Header->dest.IP2,
+		ipv4Header->dest.IP3,
+		ntohs(tcpv4Header->destPort),
+		ntohs(tcpv4Header->sequence),
+		ntohs(tcpv4Header->ack),
+		tcpv4Header->offset,
+		
+		tcpv4Header->URG ? 'U' : '-',
+		tcpv4Header->ACK ? 'A' : '-',
+		tcpv4Header->PSH ? 'P' : '-',
+		tcpv4Header->RST ? 'R' : '-',
+		tcpv4Header->SYN ? 'S' : '-',
+		tcpv4Header->FIN ? 'F' : '-',
+		
+		ntohs(tcpv4Header->window),
+		ntohs(tcpv4Header->crc),
+		ntohs(tcpv4Header->pointer)
+		
+	));
+}
+
--- a/UDPv4.c	Sun Jun 12 11:23:03 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-/*
- * $Id: UDPv4.c 29 2011-06-11 14:53:08Z benoit $
- * $Author: benoit $
- * $Date: 2011-06-11 16:53:08 +0200 (sam., 11 juin 2011) $
- * $Rev: 29 $
- * 
- * 
- * 
- * 
- * 
- */
- 
-#include "UDPv4.h"
-#include "NetIF.h"
-#include "Debug.h"
-#include <string.h>
-
-#define    DEBUG_CURRENT_MODULE_NAME    "UDPv4"
-#define    DEBUG_CURRENT_MODULE_ID        DEBUG_MODULE_UDPV4
-
-
-static void Init(void);
-static void Handler(NetIF_t *netIF, Packet_t *packet);
-static int32_t RegisterAPI(Net_API_t *api);
-
-
-Protocol_Handler_t    udpv4 = 
-{
-    PROTOCOL_INDEX_NOT_INITIALIZED,         /* Always PROTOCOL_INDEX_NOT_INITIALIZED at initialization */
-    Protocol_ID_UDPv4,                         /* Protocol ID */
-    IPV4_PROTO_UDPV4,                         /* Protocol number */
-    Init,                                     /* Protocol initialisation function */
-    Handler,                                /* Protocol handler */
-    NULL,                                     /* Protocol registration function */
-    RegisterAPI,                            /* API registration function */
-};
-
-
-static Net_API_t    *netAPITable[NET_API_PER_PROTOCOL_MAX_COUNT];
-static int32_t        netAPICount = 0;
-
-
-static void Init(void)
-{
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing UDPv4 layer"));
-    memset(netAPITable, 0, sizeof(netAPITable));
-    netAPICount = 0;
-}
-
-
-static void Handler(NetIF_t *netIF, Packet_t *packet)
-{
-    IPv4_Header_t    *ipv4Header;
-    int32_t            depth, index;
-    
-    for (index = 0; index < netAPICount; index++)
-    {
-        netAPITable[index]->Hook(netIF, Protocol_ID_UDPv4, packet);
-    }
-        
-    depth = packet->depth;
-    ipv4Header = (IPv4_Header_t *)packet->headerPtrTable[depth];
-    
-    DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE1)
-    {
-        UDPv4_DumpHeader(NULL, ipv4Header);
-    }
-}
-
-
-static int32_t RegisterAPI(Net_API_t *netAPI)
-{
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Registering %s API", api_IDNames[netAPI->apiID]));
-    netAPI->InitAPI();
-    netAPITable[netAPICount] = netAPI;
-    netAPICount++;
-    return -1;
-}
-
-
-void UDPv4_DumpHeader(const char *prefix, IPv4_Header_t *ipv4Header)
-{
-    UDPv4_Header_t    *udpv4Header = (UDPv4_Header_t *)(ipv4Header + 1);
-
-    DEBUG_RAW(("%sUDPv4 %d.%d.%d.%d:%d --> %d.%d.%d.%d:%d  length:%d crc:%04X" ,
-        prefix != NULL ? prefix : "",
-        ipv4Header->source.IP0,
-        ipv4Header->source.IP1,
-        ipv4Header->source.IP2,
-        ipv4Header->source.IP3,
-        ntohs(udpv4Header->sourcePort),
-        ipv4Header->dest.IP0,
-        ipv4Header->dest.IP1,
-        ipv4Header->dest.IP2,
-        ipv4Header->dest.IP3,
-        ntohs(udpv4Header->destPort),
-        ntohs(udpv4Header->length),
-        ntohs(udpv4Header->crc)
-    ));
-    
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UDPv4.cpp	Sun Jun 12 19:17:11 2011 +0000
@@ -0,0 +1,102 @@
+/*
+ * $Id: UDPv4.c 29 2011-06-11 14:53:08Z benoit $
+ * $Author: benoit $
+ * $Date: 2011-06-11 16:53:08 +0200 (sam., 11 juin 2011) $
+ * $Rev: 29 $
+ * 
+ * 
+ * 
+ * 
+ * 
+ */
+ 
+#include "UDPv4.h"
+#include "NetIF.h"
+#include "Debug.h"
+#include <string.h>
+
+#define    DEBUG_CURRENT_MODULE_NAME    "UDPv4"
+#define    DEBUG_CURRENT_MODULE_ID        DEBUG_MODULE_UDPV4
+
+
+static void Init(void);
+static void Handler(NetIF_t *netIF, Packet_t *packet);
+static int32_t RegisterAPI(Net_API_t *api);
+
+
+Protocol_Handler_t    udpv4 = 
+{
+    PROTOCOL_INDEX_NOT_INITIALIZED,         /* Always PROTOCOL_INDEX_NOT_INITIALIZED at initialization */
+    Protocol_ID_UDPv4,                         /* Protocol ID */
+    IPV4_PROTO_UDPV4,                         /* Protocol number */
+    Init,                                     /* Protocol initialisation function */
+    Handler,                                /* Protocol handler */
+    NULL,                                     /* Protocol registration function */
+    RegisterAPI,                            /* API registration function */
+};
+
+
+static Net_API_t    *netAPITable[NET_API_PER_PROTOCOL_MAX_COUNT];
+static int32_t        netAPICount = 0;
+
+
+static void Init(void)
+{
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing UDPv4 layer"));
+    memset(netAPITable, 0, sizeof(netAPITable));
+    netAPICount = 0;
+}
+
+
+static void Handler(NetIF_t *netIF, Packet_t *packet)
+{
+    IPv4_Header_t    *ipv4Header;
+    int32_t            depth, index;
+    
+    for (index = 0; index < netAPICount; index++)
+    {
+        netAPITable[index]->Hook(netIF, Protocol_ID_UDPv4, packet);
+    }
+        
+    depth = packet->depth;
+    ipv4Header = (IPv4_Header_t *)packet->headerPtrTable[depth];
+    
+    DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE1)
+    {
+        UDPv4_DumpHeader(NULL, ipv4Header);
+    }
+}
+
+
+static int32_t RegisterAPI(Net_API_t *netAPI)
+{
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Registering %s API", api_IDNames[netAPI->apiID]));
+    netAPI->InitAPI();
+    netAPITable[netAPICount] = netAPI;
+    netAPICount++;
+    return -1;
+}
+
+
+void UDPv4_DumpHeader(const char *prefix, IPv4_Header_t *ipv4Header)
+{
+    UDPv4_Header_t    *udpv4Header = (UDPv4_Header_t *)(ipv4Header + 1);
+
+    DEBUG_RAW(("%sUDPv4 %d.%d.%d.%d:%d --> %d.%d.%d.%d:%d  length:%d crc:%04X" ,
+        prefix != NULL ? prefix : "",
+        ipv4Header->source.IP0,
+        ipv4Header->source.IP1,
+        ipv4Header->source.IP2,
+        ipv4Header->source.IP3,
+        ntohs(udpv4Header->sourcePort),
+        ipv4Header->dest.IP0,
+        ipv4Header->dest.IP1,
+        ipv4Header->dest.IP2,
+        ipv4Header->dest.IP3,
+        ntohs(udpv4Header->destPort),
+        ntohs(udpv4Header->length),
+        ntohs(udpv4Header->crc)
+    ));
+    
+}
+
--- a/UDPv4.h	Sun Jun 12 11:23:03 2011 +0000
+++ b/UDPv4.h	Sun Jun 12 19:17:11 2011 +0000
@@ -34,7 +34,7 @@
 extern Protocol_Handler_t udpv4;
 
 
-CAPI void UDPv4_DumpHeader(const char *prefix, IPv4_Header_t *ipv4Header);
+void UDPv4_DumpHeader(const char *prefix, IPv4_Header_t *ipv4Header);
 
 
 #endif /* __UDPV4_H__ */
--- a/lpc17xx_clkpwr.c	Sun Jun 12 11:23:03 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,338 +0,0 @@
-/***********************************************************************//**
- * @file		lpc17xx_clkpwr.c
- * @brief		Contains all functions support for Clock and Power Control
- * 				firmware library on LPC17xx
- * @version		3.0
- * @date		18. June. 2010
- * @author		NXP MCU SW Application Team
- **************************************************************************
- * Software that is described herein is for illustrative purposes only
- * which provides customers with programming information regarding the
- * products. This software is supplied "AS IS" without any warranties.
- * NXP Semiconductors assumes no responsibility or liability for the
- * use of the software, conveys no license or title under any patent,
- * copyright, or mask work right to the product. NXP Semiconductors
- * reserves the right to make changes in the software without
- * notification. NXP Semiconductors also make no representation or
- * warranty that such application will be suitable for the specified
- * use without further testing or modification.
- **********************************************************************/
-
-/* Peripheral group ----------------------------------------------------------- */
-/** @addtogroup CLKPWR
- * @{
- */
-
-/* Includes ------------------------------------------------------------------- */
-#include "lpc17xx_clkpwr.h"
-
-
-/* Public Functions ----------------------------------------------------------- */
-/** @addtogroup CLKPWR_Public_Functions
- * @{
- */
-
-/*********************************************************************//**
- * @brief 		Set value of each Peripheral Clock Selection
- * @param[in]	ClkType	Peripheral Clock Selection of each type,
- * 				should be one of the following:
- *				- CLKPWR_PCLKSEL_WDT   		: WDT
-				- CLKPWR_PCLKSEL_TIMER0   	: Timer 0
-				- CLKPWR_PCLKSEL_TIMER1   	: Timer 1
-				- CLKPWR_PCLKSEL_UART0   	: UART 0
-				- CLKPWR_PCLKSEL_UART1  	: UART 1
-				- CLKPWR_PCLKSEL_PWM1   	: PWM 1
-				- CLKPWR_PCLKSEL_I2C0   	: I2C 0
-				- CLKPWR_PCLKSEL_SPI   		: SPI
-				- CLKPWR_PCLKSEL_SSP1   	: SSP 1
-				- CLKPWR_PCLKSEL_DAC   		: DAC
-				- CLKPWR_PCLKSEL_ADC   		: ADC
-				- CLKPWR_PCLKSEL_CAN1  		: CAN 1
-				- CLKPWR_PCLKSEL_CAN2  		: CAN 2
-				- CLKPWR_PCLKSEL_ACF   		: ACF
-				- CLKPWR_PCLKSEL_QEI 		: QEI
-				- CLKPWR_PCLKSEL_PCB   		: PCB
-				- CLKPWR_PCLKSEL_I2C1   	: I2C 1
-				- CLKPWR_PCLKSEL_SSP0   	: SSP 0
-				- CLKPWR_PCLKSEL_TIMER2   	: Timer 2
-				- CLKPWR_PCLKSEL_TIMER3   	: Timer 3
-				- CLKPWR_PCLKSEL_UART2   	: UART 2
-				- CLKPWR_PCLKSEL_UART3   	: UART 3
-				- CLKPWR_PCLKSEL_I2C2   	: I2C 2
-				- CLKPWR_PCLKSEL_I2S   		: I2S
-				- CLKPWR_PCLKSEL_RIT   		: RIT
-				- CLKPWR_PCLKSEL_SYSCON   	: SYSCON
-				- CLKPWR_PCLKSEL_MC 		: MC
-
- * @param[in]	DivVal	Value of divider, should be:
- * 				- CLKPWR_PCLKSEL_CCLK_DIV_4 : PCLK_peripheral = CCLK/4
- * 				- CLKPWR_PCLKSEL_CCLK_DIV_1 : PCLK_peripheral = CCLK/1
- *				- CLKPWR_PCLKSEL_CCLK_DIV_2 : PCLK_peripheral = CCLK/2
- *
- * @return none
- **********************************************************************/
-void CLKPWR_SetPCLKDiv (uint32_t ClkType, uint32_t DivVal)
-{
-	uint32_t bitpos;
-
-	bitpos = (ClkType < 32) ? (ClkType) : (ClkType - 32);
-
-	/* PCLKSEL0 selected */
-	if (ClkType < 32)
-	{
-		/* Clear two bit at bit position */
-		LPC_SC->PCLKSEL0 &= (~(CLKPWR_PCLKSEL_BITMASK(bitpos)));
-
-		/* Set two selected bit */
-		LPC_SC->PCLKSEL0 |= (CLKPWR_PCLKSEL_SET(bitpos, DivVal));
-	}
-	/* PCLKSEL1 selected */
-	else
-	{
-		/* Clear two bit at bit position */
-		LPC_SC->PCLKSEL1 &= ~(CLKPWR_PCLKSEL_BITMASK(bitpos));
-
-		/* Set two selected bit */
-		LPC_SC->PCLKSEL1 |= (CLKPWR_PCLKSEL_SET(bitpos, DivVal));
-	}
-}
-
-
-/*********************************************************************//**
- * @brief		Get current value of each Peripheral Clock Selection
- * @param[in]	ClkType	Peripheral Clock Selection of each type,
- * 				should be one of the following:
- *				- CLKPWR_PCLKSEL_WDT   		: WDT
-				- CLKPWR_PCLKSEL_TIMER0   	: Timer 0
-				- CLKPWR_PCLKSEL_TIMER1   	: Timer 1
-				- CLKPWR_PCLKSEL_UART0   	: UART 0
-				- CLKPWR_PCLKSEL_UART1  	: UART 1
-				- CLKPWR_PCLKSEL_PWM1   	: PWM 1
-				- CLKPWR_PCLKSEL_I2C0   	: I2C 0
-				- CLKPWR_PCLKSEL_SPI   		: SPI
-				- CLKPWR_PCLKSEL_SSP1   	: SSP 1
-				- CLKPWR_PCLKSEL_DAC   		: DAC
-				- CLKPWR_PCLKSEL_ADC   		: ADC
-				- CLKPWR_PCLKSEL_CAN1  		: CAN 1
-				- CLKPWR_PCLKSEL_CAN2  		: CAN 2
-				- CLKPWR_PCLKSEL_ACF   		: ACF
-				- CLKPWR_PCLKSEL_QEI 		: QEI
-				- CLKPWR_PCLKSEL_PCB   		: PCB
-				- CLKPWR_PCLKSEL_I2C1   	: I2C 1
-				- CLKPWR_PCLKSEL_SSP0   	: SSP 0
-				- CLKPWR_PCLKSEL_TIMER2   	: Timer 2
-				- CLKPWR_PCLKSEL_TIMER3   	: Timer 3
-				- CLKPWR_PCLKSEL_UART2   	: UART 2
-				- CLKPWR_PCLKSEL_UART3   	: UART 3
-				- CLKPWR_PCLKSEL_I2C2   	: I2C 2
-				- CLKPWR_PCLKSEL_I2S   		: I2S
-				- CLKPWR_PCLKSEL_RIT   		: RIT
-				- CLKPWR_PCLKSEL_SYSCON   	: SYSCON
-				- CLKPWR_PCLKSEL_MC 		: MC
-
- * @return		Value of Selected Peripheral Clock Selection
- **********************************************************************/
-uint32_t CLKPWR_GetPCLKSEL (uint32_t ClkType)
-{
-	uint32_t bitpos, retval;
-
-	if (ClkType < 32)
-	{
-		bitpos = ClkType;
-		retval = LPC_SC->PCLKSEL0;
-	}
-	else
-	{
-		bitpos = ClkType - 32;
-		retval = LPC_SC->PCLKSEL1;
-	}
-
-	retval = CLKPWR_PCLKSEL_GET(bitpos, retval);
-	return retval;
-}
-
-
-
-/*********************************************************************//**
- * @brief 		Get current value of each Peripheral Clock
- * @param[in]	ClkType	Peripheral Clock Selection of each type,
- * 				should be one of the following:
- *				- CLKPWR_PCLKSEL_WDT   		: WDT
-				- CLKPWR_PCLKSEL_TIMER0   	: Timer 0
-				- CLKPWR_PCLKSEL_TIMER1   	: Timer 1
-				- CLKPWR_PCLKSEL_UART0   	: UART 0
-				- CLKPWR_PCLKSEL_UART1  	: UART 1
-				- CLKPWR_PCLKSEL_PWM1   	: PWM 1
-				- CLKPWR_PCLKSEL_I2C0   	: I2C 0
-				- CLKPWR_PCLKSEL_SPI   		: SPI
-				- CLKPWR_PCLKSEL_SSP1   	: SSP 1
-				- CLKPWR_PCLKSEL_DAC   		: DAC
-				- CLKPWR_PCLKSEL_ADC   		: ADC
-				- CLKPWR_PCLKSEL_CAN1  		: CAN 1
-				- CLKPWR_PCLKSEL_CAN2  		: CAN 2
-				- CLKPWR_PCLKSEL_ACF   		: ACF
-				- CLKPWR_PCLKSEL_QEI 		: QEI
-				- CLKPWR_PCLKSEL_PCB   		: PCB
-				- CLKPWR_PCLKSEL_I2C1   	: I2C 1
-				- CLKPWR_PCLKSEL_SSP0   	: SSP 0
-				- CLKPWR_PCLKSEL_TIMER2   	: Timer 2
-				- CLKPWR_PCLKSEL_TIMER3   	: Timer 3
-				- CLKPWR_PCLKSEL_UART2   	: UART 2
-				- CLKPWR_PCLKSEL_UART3   	: UART 3
-				- CLKPWR_PCLKSEL_I2C2   	: I2C 2
-				- CLKPWR_PCLKSEL_I2S   		: I2S
-				- CLKPWR_PCLKSEL_RIT   		: RIT
-				- CLKPWR_PCLKSEL_SYSCON   	: SYSCON
-				- CLKPWR_PCLKSEL_MC 		: MC
-
- * @return		Value of Selected Peripheral Clock
- **********************************************************************/
-uint32_t CLKPWR_GetPCLK (uint32_t ClkType)
-{
-	uint32_t retval, div;
-
-	retval = SystemCoreClock;
-	div = CLKPWR_GetPCLKSEL(ClkType);
-
-	switch (div)
-	{
-	case 0:
-		div = 4;
-		break;
-
-	case 1:
-		div = 1;
-		break;
-
-	case 2:
-		div = 2;
-		break;
-
-	case 3:
-		div = 8;
-		break;
-	}
-	retval /= div;
-
-	return retval;
-}
-
-
-
-/*********************************************************************//**
- * @brief 		Configure power supply for each peripheral according to NewState
- * @param[in]	PPType	Type of peripheral used to enable power,
- *     					should be one of the following:
- *     			-  CLKPWR_PCONP_PCTIM0 		: Timer 0
-				-  CLKPWR_PCONP_PCTIM1 		: Timer 1
-				-  CLKPWR_PCONP_PCUART0  	: UART 0
-				-  CLKPWR_PCONP_PCUART1   	: UART 1
-				-  CLKPWR_PCONP_PCPWM1 		: PWM 1
-				-  CLKPWR_PCONP_PCI2C0 		: I2C 0
-				-  CLKPWR_PCONP_PCSPI   	: SPI
-				-  CLKPWR_PCONP_PCRTC   	: RTC
-				-  CLKPWR_PCONP_PCSSP1 		: SSP 1
-				-  CLKPWR_PCONP_PCAD   		: ADC
-				-  CLKPWR_PCONP_PCAN1   	: CAN 1
-				-  CLKPWR_PCONP_PCAN2   	: CAN 2
-				-  CLKPWR_PCONP_PCGPIO 		: GPIO
-				-  CLKPWR_PCONP_PCRIT 		: RIT
-				-  CLKPWR_PCONP_PCMC 		: MC
-				-  CLKPWR_PCONP_PCQEI 		: QEI
-				-  CLKPWR_PCONP_PCI2C1   	: I2C 1
-				-  CLKPWR_PCONP_PCSSP0 		: SSP 0
-				-  CLKPWR_PCONP_PCTIM2 		: Timer 2
-				-  CLKPWR_PCONP_PCTIM3 		: Timer 3
-				-  CLKPWR_PCONP_PCUART2  	: UART 2
-				-  CLKPWR_PCONP_PCUART3   	: UART 3
-				-  CLKPWR_PCONP_PCI2C2 		: I2C 2
-				-  CLKPWR_PCONP_PCI2S   	: I2S
-				-  CLKPWR_PCONP_PCGPDMA   	: GPDMA
-				-  CLKPWR_PCONP_PCENET 		: Ethernet
-				-  CLKPWR_PCONP_PCUSB   	: USB
- *
- * @param[in]	NewState	New state of Peripheral Power, should be:
- * 				- ENABLE	: Enable power for this peripheral
- * 				- DISABLE	: Disable power for this peripheral
- *
- * @return none
- **********************************************************************/
-void CLKPWR_ConfigPPWR (uint32_t PPType, FunctionalState NewState)
-{
-	if (NewState == ENABLE)
-	{
-		LPC_SC->PCONP |= PPType & CLKPWR_PCONP_BITMASK;
-	}
-	else if (NewState == DISABLE)
-	{
-		LPC_SC->PCONP &= (~PPType) & CLKPWR_PCONP_BITMASK;
-	}
-}
-
-
-/*********************************************************************//**
- * @brief 		Enter Sleep mode with co-operated instruction by the Cortex-M3.
- * @param[in]	None
- * @return		None
- **********************************************************************/
-void CLKPWR_Sleep(void)
-{
-	LPC_SC->PCON = 0x00;
-	/* Sleep Mode*/
-	__WFI();
-}
-
-
-/*********************************************************************//**
- * @brief 		Enter Deep Sleep mode with co-operated instruction by the Cortex-M3.
- * @param[in]	None
- * @return		None
- **********************************************************************/
-void CLKPWR_DeepSleep(void)
-{
-    /* Deep-Sleep Mode, set SLEEPDEEP bit */
-	SCB->SCR = 0x4;
-	LPC_SC->PCON = 0x8;
-	/* Deep Sleep Mode*/
-	__WFI();
-}
-
-
-/*********************************************************************//**
- * @brief 		Enter Power Down mode with co-operated instruction by the Cortex-M3.
- * @param[in]	None
- * @return		None
- **********************************************************************/
-void CLKPWR_PowerDown(void)
-{
-    /* Deep-Sleep Mode, set SLEEPDEEP bit */
-	SCB->SCR = 0x4;
-	LPC_SC->PCON = 0x09;
-	/* Power Down Mode*/
-	__WFI();
-}
-
-
-/*********************************************************************//**
- * @brief 		Enter Deep Power Down mode with co-operated instruction by the Cortex-M3.
- * @param[in]	None
- * @return		None
- **********************************************************************/
-void CLKPWR_DeepPowerDown(void)
-{
-    /* Deep-Sleep Mode, set SLEEPDEEP bit */
-	SCB->SCR = 0x4;
-	LPC_SC->PCON = 0x03;
-	/* Deep Power Down Mode*/
-	__WFI();
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* --------------------------------- End Of File ------------------------------ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lpc17xx_clkpwr.cpp	Sun Jun 12 19:17:11 2011 +0000
@@ -0,0 +1,338 @@
+/***********************************************************************//**
+ * @file		lpc17xx_clkpwr.c
+ * @brief		Contains all functions support for Clock and Power Control
+ * 				firmware library on LPC17xx
+ * @version		3.0
+ * @date		18. June. 2010
+ * @author		NXP MCU SW Application Team
+ **************************************************************************
+ * Software that is described herein is for illustrative purposes only
+ * which provides customers with programming information regarding the
+ * products. This software is supplied "AS IS" without any warranties.
+ * NXP Semiconductors assumes no responsibility or liability for the
+ * use of the software, conveys no license or title under any patent,
+ * copyright, or mask work right to the product. NXP Semiconductors
+ * reserves the right to make changes in the software without
+ * notification. NXP Semiconductors also make no representation or
+ * warranty that such application will be suitable for the specified
+ * use without further testing or modification.
+ **********************************************************************/
+
+/* Peripheral group ----------------------------------------------------------- */
+/** @addtogroup CLKPWR
+ * @{
+ */
+
+/* Includes ------------------------------------------------------------------- */
+#include "lpc17xx_clkpwr.h"
+
+
+/* Public Functions ----------------------------------------------------------- */
+/** @addtogroup CLKPWR_Public_Functions
+ * @{
+ */
+
+/*********************************************************************//**
+ * @brief 		Set value of each Peripheral Clock Selection
+ * @param[in]	ClkType	Peripheral Clock Selection of each type,
+ * 				should be one of the following:
+ *				- CLKPWR_PCLKSEL_WDT   		: WDT
+				- CLKPWR_PCLKSEL_TIMER0   	: Timer 0
+				- CLKPWR_PCLKSEL_TIMER1   	: Timer 1
+				- CLKPWR_PCLKSEL_UART0   	: UART 0
+				- CLKPWR_PCLKSEL_UART1  	: UART 1
+				- CLKPWR_PCLKSEL_PWM1   	: PWM 1
+				- CLKPWR_PCLKSEL_I2C0   	: I2C 0
+				- CLKPWR_PCLKSEL_SPI   		: SPI
+				- CLKPWR_PCLKSEL_SSP1   	: SSP 1
+				- CLKPWR_PCLKSEL_DAC   		: DAC
+				- CLKPWR_PCLKSEL_ADC   		: ADC
+				- CLKPWR_PCLKSEL_CAN1  		: CAN 1
+				- CLKPWR_PCLKSEL_CAN2  		: CAN 2
+				- CLKPWR_PCLKSEL_ACF   		: ACF
+				- CLKPWR_PCLKSEL_QEI 		: QEI
+				- CLKPWR_PCLKSEL_PCB   		: PCB
+				- CLKPWR_PCLKSEL_I2C1   	: I2C 1
+				- CLKPWR_PCLKSEL_SSP0   	: SSP 0
+				- CLKPWR_PCLKSEL_TIMER2   	: Timer 2
+				- CLKPWR_PCLKSEL_TIMER3   	: Timer 3
+				- CLKPWR_PCLKSEL_UART2   	: UART 2
+				- CLKPWR_PCLKSEL_UART3   	: UART 3
+				- CLKPWR_PCLKSEL_I2C2   	: I2C 2
+				- CLKPWR_PCLKSEL_I2S   		: I2S
+				- CLKPWR_PCLKSEL_RIT   		: RIT
+				- CLKPWR_PCLKSEL_SYSCON   	: SYSCON
+				- CLKPWR_PCLKSEL_MC 		: MC
+
+ * @param[in]	DivVal	Value of divider, should be:
+ * 				- CLKPWR_PCLKSEL_CCLK_DIV_4 : PCLK_peripheral = CCLK/4
+ * 				- CLKPWR_PCLKSEL_CCLK_DIV_1 : PCLK_peripheral = CCLK/1
+ *				- CLKPWR_PCLKSEL_CCLK_DIV_2 : PCLK_peripheral = CCLK/2
+ *
+ * @return none
+ **********************************************************************/
+void CLKPWR_SetPCLKDiv (uint32_t ClkType, uint32_t DivVal)
+{
+	uint32_t bitpos;
+
+	bitpos = (ClkType < 32) ? (ClkType) : (ClkType - 32);
+
+	/* PCLKSEL0 selected */
+	if (ClkType < 32)
+	{
+		/* Clear two bit at bit position */
+		LPC_SC->PCLKSEL0 &= (~(CLKPWR_PCLKSEL_BITMASK(bitpos)));
+
+		/* Set two selected bit */
+		LPC_SC->PCLKSEL0 |= (CLKPWR_PCLKSEL_SET(bitpos, DivVal));
+	}
+	/* PCLKSEL1 selected */
+	else
+	{
+		/* Clear two bit at bit position */
+		LPC_SC->PCLKSEL1 &= ~(CLKPWR_PCLKSEL_BITMASK(bitpos));
+
+		/* Set two selected bit */
+		LPC_SC->PCLKSEL1 |= (CLKPWR_PCLKSEL_SET(bitpos, DivVal));
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Get current value of each Peripheral Clock Selection
+ * @param[in]	ClkType	Peripheral Clock Selection of each type,
+ * 				should be one of the following:
+ *				- CLKPWR_PCLKSEL_WDT   		: WDT
+				- CLKPWR_PCLKSEL_TIMER0   	: Timer 0
+				- CLKPWR_PCLKSEL_TIMER1   	: Timer 1
+				- CLKPWR_PCLKSEL_UART0   	: UART 0
+				- CLKPWR_PCLKSEL_UART1  	: UART 1
+				- CLKPWR_PCLKSEL_PWM1   	: PWM 1
+				- CLKPWR_PCLKSEL_I2C0   	: I2C 0
+				- CLKPWR_PCLKSEL_SPI   		: SPI
+				- CLKPWR_PCLKSEL_SSP1   	: SSP 1
+				- CLKPWR_PCLKSEL_DAC   		: DAC
+				- CLKPWR_PCLKSEL_ADC   		: ADC
+				- CLKPWR_PCLKSEL_CAN1  		: CAN 1
+				- CLKPWR_PCLKSEL_CAN2  		: CAN 2
+				- CLKPWR_PCLKSEL_ACF   		: ACF
+				- CLKPWR_PCLKSEL_QEI 		: QEI
+				- CLKPWR_PCLKSEL_PCB   		: PCB
+				- CLKPWR_PCLKSEL_I2C1   	: I2C 1
+				- CLKPWR_PCLKSEL_SSP0   	: SSP 0
+				- CLKPWR_PCLKSEL_TIMER2   	: Timer 2
+				- CLKPWR_PCLKSEL_TIMER3   	: Timer 3
+				- CLKPWR_PCLKSEL_UART2   	: UART 2
+				- CLKPWR_PCLKSEL_UART3   	: UART 3
+				- CLKPWR_PCLKSEL_I2C2   	: I2C 2
+				- CLKPWR_PCLKSEL_I2S   		: I2S
+				- CLKPWR_PCLKSEL_RIT   		: RIT
+				- CLKPWR_PCLKSEL_SYSCON   	: SYSCON
+				- CLKPWR_PCLKSEL_MC 		: MC
+
+ * @return		Value of Selected Peripheral Clock Selection
+ **********************************************************************/
+uint32_t CLKPWR_GetPCLKSEL (uint32_t ClkType)
+{
+	uint32_t bitpos, retval;
+
+	if (ClkType < 32)
+	{
+		bitpos = ClkType;
+		retval = LPC_SC->PCLKSEL0;
+	}
+	else
+	{
+		bitpos = ClkType - 32;
+		retval = LPC_SC->PCLKSEL1;
+	}
+
+	retval = CLKPWR_PCLKSEL_GET(bitpos, retval);
+	return retval;
+}
+
+
+
+/*********************************************************************//**
+ * @brief 		Get current value of each Peripheral Clock
+ * @param[in]	ClkType	Peripheral Clock Selection of each type,
+ * 				should be one of the following:
+ *				- CLKPWR_PCLKSEL_WDT   		: WDT
+				- CLKPWR_PCLKSEL_TIMER0   	: Timer 0
+				- CLKPWR_PCLKSEL_TIMER1   	: Timer 1
+				- CLKPWR_PCLKSEL_UART0   	: UART 0
+				- CLKPWR_PCLKSEL_UART1  	: UART 1
+				- CLKPWR_PCLKSEL_PWM1   	: PWM 1
+				- CLKPWR_PCLKSEL_I2C0   	: I2C 0
+				- CLKPWR_PCLKSEL_SPI   		: SPI
+				- CLKPWR_PCLKSEL_SSP1   	: SSP 1
+				- CLKPWR_PCLKSEL_DAC   		: DAC
+				- CLKPWR_PCLKSEL_ADC   		: ADC
+				- CLKPWR_PCLKSEL_CAN1  		: CAN 1
+				- CLKPWR_PCLKSEL_CAN2  		: CAN 2
+				- CLKPWR_PCLKSEL_ACF   		: ACF
+				- CLKPWR_PCLKSEL_QEI 		: QEI
+				- CLKPWR_PCLKSEL_PCB   		: PCB
+				- CLKPWR_PCLKSEL_I2C1   	: I2C 1
+				- CLKPWR_PCLKSEL_SSP0   	: SSP 0
+				- CLKPWR_PCLKSEL_TIMER2   	: Timer 2
+				- CLKPWR_PCLKSEL_TIMER3   	: Timer 3
+				- CLKPWR_PCLKSEL_UART2   	: UART 2
+				- CLKPWR_PCLKSEL_UART3   	: UART 3
+				- CLKPWR_PCLKSEL_I2C2   	: I2C 2
+				- CLKPWR_PCLKSEL_I2S   		: I2S
+				- CLKPWR_PCLKSEL_RIT   		: RIT
+				- CLKPWR_PCLKSEL_SYSCON   	: SYSCON
+				- CLKPWR_PCLKSEL_MC 		: MC
+
+ * @return		Value of Selected Peripheral Clock
+ **********************************************************************/
+uint32_t CLKPWR_GetPCLK (uint32_t ClkType)
+{
+	uint32_t retval, div;
+
+	retval = SystemCoreClock;
+	div = CLKPWR_GetPCLKSEL(ClkType);
+
+	switch (div)
+	{
+	case 0:
+		div = 4;
+		break;
+
+	case 1:
+		div = 1;
+		break;
+
+	case 2:
+		div = 2;
+		break;
+
+	case 3:
+		div = 8;
+		break;
+	}
+	retval /= div;
+
+	return retval;
+}
+
+
+
+/*********************************************************************//**
+ * @brief 		Configure power supply for each peripheral according to NewState
+ * @param[in]	PPType	Type of peripheral used to enable power,
+ *     					should be one of the following:
+ *     			-  CLKPWR_PCONP_PCTIM0 		: Timer 0
+				-  CLKPWR_PCONP_PCTIM1 		: Timer 1
+				-  CLKPWR_PCONP_PCUART0  	: UART 0
+				-  CLKPWR_PCONP_PCUART1   	: UART 1
+				-  CLKPWR_PCONP_PCPWM1 		: PWM 1
+				-  CLKPWR_PCONP_PCI2C0 		: I2C 0
+				-  CLKPWR_PCONP_PCSPI   	: SPI
+				-  CLKPWR_PCONP_PCRTC   	: RTC
+				-  CLKPWR_PCONP_PCSSP1 		: SSP 1
+				-  CLKPWR_PCONP_PCAD   		: ADC
+				-  CLKPWR_PCONP_PCAN1   	: CAN 1
+				-  CLKPWR_PCONP_PCAN2   	: CAN 2
+				-  CLKPWR_PCONP_PCGPIO 		: GPIO
+				-  CLKPWR_PCONP_PCRIT 		: RIT
+				-  CLKPWR_PCONP_PCMC 		: MC
+				-  CLKPWR_PCONP_PCQEI 		: QEI
+				-  CLKPWR_PCONP_PCI2C1   	: I2C 1
+				-  CLKPWR_PCONP_PCSSP0 		: SSP 0
+				-  CLKPWR_PCONP_PCTIM2 		: Timer 2
+				-  CLKPWR_PCONP_PCTIM3 		: Timer 3
+				-  CLKPWR_PCONP_PCUART2  	: UART 2
+				-  CLKPWR_PCONP_PCUART3   	: UART 3
+				-  CLKPWR_PCONP_PCI2C2 		: I2C 2
+				-  CLKPWR_PCONP_PCI2S   	: I2S
+				-  CLKPWR_PCONP_PCGPDMA   	: GPDMA
+				-  CLKPWR_PCONP_PCENET 		: Ethernet
+				-  CLKPWR_PCONP_PCUSB   	: USB
+ *
+ * @param[in]	NewState	New state of Peripheral Power, should be:
+ * 				- ENABLE	: Enable power for this peripheral
+ * 				- DISABLE	: Disable power for this peripheral
+ *
+ * @return none
+ **********************************************************************/
+void CLKPWR_ConfigPPWR (uint32_t PPType, FunctionalState NewState)
+{
+	if (NewState == ENABLE)
+	{
+		LPC_SC->PCONP |= PPType & CLKPWR_PCONP_BITMASK;
+	}
+	else if (NewState == DISABLE)
+	{
+		LPC_SC->PCONP &= (~PPType) & CLKPWR_PCONP_BITMASK;
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief 		Enter Sleep mode with co-operated instruction by the Cortex-M3.
+ * @param[in]	None
+ * @return		None
+ **********************************************************************/
+void CLKPWR_Sleep(void)
+{
+	LPC_SC->PCON = 0x00;
+	/* Sleep Mode*/
+	__WFI();
+}
+
+
+/*********************************************************************//**
+ * @brief 		Enter Deep Sleep mode with co-operated instruction by the Cortex-M3.
+ * @param[in]	None
+ * @return		None
+ **********************************************************************/
+void CLKPWR_DeepSleep(void)
+{
+    /* Deep-Sleep Mode, set SLEEPDEEP bit */
+	SCB->SCR = 0x4;
+	LPC_SC->PCON = 0x8;
+	/* Deep Sleep Mode*/
+	__WFI();
+}
+
+
+/*********************************************************************//**
+ * @brief 		Enter Power Down mode with co-operated instruction by the Cortex-M3.
+ * @param[in]	None
+ * @return		None
+ **********************************************************************/
+void CLKPWR_PowerDown(void)
+{
+    /* Deep-Sleep Mode, set SLEEPDEEP bit */
+	SCB->SCR = 0x4;
+	LPC_SC->PCON = 0x09;
+	/* Power Down Mode*/
+	__WFI();
+}
+
+
+/*********************************************************************//**
+ * @brief 		Enter Deep Power Down mode with co-operated instruction by the Cortex-M3.
+ * @param[in]	None
+ * @return		None
+ **********************************************************************/
+void CLKPWR_DeepPowerDown(void)
+{
+    /* Deep-Sleep Mode, set SLEEPDEEP bit */
+	SCB->SCR = 0x4;
+	LPC_SC->PCON = 0x03;
+	/* Deep Power Down Mode*/
+	__WFI();
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
--- a/lpc17xx_clkpwr.h	Sun Jun 12 11:23:03 2011 +0000
+++ b/lpc17xx_clkpwr.h	Sun Jun 12 19:17:11 2011 +0000
@@ -100,9 +100,9 @@
 #define    CLKPWR_PCLKSEL_MC              ((uint32_t)(62))
 
 /** Macro for Peripheral Clock Selection register bit values
- * Note: When CCLK_DIV_8, Peripheral�s clock is selected to
+ * Note: When CCLK_DIV_8, Peripheral�s clock is selected to
  * PCLK_xyz = CCLK/8 except for CAN1, CAN2, and CAN filtering
- * when �11�selects PCLK_xyz = CCLK/6 */
+ * when �11�selects PCLK_xyz = CCLK/6 */
 /* Peripheral clock divider is set to 4 from CCLK */
 #define    CLKPWR_PCLKSEL_CCLK_DIV_4  ((uint32_t)(0))
 /** Peripheral clock divider is the same with CCLK */
--- a/lpc17xx_emac.c	Sun Jun 12 11:23:03 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,950 +0,0 @@
-/**
- * @file		lpc17xx_emac.c
- * @brief		Contains all functions support for Ethernet MAC firmware library on LPC17xx
- * @version		2.0
- * @date		21. May. 2010
- * @author		NXP MCU SW Application Team
- **************************************************************************
- * Software that is described herein is for illustrative purposes only
- * which provides customers with programming information regarding the
- * products. This software is supplied "AS IS" without any warranties.
- * NXP Semiconductors assumes no responsibility or liability for the
- * use of the software, conveys no license or title under any patent,
- * copyright, or mask work right to the product. NXP Semiconductors
- * reserves the right to make changes in the software without
- * notification. NXP Semiconductors also make no representation or
- * warranty that such application will be suitable for the specified
- * use without further testing or modification.
- **********************************************************************/
-
-/* Peripheral group ----------------------------------------------------------- */
-/** @addtogroup EMAC
- * @{
- */
-
-/* Includes ------------------------------------------------------------------- */
-#include "lpc17xx_emac.h"
-#include "lpc17xx_clkpwr.h"
-
-/* If this source file built with example, the LPC17xx FW library configuration
- * file in each example directory ("lpc17xx_libcfg.h") must be included,
- * otherwise the default FW library configuration file must be included instead
- */
-#ifdef __BUILD_WITH_EXAMPLE__
-#include "lpc17xx_libcfg.h"
-#else
-#include "lpc17xx_libcfg_default.h"
-#endif /* __BUILD_WITH_EXAMPLE__ */
-
-
-#ifdef _EMAC
-
-/* Private Variables ---------------------------------------------------------- */
-/** @defgroup EMAC_Private_Variables EMAC Private Variables
- * @{
- */
-
-/* MII Mgmt Configuration register - Clock divider setting */
-const uint8_t EMAC_clkdiv[] = { 4, 6, 8, 10, 14, 20, 28 };
-
-/* EMAC local DMA Descriptors */
-
-/** Rx Descriptor data array */
-static RX_Desc Rx_Desc[EMAC_NUM_RX_FRAG];
-
-/** Rx Status data array - Must be 8-Byte aligned */
-#if defined ( __CC_ARM   )
-static __align(8) RX_Stat Rx_Stat[EMAC_NUM_RX_FRAG];
-#elif defined ( __ICCARM__ )
-#pragma data_alignment=8
-static RX_Stat Rx_Stat[EMAC_NUM_RX_FRAG];
-#elif defined   (  __GNUC__  )
-static __attribute__ ((aligned (8))) RX_Stat Rx_Stat[EMAC_NUM_RX_FRAG];
-#endif
-
-/** Tx Descriptor data array */
-static TX_Desc Tx_Desc[EMAC_NUM_TX_FRAG];
-/** Tx Status data array */
-static TX_Stat Tx_Stat[EMAC_NUM_TX_FRAG];
-
-/* EMAC local DMA buffers */
-/** Rx buffer data */
-static uint32_t rx_buf[EMAC_NUM_RX_FRAG][EMAC_ETH_MAX_FLEN>>2];
-/** Tx buffer data */
-static uint32_t tx_buf[EMAC_NUM_TX_FRAG][EMAC_ETH_MAX_FLEN>>2];
-
-/**
- * @}
- */
-
-/* Private Functions ---------------------------------------------------------- */
-static void rx_descr_init (void);
-static void tx_descr_init (void);
-static int32_t write_PHY (uint32_t PhyReg, uint16_t Value);
-static int32_t  read_PHY (uint32_t PhyReg);
-
-static void setEmacAddr(uint8_t abStationAddr[]);
-static int32_t emac_CRCCalc(uint8_t frame_no_fcs[], int32_t frame_len);
-
-
-/*--------------------------- rx_descr_init ---------------------------------*/
-/*********************************************************************//**
- * @brief 		Initializes RX Descriptor
- * @param[in] 	None
- * @return 		None
- ***********************************************************************/
-static void rx_descr_init (void)
-{
-	/* Initialize Receive Descriptor and Status array. */
-	uint32_t i;
-
-	for (i = 0; i < EMAC_NUM_RX_FRAG; i++) {
-		Rx_Desc[i].Packet  = (uint32_t)&rx_buf[i];
-		Rx_Desc[i].Ctrl    = EMAC_RCTRL_INT | (EMAC_ETH_MAX_FLEN - 1);
-		Rx_Stat[i].Info    = 0;
-		Rx_Stat[i].HashCRC = 0;
-	}
-
-	/* Set EMAC Receive Descriptor Registers. */
-	LPC_EMAC->RxDescriptor       = (uint32_t)&Rx_Desc[0];
-	LPC_EMAC->RxStatus           = (uint32_t)&Rx_Stat[0];
-	LPC_EMAC->RxDescriptorNumber = EMAC_NUM_RX_FRAG - 1;
-
-	/* Rx Descriptors Point to 0 */
-	LPC_EMAC->RxConsumeIndex  = 0;
-}
-
-
-/*--------------------------- tx_descr_init ---- ----------------------------*/
-/*********************************************************************//**
- * @brief 		Initializes TX Descriptor
- * @param[in] 	None
- * @return 		None
- ***********************************************************************/
-static void tx_descr_init (void) {
-	/* Initialize Transmit Descriptor and Status array. */
-	uint32_t i;
-
-	for (i = 0; i < EMAC_NUM_TX_FRAG; i++) {
-		Tx_Desc[i].Packet = (uint32_t)&tx_buf[i];
-		Tx_Desc[i].Ctrl   = 0;
-		Tx_Stat[i].Info   = 0;
-	}
-
-	/* Set EMAC Transmit Descriptor Registers. */
-	LPC_EMAC->TxDescriptor       = (uint32_t)&Tx_Desc[0];
-	LPC_EMAC->TxStatus           = (uint32_t)&Tx_Stat[0];
-	LPC_EMAC->TxDescriptorNumber = EMAC_NUM_TX_FRAG - 1;
-
-	/* Tx Descriptors Point to 0 */
-	LPC_EMAC->TxProduceIndex  = 0;
-}
-
-
-/*--------------------------- write_PHY -------------------------------------*/
-/*********************************************************************//**
- * @brief 		Write value to PHY device
- * @param[in] 	PhyReg: PHY Register address
- * @param[in] 	Value:  Value to write
- * @return 		0 - if success
- * 				1 - if fail
- ***********************************************************************/
-static int32_t write_PHY (uint32_t PhyReg, uint16_t Value)
-{
-	/* Write a data 'Value' to PHY register 'PhyReg'. */
-	uint32_t tout;
-
-	LPC_EMAC->MADR = EMAC_DEF_ADR | PhyReg;
-	LPC_EMAC->MWTD = Value;
-
-	/* Wait until operation completed */
-	tout = 0;
-	for (tout = 0; tout < EMAC_MII_WR_TOUT; tout++) {
-		if ((LPC_EMAC->MIND & EMAC_MIND_BUSY) == 0) {
-			return (0);
-		}
-	}
-	// Time out!
-	return (-1);
-}
-
-
-/*--------------------------- read_PHY --------------------------------------*/
-/*********************************************************************//**
- * @brief 		Read value from PHY device
- * @param[in] 	PhyReg: PHY Register address
- * @return 		0 - if success
- * 				1 - if fail
- ***********************************************************************/
-static int32_t read_PHY (uint32_t PhyReg)
-{
-	/* Read a PHY register 'PhyReg'. */
-	uint32_t tout;
-
-	LPC_EMAC->MADR = EMAC_DEF_ADR | PhyReg;
-	LPC_EMAC->MCMD = EMAC_MCMD_READ;
-
-	/* Wait until operation completed */
-	tout = 0;
-	for (tout = 0; tout < EMAC_MII_RD_TOUT; tout++) {
-		if ((LPC_EMAC->MIND & EMAC_MIND_BUSY) == 0) {
-			LPC_EMAC->MCMD = 0;
-			return (LPC_EMAC->MRDD);
-		}
-	}
-	// Time out!
-	return (-1);
-}
-
-/*********************************************************************//**
- * @brief		Set Station MAC address for EMAC module
- * @param[in]	abStationAddr Pointer to Station address that contains 6-bytes
- * 				of MAC address (should be in order from MAC Address 1 to MAC Address 6)
- * @return		None
- **********************************************************************/
-static void setEmacAddr(uint8_t abStationAddr[])
-{
-	/* Set the Ethernet MAC Address registers */
-	LPC_EMAC->SA0 = ((uint32_t)abStationAddr[5] << 8) | (uint32_t)abStationAddr[4];
-	LPC_EMAC->SA1 = ((uint32_t)abStationAddr[3] << 8) | (uint32_t)abStationAddr[2];
-	LPC_EMAC->SA2 = ((uint32_t)abStationAddr[1] << 8) | (uint32_t)abStationAddr[0];
-}
-
-
-/*********************************************************************//**
- * @brief		Calculates CRC code for number of bytes in the frame
- * @param[in]	frame_no_fcs	Pointer to the first byte of the frame
- * @param[in]	frame_len		length of the frame without the FCS
- * @return		the CRC as a 32 bit integer
- **********************************************************************/
-static int32_t emac_CRCCalc(uint8_t frame_no_fcs[], int32_t frame_len)
-{
-	int i; 		// iterator
-	int j; 		// another iterator
-	char byte; 	// current byte
-	int crc; 	// CRC result
-	int q0, q1, q2, q3; // temporary variables
-	crc = 0xFFFFFFFF;
-	for (i = 0; i < frame_len; i++) {
-		byte = *frame_no_fcs++;
-		for (j = 0; j < 2; j++) {
-			if (((crc >> 28) ^ (byte >> 3)) & 0x00000001) {
-				q3 = 0x04C11DB7;
-			} else {
-				q3 = 0x00000000;
-			}
-			if (((crc >> 29) ^ (byte >> 2)) & 0x00000001) {
-				q2 = 0x09823B6E;
-			} else {
-				q2 = 0x00000000;
-			}
-			if (((crc >> 30) ^ (byte >> 1)) & 0x00000001) {
-				q1 = 0x130476DC;
-			} else {
-				q1 = 0x00000000;
-			}
-			if (((crc >> 31) ^ (byte >> 0)) & 0x00000001) {
-				q0 = 0x2608EDB8;
-			} else {
-				q0 = 0x00000000;
-			}
-			crc = (crc << 4) ^ q3 ^ q2 ^ q1 ^ q0;
-			byte >>= 4;
-		}
-	}
-	return crc;
-}
-/* End of Private Functions --------------------------------------------------- */
-
-
-/* Public Functions ----------------------------------------------------------- */
-/** @addtogroup EMAC_Public_Functions
- * @{
- */
-
-
-/*********************************************************************//**
- * @brief		Initializes the EMAC peripheral according to the specified
-*               parameters in the EMAC_ConfigStruct.
- * @param[in]	EMAC_ConfigStruct Pointer to a EMAC_CFG_Type structure
-*                    that contains the configuration information for the
-*                    specified EMAC peripheral.
- * @return		None
- *
- * Note: This function will initialize EMAC module according to procedure below:
- *  - Remove the soft reset condition from the MAC
- *  - Configure the PHY via the MIIM interface of the MAC
- *  - Select RMII mode
- *  - Configure the transmit and receive DMA engines, including the descriptor arrays
- *  - Configure the host registers (MAC1,MAC2 etc.) in the MAC
- *  - Enable the receive and transmit data paths
- *  In default state after initializing, only Rx Done and Tx Done interrupt are enabled,
- *  all remain interrupts are disabled
- *  (Ref. from LPC17xx UM)
- **********************************************************************/
-Status EMAC_Init(EMAC_CFG_Type *EMAC_ConfigStruct)
-{
-	/* Initialize the EMAC Ethernet controller. */
-	int32_t regv,tout, tmp;
-
-	/* Set up clock and power for Ethernet module */
-	CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCENET, ENABLE);
-
-	/* Reset all EMAC internal modules */
-	LPC_EMAC->MAC1    = EMAC_MAC1_RES_TX | EMAC_MAC1_RES_MCS_TX | EMAC_MAC1_RES_RX |
-					EMAC_MAC1_RES_MCS_RX | EMAC_MAC1_SIM_RES | EMAC_MAC1_SOFT_RES;
-
-	LPC_EMAC->Command = EMAC_CR_REG_RES | EMAC_CR_TX_RES | EMAC_CR_RX_RES | EMAC_CR_PASS_RUNT_FRM;
-
-	/* A short delay after reset. */
-	for (tout = 100; tout; tout--);
-
-	/* Initialize MAC control registers. */
-	LPC_EMAC->MAC1 = EMAC_MAC1_PASS_ALL;
-	LPC_EMAC->MAC2 = EMAC_MAC2_CRC_EN | EMAC_MAC2_PAD_EN;
-	LPC_EMAC->MAXF = EMAC_ETH_MAX_FLEN;
-	/*
-	 * Find the clock that close to desired target clock
-	 */
-	tmp = SystemCoreClock / EMAC_MCFG_MII_MAXCLK;
-	for (tout = 0; tout < sizeof (EMAC_clkdiv); tout++){
-		if (EMAC_clkdiv[tout] >= tmp) break;
-	}
-	tout++;
-	// Write to MAC configuration register and reset
-	LPC_EMAC->MCFG = EMAC_MCFG_CLK_SEL(tout) | EMAC_MCFG_RES_MII;
-	// release reset
-	LPC_EMAC->MCFG &= ~(EMAC_MCFG_RES_MII);
-	LPC_EMAC->CLRT = EMAC_CLRT_DEF;
-	LPC_EMAC->IPGR = EMAC_IPGR_P2_DEF;
-
-	/* Enable Reduced MII interface. */
-	LPC_EMAC->Command = EMAC_CR_RMII | EMAC_CR_PASS_RUNT_FRM;
-
-	/* Reset Reduced MII Logic. */
-	LPC_EMAC->SUPP = EMAC_SUPP_RES_RMII;
-
-	for (tout = 100; tout; tout--);
-	LPC_EMAC->SUPP = 0;
-
-	/* Put the DP83848C in reset mode */
-	write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_BMCR_RESET);
-
-	/* Wait for hardware reset to end. */
-	for (tout = EMAC_PHY_RESP_TOUT; tout; tout--) {
-		regv = read_PHY (EMAC_PHY_REG_BMCR);
-		if (!(regv & (EMAC_PHY_BMCR_RESET | EMAC_PHY_BMCR_POWERDOWN))) {
-			/* Reset complete, device not Power Down. */
-			break;
-		}
-		if (tout == 0){
-			// Time out, return ERROR
-			return (ERROR);
-		}
-	}
-
-	// Set PHY mode
-	if (EMAC_SetPHYMode(EMAC_ConfigStruct->Mode) < 0){
-		return (ERROR);
-	}
-
-	// Set EMAC address
-	setEmacAddr(EMAC_ConfigStruct->pbEMAC_Addr);
-
-	/* Initialize Tx and Rx DMA Descriptors */
-	rx_descr_init ();
-	tx_descr_init ();
-
-	// Set Receive Filter register: enable broadcast and multicast
-	LPC_EMAC->RxFilterCtrl = EMAC_RFC_MCAST_EN | EMAC_RFC_BCAST_EN | EMAC_RFC_PERFECT_EN;
-
-	/* Enable Rx Done and Tx Done interrupt for EMAC */
-	LPC_EMAC->IntEnable = EMAC_INT_RX_DONE | EMAC_INT_TX_DONE;
-
-	/* Reset all interrupts */
-	LPC_EMAC->IntClear  = 0xFFFF;
-
-	/* Enable receive and transmit mode of MAC Ethernet core */
-	LPC_EMAC->Command  |= (EMAC_CR_RX_EN | EMAC_CR_TX_EN);
-	LPC_EMAC->MAC1     |= EMAC_MAC1_REC_EN;
-
-	return SUCCESS;
-}
-
-
-/*********************************************************************//**
- * @brief		De-initializes the EMAC peripheral registers to their
-*                  default reset values.
- * @param[in]	None
- * @return 		None
- **********************************************************************/
-void EMAC_DeInit(void)
-{
-	// Disable all interrupt
-	LPC_EMAC->IntEnable = 0x00;
-	// Clear all pending interrupt
-	LPC_EMAC->IntClear = (0xFF) | (EMAC_INT_SOFT_INT | EMAC_INT_WAKEUP);
-
-	/* TurnOff clock and power for Ethernet module */
-	CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCENET, DISABLE);
-}
-
-
-/*********************************************************************//**
- * @brief		Check specified PHY status in EMAC peripheral
- * @param[in]	ulPHYState	Specified PHY Status Type, should be:
- * 							- EMAC_PHY_STAT_LINK: Link Status
- * 							- EMAC_PHY_STAT_SPEED: Speed Status
- * 							- EMAC_PHY_STAT_DUP: Duplex Status
- * @return		Status of specified PHY status (0 or 1).
- * 				(-1) if error.
- *
- * Note:
- * For EMAC_PHY_STAT_LINK, return value:
- * - 0: Link Down
- * - 1: Link Up
- * For EMAC_PHY_STAT_SPEED, return value:
- * - 0: 10Mbps
- * - 1: 100Mbps
- * For EMAC_PHY_STAT_DUP, return value:
- * - 0: Half-Duplex
- * - 1: Full-Duplex
- **********************************************************************/
-int32_t EMAC_CheckPHYStatus(uint32_t ulPHYState)
-{
-	int32_t regv, tmp;
-#ifdef MCB_LPC_1768
-	regv = read_PHY (EMAC_PHY_REG_STS);
-	switch(ulPHYState){
-	case EMAC_PHY_STAT_LINK:
-		tmp = (regv & EMAC_PHY_SR_LINK) ? 1 : 0;
-		break;
-	case EMAC_PHY_STAT_SPEED:
-		tmp = (regv & EMAC_PHY_SR_SPEED) ? 0 : 1;
-		break;
-	case EMAC_PHY_STAT_DUP:
-		tmp = (regv & EMAC_PHY_SR_FULL_DUP) ? 1 : 0;
-		break;
-#elif defined(IAR_LPC_1768)
-	/* Use IAR_LPC_1768 board:
-	 * FSZ8721BL doesn't have Status Register
-	 * so we read Basic Mode Status Register (0x01h) instead
-	 */
-	regv = read_PHY (EMAC_PHY_REG_BMSR);
-	switch(ulPHYState){
-	case EMAC_PHY_STAT_LINK:
-		tmp = (regv & EMAC_PHY_BMSR_LINK_STATUS) ? 1 : 0;
-		break;
-	case EMAC_PHY_STAT_SPEED:
-		tmp = (regv & EMAC_PHY_SR_100_SPEED) ? 1 : 0;
-		break;
-	case EMAC_PHY_STAT_DUP:
-		tmp = (regv & EMAC_PHY_SR_FULL_DUP) ? 1 : 0;
-		break;
-#endif
-	default:
-		tmp = -1;
-		break;
-	}
-	return (tmp);
-}
-
-
-/*********************************************************************//**
- * @brief		Set specified PHY mode in EMAC peripheral
- * @param[in]	ulPHYMode	Specified PHY mode, should be:
- * 							- EMAC_MODE_AUTO
- * 							- EMAC_MODE_10M_FULL
- * 							- EMAC_MODE_10M_HALF
- * 							- EMAC_MODE_100M_FULL
- * 							- EMAC_MODE_100M_HALF
- * @return		Return (0) if no error, otherwise return (-1)
- **********************************************************************/
-int32_t EMAC_SetPHYMode(uint32_t ulPHYMode)
-{
-	int32_t id1, id2, tout, regv;
-
-	/* Check if this is a DP83848C PHY. */
-	id1 = read_PHY (EMAC_PHY_REG_IDR1);
-	id2 = read_PHY (EMAC_PHY_REG_IDR2);
-
-#ifdef MCB_LPC_1768
-	if (((id1 << 16) | (id2 & 0xFFF0)) == EMAC_DP83848C_ID) {
-		switch(ulPHYMode){
-		case EMAC_MODE_AUTO:
-			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_AUTO_NEG);
-#elif defined(IAR_LPC_1768) /* Use IAR LPC1768 KickStart board */
-	if (((id1 << 16) | id2) == EMAC_KSZ8721BL_ID) {
-		/* Configure the PHY device */
-		switch(ulPHYMode){
-		case EMAC_MODE_AUTO:
-			/* Use auto-negotiation about the link speed. */
-			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_AUTO_NEG);
-//			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_BMCR_AN);
-#endif
-			/* Wait to complete Auto_Negotiation */
-			for (tout = EMAC_PHY_RESP_TOUT; tout; tout--) {
-				regv = read_PHY (EMAC_PHY_REG_BMSR);
-				if (regv & EMAC_PHY_BMSR_AUTO_DONE) {
-					/* Auto-negotiation Complete. */
-					break;
-				}
-				if (tout == 0){
-					// Time out, return error
-					return (-1);
-				}
-			}
-			break;
-		case EMAC_MODE_10M_FULL:
-			/* Connect at 10MBit full-duplex */
-			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_FULLD_10M);
-			break;
-		case EMAC_MODE_10M_HALF:
-			/* Connect at 10MBit half-duplex */
-			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_HALFD_10M);
-			break;
-		case EMAC_MODE_100M_FULL:
-			/* Connect at 100MBit full-duplex */
-			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_FULLD_100M);
-			break;
-		case EMAC_MODE_100M_HALF:
-			/* Connect at 100MBit half-duplex */
-			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_HALFD_100M);
-			break;
-		default:
-			// un-supported
-			return (-1);
-		}
-	}
-	// It's not correct module ID
-	else {
-		return (-1);
-	}
-
-	// Update EMAC configuration with current PHY status
-	if (EMAC_UpdatePHYStatus() < 0){
-		return (-1);
-	}
-
-	// Complete
-	return (0);
-}
-
-
-/*********************************************************************//**
- * @brief		Auto-Configures value for the EMAC configuration register to
- * 				match with current PHY mode
- * @param[in]	None
- * @return		Return (0) if no error, otherwise return (-1)
- *
- * Note: The EMAC configuration will be auto-configured:
- * 		- Speed mode.
- * 		- Half/Full duplex mode
- **********************************************************************/
-int32_t EMAC_UpdatePHYStatus(void)
-{
-	int32_t regv, tout;
-
-	/* Check the link status. */
-#ifdef MCB_LPC_1768
-	for (tout = EMAC_PHY_RESP_TOUT; tout; tout--) {
-		regv = read_PHY (EMAC_PHY_REG_STS);
-		if (regv & EMAC_PHY_SR_LINK) {
-			/* Link is on. */
-			break;
-		}
-		if (tout == 0){
-			// time out
-			return (-1);
-		}
-	}
-	/* Configure Full/Half Duplex mode. */
-	if (regv & EMAC_PHY_SR_DUP) {
-	/* Full duplex is enabled. */
-			LPC_EMAC->MAC2    |= EMAC_MAC2_FULL_DUP;
-			LPC_EMAC->Command |= EMAC_CR_FULL_DUP;
-			LPC_EMAC->IPGT     = EMAC_IPGT_FULL_DUP;
-	} else {
-		/* Half duplex mode. */
-		LPC_EMAC->IPGT = EMAC_IPGT_HALF_DUP;
-	}
-	if (regv & EMAC_PHY_SR_SPEED) {
-	/* 10MBit mode. */
-		LPC_EMAC->SUPP = 0;
-	} else {
-		/* 100MBit mode. */
-		LPC_EMAC->SUPP = EMAC_SUPP_SPEED;
-	}
-#elif defined(IAR_LPC_1768)
-	for (tout = EMAC_PHY_RESP_TOUT; tout; tout--) {
-		regv = read_PHY (EMAC_PHY_REG_BMSR);
-		if (regv & EMAC_PHY_BMSR_LINK_STATUS) {
-			/* Link is on. */
-			break;
-		}
-		if (tout == 0){
-			// time out
-			return (-1);
-		}
-	}
-
-	/* Configure Full/Half Duplex mode. */
-	if (regv & EMAC_PHY_SR_FULL_DUP) {
-		/* Full duplex is enabled. */
-		LPC_EMAC->MAC2    |= EMAC_MAC2_FULL_DUP;
-		LPC_EMAC->Command |= EMAC_CR_FULL_DUP;
-		LPC_EMAC->IPGT     = EMAC_IPGT_FULL_DUP;
-	} else {
-		/* Half duplex mode. */
-		LPC_EMAC->IPGT = EMAC_IPGT_HALF_DUP;
-	}
-
-	/* Configure 100MBit/10MBit mode. */
-	if (!(regv & EMAC_PHY_SR_100_SPEED)) {
-		/* 10MBit mode. */
-		LPC_EMAC->SUPP = 0;
-	} else {
-		/* 100MBit mode. */
-		LPC_EMAC->SUPP = EMAC_SUPP_SPEED;
-	}
-#endif
-	// Complete
-	return (0);
-}
-
-
-/*********************************************************************//**
- * @brief		Enable/Disable hash filter functionality for specified destination
- * 				MAC address in EMAC module
- * @param[in]	dstMAC_addr		Pointer to the first MAC destination address, should
- * 								be 6-bytes length, in order LSB to the MSB
- * @param[in]	NewState		New State of this command, should be:
- *									- ENABLE.
- *									- DISABLE.
- * @return		None
- *
- * Note:
- * The standard Ethernet cyclic redundancy check (CRC) function is calculated from
- * the 6 byte destination address in the Ethernet frame (this CRC is calculated
- * anyway as part of calculating the CRC of the whole frame), then bits [28:23] out of
- * the 32 bits CRC result are taken to form the hash. The 6 bit hash is used to access
- * the hash table: it is used as an index in the 64 bit HashFilter register that has been
- * programmed with accept values. If the selected accept value is 1, the frame is
- * accepted.
- **********************************************************************/
-void EMAC_SetHashFilter(uint8_t dstMAC_addr[], FunctionalState NewState)
-{
-	uint32_t *pReg;
-	uint32_t tmp;
-	int32_t crc;
-
-	// Calculate the CRC from the destination MAC address
-	crc = emac_CRCCalc(dstMAC_addr, 6);
-	// Extract the value from CRC to get index value for hash filter table
-	crc = (crc >> 23) & 0x3F;
-
-	pReg = (crc > 31) ? ((uint32_t *)&LPC_EMAC->HashFilterH) \
-								: ((uint32_t *)&LPC_EMAC->HashFilterL);
-	tmp = (crc > 31) ? (crc - 32) : crc;
-	if (NewState == ENABLE) {
-		(*pReg) |= (1UL << tmp);
-	} else {
-		(*pReg) &= ~(1UL << tmp);
-	}
-	// Enable Rx Filter
-	LPC_EMAC->Command &= ~EMAC_CR_PASS_RX_FILT;
-}
-
-/*********************************************************************//**
- * @brief		Enable/Disable Filter mode for each specified type EMAC peripheral
- * @param[in]	ulFilterMode	Filter mode, should be:
- * 								- EMAC_RFC_UCAST_EN: all frames of unicast types
- * 								will be accepted
- * 								- EMAC_RFC_BCAST_EN: broadcast frame will be
- * 								accepted
- * 								- EMAC_RFC_MCAST_EN: all frames of multicast
- * 								types will be accepted
- * 								- EMAC_RFC_UCAST_HASH_EN: The imperfect hash
- * 								filter will be applied to unicast addresses
- * 								- EMAC_RFC_MCAST_HASH_EN: The imperfect hash
- * 								filter will be applied to multicast addresses
- * 								- EMAC_RFC_PERFECT_EN: the destination address
- * 								will be compared with the 6 byte station address
- * 								programmed in the station address by the filter
- * 								- EMAC_RFC_MAGP_WOL_EN: the result of the magic
- * 								packet filter will generate a WoL interrupt when
- * 								there is a match
- * 								- EMAC_RFC_PFILT_WOL_EN: the result of the perfect address
- * 								matching filter and the imperfect hash filter will
- * 								generate a WoL interrupt when there is a match
- * @param[in]	NewState	New State of this command, should be:
- * 								- ENABLE
- * 								- DISABLE
- * @return		None
- **********************************************************************/
-void EMAC_SetFilterMode(uint32_t ulFilterMode, FunctionalState NewState)
-{
-	if (NewState == ENABLE){
-		LPC_EMAC->RxFilterCtrl |= ulFilterMode;
-	} else {
-		LPC_EMAC->RxFilterCtrl &= ~ulFilterMode;
-	}
-}
-
-/*********************************************************************//**
- * @brief		Get status of Wake On LAN Filter for each specified
- * 				type in EMAC peripheral, clear this status if it is set
- * @param[in]	ulWoLMode	WoL Filter mode, should be:
- * 								- EMAC_WOL_UCAST: unicast frames caused WoL
- * 								- EMAC_WOL_UCAST: broadcast frame caused WoL
- * 								- EMAC_WOL_MCAST: multicast frame caused WoL
- * 								- EMAC_WOL_UCAST_HASH: unicast frame that passes the
- * 								imperfect hash filter caused WoL
- * 								- EMAC_WOL_MCAST_HASH: multicast frame that passes the
- * 								imperfect hash filter caused WoL
- * 								- EMAC_WOL_PERFECT:perfect address matching filter
- * 								caused WoL
- * 								- EMAC_WOL_RX_FILTER: the receive filter caused WoL
- * 								- EMAC_WOL_MAG_PACKET: the magic packet filter caused WoL
- * @return		SET/RESET
- **********************************************************************/
-FlagStatus EMAC_GetWoLStatus(uint32_t ulWoLMode)
-{
-	if (LPC_EMAC->RxFilterWoLStatus & ulWoLMode) {
-		LPC_EMAC->RxFilterWoLClear = ulWoLMode;
-		return SET;
-	} else {
-		return RESET;
-	}
-}
-
-
-/*********************************************************************//**
- * @brief		Write data to Tx packet data buffer at current index due to
- * 				TxProduceIndex
- * @param[in]	pDataStruct		Pointer to a EMAC_PACKETBUF_Type structure
- * 							data that contain specified information about
- * 							Packet data buffer.
- * @return		None
- **********************************************************************/
-void EMAC_WritePacketBuffer(EMAC_PACKETBUF_Type *pDataStruct)
-{
-	uint32_t idx,len;
-	uint32_t *sp,*dp;
-
-	idx = LPC_EMAC->TxProduceIndex;
-	sp  = (uint32_t *)pDataStruct->pbDataBuf;
-	dp  = (uint32_t *)Tx_Desc[idx].Packet;
-	/* Copy frame data to EMAC packet buffers. */
-	for (len = (pDataStruct->ulDataLen + 3) >> 2; len; len--) {
-		*dp++ = *sp++;
-	}
-	Tx_Desc[idx].Ctrl = (pDataStruct->ulDataLen - 1) | (EMAC_TCTRL_INT | EMAC_TCTRL_LAST);
-}
-
-/*********************************************************************//**
- * @brief		Read data from Rx packet data buffer at current index due
- * 				to RxConsumeIndex
- * @param[in]	pDataStruct		Pointer to a EMAC_PACKETBUF_Type structure
- * 							data that contain specified information about
- * 							Packet data buffer.
- * @return		None
- **********************************************************************/
-void EMAC_ReadPacketBuffer(EMAC_PACKETBUF_Type *pDataStruct)
-{
-	uint32_t idx, len;
-	uint32_t *dp, *sp;
-
-	idx = LPC_EMAC->RxConsumeIndex;
-	dp = (uint32_t *)pDataStruct->pbDataBuf;
-	sp = (uint32_t *)Rx_Desc[idx].Packet;
-
-	if (pDataStruct->pbDataBuf != NULL) {
-		for (len = (pDataStruct->ulDataLen + 3) >> 2; len; len--) {
-			*dp++ = *sp++;
-		}
-	}
-}
-
-/*********************************************************************//**
- * @brief 		Enable/Disable interrupt for each type in EMAC
- * @param[in]	ulIntType	Interrupt Type, should be:
- * 							- EMAC_INT_RX_OVERRUN: Receive Overrun
- * 							- EMAC_INT_RX_ERR: Receive Error
- * 							- EMAC_INT_RX_FIN: Receive Descriptor Finish
- * 							- EMAC_INT_RX_DONE: Receive Done
- * 							- EMAC_INT_TX_UNDERRUN: Transmit Under-run
- * 							- EMAC_INT_TX_ERR: Transmit Error
- * 							- EMAC_INT_TX_FIN: Transmit descriptor finish
- * 							- EMAC_INT_TX_DONE: Transmit Done
- * 							- EMAC_INT_SOFT_INT: Software interrupt
- * 							- EMAC_INT_WAKEUP: Wakeup interrupt
- * @param[in]	NewState	New State of this function, should be:
- * 							- ENABLE.
- * 							- DISABLE.
- * @return		None
- **********************************************************************/
-void EMAC_IntCmd(uint32_t ulIntType, FunctionalState NewState)
-{
-	if (NewState == ENABLE) {
-		LPC_EMAC->IntEnable |= ulIntType;
-	} else {
-		LPC_EMAC->IntEnable &= ~(ulIntType);
-	}
-}
-
-/*********************************************************************//**
- * @brief 		Check whether if specified interrupt flag is set or not
- * 				for each interrupt type in EMAC and clear interrupt pending
- * 				if it is set.
- * @param[in]	ulIntType	Interrupt Type, should be:
- * 							- EMAC_INT_RX_OVERRUN: Receive Overrun
- * 							- EMAC_INT_RX_ERR: Receive Error
- * 							- EMAC_INT_RX_FIN: Receive Descriptor Finish
- * 							- EMAC_INT_RX_DONE: Receive Done
- * 							- EMAC_INT_TX_UNDERRUN: Transmit Under-run
- * 							- EMAC_INT_TX_ERR: Transmit Error
- * 							- EMAC_INT_TX_FIN: Transmit descriptor finish
- * 							- EMAC_INT_TX_DONE: Transmit Done
- * 							- EMAC_INT_SOFT_INT: Software interrupt
- * 							- EMAC_INT_WAKEUP: Wakeup interrupt
- * @return		New state of specified interrupt (SET or RESET)
- **********************************************************************/
-IntStatus EMAC_IntGetStatus(uint32_t ulIntType)
-{
-	if (LPC_EMAC->IntStatus & ulIntType) {
-		LPC_EMAC->IntClear = ulIntType;
-		return SET;
-	} else {
-		return RESET;
-	}
-}
-
-
-/*********************************************************************//**
- * @brief		Check whether if the current RxConsumeIndex is not equal to the
- * 				current RxProduceIndex.
- * @param[in]	None
- * @return		TRUE if they're not equal, otherwise return FALSE
- *
- * Note: In case the RxConsumeIndex is not equal to the RxProduceIndex,
- * it means there're available data has been received. They should be read
- * out and released the Receive Data Buffer by updating the RxConsumeIndex value.
- **********************************************************************/
-Bool EMAC_CheckReceiveIndex(void)
-{
-	if (LPC_EMAC->RxConsumeIndex != LPC_EMAC->RxProduceIndex) {
-		return TRUE;
-	} else {
-		return FALSE;
-	}
-}
-
-
-/*********************************************************************//**
- * @brief		Check whether if the current TxProduceIndex is not equal to the
- * 				current RxProduceIndex - 1.
- * @param[in]	None
- * @return		TRUE if they're not equal, otherwise return FALSE
- *
- * Note: In case the RxConsumeIndex is equal to the RxProduceIndex - 1,
- * it means the transmit buffer is available and data can be written to transmit
- * buffer to be sent.
- **********************************************************************/
-Bool EMAC_CheckTransmitIndex(void)
-{
-	uint32_t tmp = LPC_EMAC->TxConsumeIndex -1;
-	if (LPC_EMAC->TxProduceIndex == tmp) {
-		return FALSE;
-	} else {
-		return TRUE;
-	}
-}
-
-
-/*********************************************************************//**
- * @brief		Get current status value of receive data (due to RxConsumeIndex)
- * @param[in]	ulRxStatType	Received Status type, should be one of following:
- * 							- EMAC_RINFO_CTRL_FRAME: Control Frame
- * 							- EMAC_RINFO_VLAN: VLAN Frame
- * 							- EMAC_RINFO_FAIL_FILT: RX Filter Failed
- * 							- EMAC_RINFO_MCAST: Multicast Frame
- * 							- EMAC_RINFO_BCAST: Broadcast Frame
- * 							- EMAC_RINFO_CRC_ERR: CRC Error in Frame
- * 							- EMAC_RINFO_SYM_ERR: Symbol Error from PHY
- * 							- EMAC_RINFO_LEN_ERR: Length Error
- * 							- EMAC_RINFO_RANGE_ERR: Range error(exceeded max size)
- * 							- EMAC_RINFO_ALIGN_ERR: Alignment error
- * 							- EMAC_RINFO_OVERRUN: Receive overrun
- * 							- EMAC_RINFO_NO_DESCR: No new Descriptor available
- * 							- EMAC_RINFO_LAST_FLAG: last Fragment in Frame
- * 							- EMAC_RINFO_ERR: Error Occurred (OR of all error)
- * @return		Current value of receive data (due to RxConsumeIndex)
- **********************************************************************/
-FlagStatus EMAC_CheckReceiveDataStatus(uint32_t ulRxStatType)
-{
-	uint32_t idx;
-	idx = LPC_EMAC->RxConsumeIndex;
-	return (((Rx_Stat[idx].Info) & ulRxStatType) ? SET : RESET);
-}
-
-
-/*********************************************************************//**
- * @brief		Get size of current Received data in received buffer (due to
- * 				RxConsumeIndex)
- * @param[in]	None
- * @return		Size of received data
- **********************************************************************/
-uint32_t EMAC_GetReceiveDataSize(void)
-{
-	uint32_t idx;
-	idx =LPC_EMAC->RxConsumeIndex;
-	return ((Rx_Stat[idx].Info) & EMAC_RINFO_SIZE);
-}
-
-/*********************************************************************//**
- * @brief		Increase the RxConsumeIndex (after reading the Receive buffer
- * 				to release the Receive buffer) and wrap-around the index if
- * 				it reaches the maximum Receive Number
- * @param[in]	None
- * @return		None
- **********************************************************************/
-void EMAC_UpdateRxConsumeIndex(void)
-{
-	// Get current Rx consume index
-	uint32_t idx = LPC_EMAC->RxConsumeIndex;
-
-	/* Release frame from EMAC buffer */
-	if (++idx == EMAC_NUM_RX_FRAG) idx = 0;
-	LPC_EMAC->RxConsumeIndex = idx;
-}
-
-/*********************************************************************//**
- * @brief		Increase the TxProduceIndex (after writting to the Transmit buffer
- * 				to enable the Transmit buffer) and wrap-around the index if
- * 				it reaches the maximum Transmit Number
- * @param[in]	None
- * @return		None
- **********************************************************************/
-void EMAC_UpdateTxProduceIndex(void)
-{
-	// Get current Tx produce index
-	uint32_t idx = LPC_EMAC->TxProduceIndex;
-
-	/* Start frame transmission */
-	if (++idx == EMAC_NUM_TX_FRAG) idx = 0;
-	LPC_EMAC->TxProduceIndex = idx;
-}
-
-
-/**
- * @}
- */
-
-#endif /* _EMAC */
-
-/**
- * @}
- */
-
-/* --------------------------------- End Of File ------------------------------ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lpc17xx_emac.cpp	Sun Jun 12 19:17:11 2011 +0000
@@ -0,0 +1,950 @@
+/**
+ * @file		lpc17xx_emac.c
+ * @brief		Contains all functions support for Ethernet MAC firmware library on LPC17xx
+ * @version		2.0
+ * @date		21. May. 2010
+ * @author		NXP MCU SW Application Team
+ **************************************************************************
+ * Software that is described herein is for illustrative purposes only
+ * which provides customers with programming information regarding the
+ * products. This software is supplied "AS IS" without any warranties.
+ * NXP Semiconductors assumes no responsibility or liability for the
+ * use of the software, conveys no license or title under any patent,
+ * copyright, or mask work right to the product. NXP Semiconductors
+ * reserves the right to make changes in the software without
+ * notification. NXP Semiconductors also make no representation or
+ * warranty that such application will be suitable for the specified
+ * use without further testing or modification.
+ **********************************************************************/
+
+/* Peripheral group ----------------------------------------------------------- */
+/** @addtogroup EMAC
+ * @{
+ */
+
+/* Includes ------------------------------------------------------------------- */
+#include "lpc17xx_emac.h"
+#include "lpc17xx_clkpwr.h"
+
+/* If this source file built with example, the LPC17xx FW library configuration
+ * file in each example directory ("lpc17xx_libcfg.h") must be included,
+ * otherwise the default FW library configuration file must be included instead
+ */
+#ifdef __BUILD_WITH_EXAMPLE__
+#include "lpc17xx_libcfg.h"
+#else
+#include "lpc17xx_libcfg_default.h"
+#endif /* __BUILD_WITH_EXAMPLE__ */
+
+
+#ifdef _EMAC
+
+/* Private Variables ---------------------------------------------------------- */
+/** @defgroup EMAC_Private_Variables EMAC Private Variables
+ * @{
+ */
+
+/* MII Mgmt Configuration register - Clock divider setting */
+const uint8_t EMAC_clkdiv[] = { 4, 6, 8, 10, 14, 20, 28 };
+
+/* EMAC local DMA Descriptors */
+
+/** Rx Descriptor data array */
+static RX_Desc Rx_Desc[EMAC_NUM_RX_FRAG];
+
+/** Rx Status data array - Must be 8-Byte aligned */
+#if defined ( __CC_ARM   )
+static __align(8) RX_Stat Rx_Stat[EMAC_NUM_RX_FRAG];
+#elif defined ( __ICCARM__ )
+#pragma data_alignment=8
+static RX_Stat Rx_Stat[EMAC_NUM_RX_FRAG];
+#elif defined   (  __GNUC__  )
+static __attribute__ ((aligned (8))) RX_Stat Rx_Stat[EMAC_NUM_RX_FRAG];
+#endif
+
+/** Tx Descriptor data array */
+static TX_Desc Tx_Desc[EMAC_NUM_TX_FRAG];
+/** Tx Status data array */
+static TX_Stat Tx_Stat[EMAC_NUM_TX_FRAG];
+
+/* EMAC local DMA buffers */
+/** Rx buffer data */
+static __align(8) uint32_t rx_buf[EMAC_NUM_RX_FRAG][EMAC_ETH_MAX_FLEN>>2] __attribute((section("AHBSRAM1"),aligned)) ;
+/** Tx buffer data */
+static __align(8) uint32_t tx_buf[EMAC_NUM_TX_FRAG][EMAC_ETH_MAX_FLEN>>2] __attribute((section("AHBSRAM1"),aligned)) ;
+
+/**
+ * @}
+ */
+
+/* Private Functions ---------------------------------------------------------- */
+static void rx_descr_init (void);
+static void tx_descr_init (void);
+static int32_t write_PHY (uint32_t PhyReg, uint16_t Value);
+static int32_t  read_PHY (uint32_t PhyReg);
+
+static void setEmacAddr(uint8_t abStationAddr[]);
+static int32_t emac_CRCCalc(uint8_t frame_no_fcs[], int32_t frame_len);
+
+
+/*--------------------------- rx_descr_init ---------------------------------*/
+/*********************************************************************//**
+ * @brief 		Initializes RX Descriptor
+ * @param[in] 	None
+ * @return 		None
+ ***********************************************************************/
+static void rx_descr_init (void)
+{
+	/* Initialize Receive Descriptor and Status array. */
+	uint32_t i;
+
+	for (i = 0; i < EMAC_NUM_RX_FRAG; i++) {
+		Rx_Desc[i].Packet  = (uint32_t)&rx_buf[i];
+		Rx_Desc[i].Ctrl    = EMAC_RCTRL_INT | (EMAC_ETH_MAX_FLEN - 1);
+		Rx_Stat[i].Info    = 0;
+		Rx_Stat[i].HashCRC = 0;
+	}
+
+	/* Set EMAC Receive Descriptor Registers. */
+	LPC_EMAC->RxDescriptor       = (uint32_t)&Rx_Desc[0];
+	LPC_EMAC->RxStatus           = (uint32_t)&Rx_Stat[0];
+	LPC_EMAC->RxDescriptorNumber = EMAC_NUM_RX_FRAG - 1;
+
+	/* Rx Descriptors Point to 0 */
+	LPC_EMAC->RxConsumeIndex  = 0;
+}
+
+
+/*--------------------------- tx_descr_init ---- ----------------------------*/
+/*********************************************************************//**
+ * @brief 		Initializes TX Descriptor
+ * @param[in] 	None
+ * @return 		None
+ ***********************************************************************/
+static void tx_descr_init (void) {
+	/* Initialize Transmit Descriptor and Status array. */
+	uint32_t i;
+
+	for (i = 0; i < EMAC_NUM_TX_FRAG; i++) {
+		Tx_Desc[i].Packet = (uint32_t)&tx_buf[i];
+		Tx_Desc[i].Ctrl   = 0;
+		Tx_Stat[i].Info   = 0;
+	}
+
+	/* Set EMAC Transmit Descriptor Registers. */
+	LPC_EMAC->TxDescriptor       = (uint32_t)&Tx_Desc[0];
+	LPC_EMAC->TxStatus           = (uint32_t)&Tx_Stat[0];
+	LPC_EMAC->TxDescriptorNumber = EMAC_NUM_TX_FRAG - 1;
+
+	/* Tx Descriptors Point to 0 */
+	LPC_EMAC->TxProduceIndex  = 0;
+}
+
+
+/*--------------------------- write_PHY -------------------------------------*/
+/*********************************************************************//**
+ * @brief 		Write value to PHY device
+ * @param[in] 	PhyReg: PHY Register address
+ * @param[in] 	Value:  Value to write
+ * @return 		0 - if success
+ * 				1 - if fail
+ ***********************************************************************/
+static int32_t write_PHY (uint32_t PhyReg, uint16_t Value)
+{
+	/* Write a data 'Value' to PHY register 'PhyReg'. */
+	uint32_t tout;
+
+	LPC_EMAC->MADR = EMAC_DEF_ADR | PhyReg;
+	LPC_EMAC->MWTD = Value;
+
+	/* Wait until operation completed */
+	tout = 0;
+	for (tout = 0; tout < EMAC_MII_WR_TOUT; tout++) {
+		if ((LPC_EMAC->MIND & EMAC_MIND_BUSY) == 0) {
+			return (0);
+		}
+	}
+	// Time out!
+	return (-1);
+}
+
+
+/*--------------------------- read_PHY --------------------------------------*/
+/*********************************************************************//**
+ * @brief 		Read value from PHY device
+ * @param[in] 	PhyReg: PHY Register address
+ * @return 		0 - if success
+ * 				1 - if fail
+ ***********************************************************************/
+static int32_t read_PHY (uint32_t PhyReg)
+{
+	/* Read a PHY register 'PhyReg'. */
+	uint32_t tout;
+
+	LPC_EMAC->MADR = EMAC_DEF_ADR | PhyReg;
+	LPC_EMAC->MCMD = EMAC_MCMD_READ;
+
+	/* Wait until operation completed */
+	tout = 0;
+	for (tout = 0; tout < EMAC_MII_RD_TOUT; tout++) {
+		if ((LPC_EMAC->MIND & EMAC_MIND_BUSY) == 0) {
+			LPC_EMAC->MCMD = 0;
+			return (LPC_EMAC->MRDD);
+		}
+	}
+	// Time out!
+	return (-1);
+}
+
+/*********************************************************************//**
+ * @brief		Set Station MAC address for EMAC module
+ * @param[in]	abStationAddr Pointer to Station address that contains 6-bytes
+ * 				of MAC address (should be in order from MAC Address 1 to MAC Address 6)
+ * @return		None
+ **********************************************************************/
+static void setEmacAddr(uint8_t abStationAddr[])
+{
+	/* Set the Ethernet MAC Address registers */
+	LPC_EMAC->SA0 = ((uint32_t)abStationAddr[5] << 8) | (uint32_t)abStationAddr[4];
+	LPC_EMAC->SA1 = ((uint32_t)abStationAddr[3] << 8) | (uint32_t)abStationAddr[2];
+	LPC_EMAC->SA2 = ((uint32_t)abStationAddr[1] << 8) | (uint32_t)abStationAddr[0];
+}
+
+
+/*********************************************************************//**
+ * @brief		Calculates CRC code for number of bytes in the frame
+ * @param[in]	frame_no_fcs	Pointer to the first byte of the frame
+ * @param[in]	frame_len		length of the frame without the FCS
+ * @return		the CRC as a 32 bit integer
+ **********************************************************************/
+static int32_t emac_CRCCalc(uint8_t frame_no_fcs[], int32_t frame_len)
+{
+	int i; 		// iterator
+	int j; 		// another iterator
+	char byte; 	// current byte
+	int crc; 	// CRC result
+	int q0, q1, q2, q3; // temporary variables
+	crc = 0xFFFFFFFF;
+	for (i = 0; i < frame_len; i++) {
+		byte = *frame_no_fcs++;
+		for (j = 0; j < 2; j++) {
+			if (((crc >> 28) ^ (byte >> 3)) & 0x00000001) {
+				q3 = 0x04C11DB7;
+			} else {
+				q3 = 0x00000000;
+			}
+			if (((crc >> 29) ^ (byte >> 2)) & 0x00000001) {
+				q2 = 0x09823B6E;
+			} else {
+				q2 = 0x00000000;
+			}
+			if (((crc >> 30) ^ (byte >> 1)) & 0x00000001) {
+				q1 = 0x130476DC;
+			} else {
+				q1 = 0x00000000;
+			}
+			if (((crc >> 31) ^ (byte >> 0)) & 0x00000001) {
+				q0 = 0x2608EDB8;
+			} else {
+				q0 = 0x00000000;
+			}
+			crc = (crc << 4) ^ q3 ^ q2 ^ q1 ^ q0;
+			byte >>= 4;
+		}
+	}
+	return crc;
+}
+/* End of Private Functions --------------------------------------------------- */
+
+
+/* Public Functions ----------------------------------------------------------- */
+/** @addtogroup EMAC_Public_Functions
+ * @{
+ */
+
+
+/*********************************************************************//**
+ * @brief		Initializes the EMAC peripheral according to the specified
+*               parameters in the EMAC_ConfigStruct.
+ * @param[in]	EMAC_ConfigStruct Pointer to a EMAC_CFG_Type structure
+*                    that contains the configuration information for the
+*                    specified EMAC peripheral.
+ * @return		None
+ *
+ * Note: This function will initialize EMAC module according to procedure below:
+ *  - Remove the soft reset condition from the MAC
+ *  - Configure the PHY via the MIIM interface of the MAC
+ *  - Select RMII mode
+ *  - Configure the transmit and receive DMA engines, including the descriptor arrays
+ *  - Configure the host registers (MAC1,MAC2 etc.) in the MAC
+ *  - Enable the receive and transmit data paths
+ *  In default state after initializing, only Rx Done and Tx Done interrupt are enabled,
+ *  all remain interrupts are disabled
+ *  (Ref. from LPC17xx UM)
+ **********************************************************************/
+Status EMAC_Init(EMAC_CFG_Type *EMAC_ConfigStruct)
+{
+	/* Initialize the EMAC Ethernet controller. */
+	int32_t regv,tout, tmp;
+
+	/* Set up clock and power for Ethernet module */
+	CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCENET, ENABLE);
+
+	/* Reset all EMAC internal modules */
+	LPC_EMAC->MAC1    = EMAC_MAC1_RES_TX | EMAC_MAC1_RES_MCS_TX | EMAC_MAC1_RES_RX |
+					EMAC_MAC1_RES_MCS_RX | EMAC_MAC1_SIM_RES | EMAC_MAC1_SOFT_RES;
+
+	LPC_EMAC->Command = EMAC_CR_REG_RES | EMAC_CR_TX_RES | EMAC_CR_RX_RES | EMAC_CR_PASS_RUNT_FRM;
+
+	/* A short delay after reset. */
+	for (tout = 100; tout; tout--);
+
+	/* Initialize MAC control registers. */
+	LPC_EMAC->MAC1 = EMAC_MAC1_PASS_ALL;
+	LPC_EMAC->MAC2 = EMAC_MAC2_CRC_EN | EMAC_MAC2_PAD_EN;
+	LPC_EMAC->MAXF = EMAC_ETH_MAX_FLEN;
+	/*
+	 * Find the clock that close to desired target clock
+	 */
+	tmp = SystemCoreClock / EMAC_MCFG_MII_MAXCLK;
+	for (tout = 0; tout < sizeof (EMAC_clkdiv); tout++){
+		if (EMAC_clkdiv[tout] >= tmp) break;
+	}
+	tout++;
+	// Write to MAC configuration register and reset
+	LPC_EMAC->MCFG = EMAC_MCFG_CLK_SEL(tout) | EMAC_MCFG_RES_MII;
+	// release reset
+	LPC_EMAC->MCFG &= ~(EMAC_MCFG_RES_MII);
+	LPC_EMAC->CLRT = EMAC_CLRT_DEF;
+	LPC_EMAC->IPGR = EMAC_IPGR_P2_DEF;
+
+	/* Enable Reduced MII interface. */
+	LPC_EMAC->Command = EMAC_CR_RMII | EMAC_CR_PASS_RUNT_FRM;
+
+	/* Reset Reduced MII Logic. */
+	LPC_EMAC->SUPP = EMAC_SUPP_RES_RMII;
+
+	for (tout = 100; tout; tout--);
+	LPC_EMAC->SUPP = 0;
+
+	/* Put the DP83848C in reset mode */
+	write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_BMCR_RESET);
+
+	/* Wait for hardware reset to end. */
+	for (tout = EMAC_PHY_RESP_TOUT; tout; tout--) {
+		regv = read_PHY (EMAC_PHY_REG_BMCR);
+		if (!(regv & (EMAC_PHY_BMCR_RESET | EMAC_PHY_BMCR_POWERDOWN))) {
+			/* Reset complete, device not Power Down. */
+			break;
+		}
+		if (tout == 0){
+			// Time out, return ERROR
+			return (ERROR);
+		}
+	}
+
+	// Set PHY mode
+	if (EMAC_SetPHYMode(EMAC_ConfigStruct->Mode) < 0){
+		return (ERROR);
+	}
+
+	// Set EMAC address
+	setEmacAddr(EMAC_ConfigStruct->pbEMAC_Addr);
+
+	/* Initialize Tx and Rx DMA Descriptors */
+	rx_descr_init ();
+	tx_descr_init ();
+
+	// Set Receive Filter register: enable broadcast and multicast
+	LPC_EMAC->RxFilterCtrl = EMAC_RFC_MCAST_EN | EMAC_RFC_BCAST_EN | EMAC_RFC_PERFECT_EN;
+
+	/* Enable Rx Done and Tx Done interrupt for EMAC */
+	LPC_EMAC->IntEnable = EMAC_INT_RX_DONE/* | EMAC_INT_TX_DONE*/;
+
+	/* Reset all interrupts */
+	LPC_EMAC->IntClear  = 0xFFFF;
+
+	/* Enable receive and transmit mode of MAC Ethernet core */
+	LPC_EMAC->Command  |= (EMAC_CR_RX_EN | EMAC_CR_TX_EN);
+	LPC_EMAC->MAC1     |= EMAC_MAC1_REC_EN;
+
+	return SUCCESS;
+}
+
+
+/*********************************************************************//**
+ * @brief		De-initializes the EMAC peripheral registers to their
+*                  default reset values.
+ * @param[in]	None
+ * @return 		None
+ **********************************************************************/
+void EMAC_DeInit(void)
+{
+	// Disable all interrupt
+	LPC_EMAC->IntEnable = 0x00;
+	// Clear all pending interrupt
+	LPC_EMAC->IntClear = (0xFF) | (EMAC_INT_SOFT_INT | EMAC_INT_WAKEUP);
+
+	/* TurnOff clock and power for Ethernet module */
+	CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCENET, DISABLE);
+}
+
+
+/*********************************************************************//**
+ * @brief		Check specified PHY status in EMAC peripheral
+ * @param[in]	ulPHYState	Specified PHY Status Type, should be:
+ * 							- EMAC_PHY_STAT_LINK: Link Status
+ * 							- EMAC_PHY_STAT_SPEED: Speed Status
+ * 							- EMAC_PHY_STAT_DUP: Duplex Status
+ * @return		Status of specified PHY status (0 or 1).
+ * 				(-1) if error.
+ *
+ * Note:
+ * For EMAC_PHY_STAT_LINK, return value:
+ * - 0: Link Down
+ * - 1: Link Up
+ * For EMAC_PHY_STAT_SPEED, return value:
+ * - 0: 10Mbps
+ * - 1: 100Mbps
+ * For EMAC_PHY_STAT_DUP, return value:
+ * - 0: Half-Duplex
+ * - 1: Full-Duplex
+ **********************************************************************/
+int32_t EMAC_CheckPHYStatus(uint32_t ulPHYState)
+{
+	int32_t regv, tmp;
+#ifdef MCB_LPC_1768
+	regv = read_PHY (EMAC_PHY_REG_STS);
+	switch(ulPHYState){
+	case EMAC_PHY_STAT_LINK:
+		tmp = (regv & EMAC_PHY_SR_LINK) ? 1 : 0;
+		break;
+	case EMAC_PHY_STAT_SPEED:
+		tmp = (regv & EMAC_PHY_SR_SPEED) ? 0 : 1;
+		break;
+	case EMAC_PHY_STAT_DUP:
+		tmp = (regv & EMAC_PHY_SR_FULL_DUP) ? 1 : 0;
+		break;
+#elif defined(IAR_LPC_1768)
+	/* Use IAR_LPC_1768 board:
+	 * FSZ8721BL doesn't have Status Register
+	 * so we read Basic Mode Status Register (0x01h) instead
+	 */
+	regv = read_PHY (EMAC_PHY_REG_BMSR);
+	switch(ulPHYState){
+	case EMAC_PHY_STAT_LINK:
+		tmp = (regv & EMAC_PHY_BMSR_LINK_STATUS) ? 1 : 0;
+		break;
+	case EMAC_PHY_STAT_SPEED:
+		tmp = (regv & EMAC_PHY_SR_100_SPEED) ? 1 : 0;
+		break;
+	case EMAC_PHY_STAT_DUP:
+		tmp = (regv & EMAC_PHY_SR_FULL_DUP) ? 1 : 0;
+		break;
+#endif
+	default:
+		tmp = -1;
+		break;
+	}
+	return (tmp);
+}
+
+
+/*********************************************************************//**
+ * @brief		Set specified PHY mode in EMAC peripheral
+ * @param[in]	ulPHYMode	Specified PHY mode, should be:
+ * 							- EMAC_MODE_AUTO
+ * 							- EMAC_MODE_10M_FULL
+ * 							- EMAC_MODE_10M_HALF
+ * 							- EMAC_MODE_100M_FULL
+ * 							- EMAC_MODE_100M_HALF
+ * @return		Return (0) if no error, otherwise return (-1)
+ **********************************************************************/
+int32_t EMAC_SetPHYMode(uint32_t ulPHYMode)
+{
+	int32_t id1, id2, tout, regv;
+
+	/* Check if this is a DP83848C PHY. */
+	id1 = read_PHY (EMAC_PHY_REG_IDR1);
+	id2 = read_PHY (EMAC_PHY_REG_IDR2);
+
+#ifdef MCB_LPC_1768
+	if (((id1 << 16) | (id2 & 0xFFF0)) == EMAC_DP83848C_ID) {
+		switch(ulPHYMode){
+		case EMAC_MODE_AUTO:
+			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_AUTO_NEG);
+#elif defined(IAR_LPC_1768) /* Use IAR LPC1768 KickStart board */
+	if (((id1 << 16) | id2) == EMAC_KSZ8721BL_ID) {
+		/* Configure the PHY device */
+		switch(ulPHYMode){
+		case EMAC_MODE_AUTO:
+			/* Use auto-negotiation about the link speed. */
+			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_AUTO_NEG);
+//			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_BMCR_AN);
+#endif
+			/* Wait to complete Auto_Negotiation */
+			for (tout = EMAC_PHY_RESP_TOUT; tout; tout--) {
+				regv = read_PHY (EMAC_PHY_REG_BMSR);
+				if (regv & EMAC_PHY_BMSR_AUTO_DONE) {
+					/* Auto-negotiation Complete. */
+					break;
+				}
+				if (tout == 0){
+					// Time out, return error
+					return (-1);
+				}
+			}
+			break;
+		case EMAC_MODE_10M_FULL:
+			/* Connect at 10MBit full-duplex */
+			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_FULLD_10M);
+			break;
+		case EMAC_MODE_10M_HALF:
+			/* Connect at 10MBit half-duplex */
+			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_HALFD_10M);
+			break;
+		case EMAC_MODE_100M_FULL:
+			/* Connect at 100MBit full-duplex */
+			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_FULLD_100M);
+			break;
+		case EMAC_MODE_100M_HALF:
+			/* Connect at 100MBit half-duplex */
+			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_HALFD_100M);
+			break;
+		default:
+			// un-supported
+			return (-1);
+		}
+	}
+	// It's not correct module ID
+	else {
+		return (-1);
+	}
+
+	// Update EMAC configuration with current PHY status
+	if (EMAC_UpdatePHYStatus() < 0){
+		return (-1);
+	}
+
+	// Complete
+	return (0);
+}
+
+
+/*********************************************************************//**
+ * @brief		Auto-Configures value for the EMAC configuration register to
+ * 				match with current PHY mode
+ * @param[in]	None
+ * @return		Return (0) if no error, otherwise return (-1)
+ *
+ * Note: The EMAC configuration will be auto-configured:
+ * 		- Speed mode.
+ * 		- Half/Full duplex mode
+ **********************************************************************/
+int32_t EMAC_UpdatePHYStatus(void)
+{
+	int32_t regv, tout;
+
+	/* Check the link status. */
+#ifdef MCB_LPC_1768
+	for (tout = EMAC_PHY_RESP_TOUT; tout; tout--) {
+		regv = read_PHY (EMAC_PHY_REG_STS);
+		if (regv & EMAC_PHY_SR_LINK) {
+			/* Link is on. */
+			break;
+		}
+		if (tout == 0){
+			// time out
+			return (-1);
+		}
+	}
+	/* Configure Full/Half Duplex mode. */
+	if (regv & EMAC_PHY_SR_DUP) {
+	/* Full duplex is enabled. */
+			LPC_EMAC->MAC2    |= EMAC_MAC2_FULL_DUP;
+			LPC_EMAC->Command |= EMAC_CR_FULL_DUP;
+			LPC_EMAC->IPGT     = EMAC_IPGT_FULL_DUP;
+	} else {
+		/* Half duplex mode. */
+		LPC_EMAC->IPGT = EMAC_IPGT_HALF_DUP;
+	}
+	if (regv & EMAC_PHY_SR_SPEED) {
+	/* 10MBit mode. */
+		LPC_EMAC->SUPP = 0;
+	} else {
+		/* 100MBit mode. */
+		LPC_EMAC->SUPP = EMAC_SUPP_SPEED;
+	}
+#elif defined(IAR_LPC_1768)
+	for (tout = EMAC_PHY_RESP_TOUT; tout; tout--) {
+		regv = read_PHY (EMAC_PHY_REG_BMSR);
+		if (regv & EMAC_PHY_BMSR_LINK_STATUS) {
+			/* Link is on. */
+			break;
+		}
+		if (tout == 0){
+			// time out
+			return (-1);
+		}
+	}
+
+	/* Configure Full/Half Duplex mode. */
+	if (regv & EMAC_PHY_SR_FULL_DUP) {
+		/* Full duplex is enabled. */
+		LPC_EMAC->MAC2    |= EMAC_MAC2_FULL_DUP;
+		LPC_EMAC->Command |= EMAC_CR_FULL_DUP;
+		LPC_EMAC->IPGT     = EMAC_IPGT_FULL_DUP;
+	} else {
+		/* Half duplex mode. */
+		LPC_EMAC->IPGT = EMAC_IPGT_HALF_DUP;
+	}
+
+	/* Configure 100MBit/10MBit mode. */
+	if (!(regv & EMAC_PHY_SR_100_SPEED)) {
+		/* 10MBit mode. */
+		LPC_EMAC->SUPP = 0;
+	} else {
+		/* 100MBit mode. */
+		LPC_EMAC->SUPP = EMAC_SUPP_SPEED;
+	}
+#endif
+	// Complete
+	return (0);
+}
+
+
+/*********************************************************************//**
+ * @brief		Enable/Disable hash filter functionality for specified destination
+ * 				MAC address in EMAC module
+ * @param[in]	dstMAC_addr		Pointer to the first MAC destination address, should
+ * 								be 6-bytes length, in order LSB to the MSB
+ * @param[in]	NewState		New State of this command, should be:
+ *									- ENABLE.
+ *									- DISABLE.
+ * @return		None
+ *
+ * Note:
+ * The standard Ethernet cyclic redundancy check (CRC) function is calculated from
+ * the 6 byte destination address in the Ethernet frame (this CRC is calculated
+ * anyway as part of calculating the CRC of the whole frame), then bits [28:23] out of
+ * the 32 bits CRC result are taken to form the hash. The 6 bit hash is used to access
+ * the hash table: it is used as an index in the 64 bit HashFilter register that has been
+ * programmed with accept values. If the selected accept value is 1, the frame is
+ * accepted.
+ **********************************************************************/
+void EMAC_SetHashFilter(uint8_t dstMAC_addr[], FunctionalState NewState)
+{
+	uint32_t *pReg;
+	uint32_t tmp;
+	int32_t crc;
+
+	// Calculate the CRC from the destination MAC address
+	crc = emac_CRCCalc(dstMAC_addr, 6);
+	// Extract the value from CRC to get index value for hash filter table
+	crc = (crc >> 23) & 0x3F;
+
+	pReg = (crc > 31) ? ((uint32_t *)&LPC_EMAC->HashFilterH) \
+								: ((uint32_t *)&LPC_EMAC->HashFilterL);
+	tmp = (crc > 31) ? (crc - 32) : crc;
+	if (NewState == ENABLE) {
+		(*pReg) |= (1UL << tmp);
+	} else {
+		(*pReg) &= ~(1UL << tmp);
+	}
+	// Enable Rx Filter
+	LPC_EMAC->Command &= ~EMAC_CR_PASS_RX_FILT;
+}
+
+/*********************************************************************//**
+ * @brief		Enable/Disable Filter mode for each specified type EMAC peripheral
+ * @param[in]	ulFilterMode	Filter mode, should be:
+ * 								- EMAC_RFC_UCAST_EN: all frames of unicast types
+ * 								will be accepted
+ * 								- EMAC_RFC_BCAST_EN: broadcast frame will be
+ * 								accepted
+ * 								- EMAC_RFC_MCAST_EN: all frames of multicast
+ * 								types will be accepted
+ * 								- EMAC_RFC_UCAST_HASH_EN: The imperfect hash
+ * 								filter will be applied to unicast addresses
+ * 								- EMAC_RFC_MCAST_HASH_EN: The imperfect hash
+ * 								filter will be applied to multicast addresses
+ * 								- EMAC_RFC_PERFECT_EN: the destination address
+ * 								will be compared with the 6 byte station address
+ * 								programmed in the station address by the filter
+ * 								- EMAC_RFC_MAGP_WOL_EN: the result of the magic
+ * 								packet filter will generate a WoL interrupt when
+ * 								there is a match
+ * 								- EMAC_RFC_PFILT_WOL_EN: the result of the perfect address
+ * 								matching filter and the imperfect hash filter will
+ * 								generate a WoL interrupt when there is a match
+ * @param[in]	NewState	New State of this command, should be:
+ * 								- ENABLE
+ * 								- DISABLE
+ * @return		None
+ **********************************************************************/
+void EMAC_SetFilterMode(uint32_t ulFilterMode, FunctionalState NewState)
+{
+	if (NewState == ENABLE){
+		LPC_EMAC->RxFilterCtrl |= ulFilterMode;
+	} else {
+		LPC_EMAC->RxFilterCtrl &= ~ulFilterMode;
+	}
+}
+
+/*********************************************************************//**
+ * @brief		Get status of Wake On LAN Filter for each specified
+ * 				type in EMAC peripheral, clear this status if it is set
+ * @param[in]	ulWoLMode	WoL Filter mode, should be:
+ * 								- EMAC_WOL_UCAST: unicast frames caused WoL
+ * 								- EMAC_WOL_UCAST: broadcast frame caused WoL
+ * 								- EMAC_WOL_MCAST: multicast frame caused WoL
+ * 								- EMAC_WOL_UCAST_HASH: unicast frame that passes the
+ * 								imperfect hash filter caused WoL
+ * 								- EMAC_WOL_MCAST_HASH: multicast frame that passes the
+ * 								imperfect hash filter caused WoL
+ * 								- EMAC_WOL_PERFECT:perfect address matching filter
+ * 								caused WoL
+ * 								- EMAC_WOL_RX_FILTER: the receive filter caused WoL
+ * 								- EMAC_WOL_MAG_PACKET: the magic packet filter caused WoL
+ * @return		SET/RESET
+ **********************************************************************/
+FlagStatus EMAC_GetWoLStatus(uint32_t ulWoLMode)
+{
+	if (LPC_EMAC->RxFilterWoLStatus & ulWoLMode) {
+		LPC_EMAC->RxFilterWoLClear = ulWoLMode;
+		return SET;
+	} else {
+		return RESET;
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Write data to Tx packet data buffer at current index due to
+ * 				TxProduceIndex
+ * @param[in]	pDataStruct		Pointer to a EMAC_PACKETBUF_Type structure
+ * 							data that contain specified information about
+ * 							Packet data buffer.
+ * @return		None
+ **********************************************************************/
+void EMAC_WritePacketBuffer(EMAC_PACKETBUF_Type *pDataStruct)
+{
+	uint32_t idx,len;
+	uint32_t *sp,*dp;
+
+	idx = LPC_EMAC->TxProduceIndex;
+	sp  = (uint32_t *)pDataStruct->pbDataBuf;
+	dp  = (uint32_t *)Tx_Desc[idx].Packet;
+	/* Copy frame data to EMAC packet buffers. */
+	for (len = (pDataStruct->ulDataLen + 3) >> 2; len; len--) {
+		*dp++ = *sp++;
+	}
+	Tx_Desc[idx].Ctrl = (pDataStruct->ulDataLen - 1) | (EMAC_TCTRL_INT | EMAC_TCTRL_LAST);
+}
+
+/*********************************************************************//**
+ * @brief		Read data from Rx packet data buffer at current index due
+ * 				to RxConsumeIndex
+ * @param[in]	pDataStruct		Pointer to a EMAC_PACKETBUF_Type structure
+ * 							data that contain specified information about
+ * 							Packet data buffer.
+ * @return		None
+ **********************************************************************/
+void EMAC_ReadPacketBuffer(EMAC_PACKETBUF_Type *pDataStruct)
+{
+	uint32_t idx, len;
+	uint32_t *dp, *sp;
+
+	idx = LPC_EMAC->RxConsumeIndex;
+	dp = (uint32_t *)pDataStruct->pbDataBuf;
+	sp = (uint32_t *)Rx_Desc[idx].Packet;
+
+	if (pDataStruct->pbDataBuf != NULL) {
+		for (len = (pDataStruct->ulDataLen + 3) >> 2; len; len--) {
+			*dp++ = *sp++;
+		}
+	}
+}
+
+/*********************************************************************//**
+ * @brief 		Enable/Disable interrupt for each type in EMAC
+ * @param[in]	ulIntType	Interrupt Type, should be:
+ * 							- EMAC_INT_RX_OVERRUN: Receive Overrun
+ * 							- EMAC_INT_RX_ERR: Receive Error
+ * 							- EMAC_INT_RX_FIN: Receive Descriptor Finish
+ * 							- EMAC_INT_RX_DONE: Receive Done
+ * 							- EMAC_INT_TX_UNDERRUN: Transmit Under-run
+ * 							- EMAC_INT_TX_ERR: Transmit Error
+ * 							- EMAC_INT_TX_FIN: Transmit descriptor finish
+ * 							- EMAC_INT_TX_DONE: Transmit Done
+ * 							- EMAC_INT_SOFT_INT: Software interrupt
+ * 							- EMAC_INT_WAKEUP: Wakeup interrupt
+ * @param[in]	NewState	New State of this function, should be:
+ * 							- ENABLE.
+ * 							- DISABLE.
+ * @return		None
+ **********************************************************************/
+void EMAC_IntCmd(uint32_t ulIntType, FunctionalState NewState)
+{
+	if (NewState == ENABLE) {
+		LPC_EMAC->IntEnable |= ulIntType;
+	} else {
+		LPC_EMAC->IntEnable &= ~(ulIntType);
+	}
+}
+
+/*********************************************************************//**
+ * @brief 		Check whether if specified interrupt flag is set or not
+ * 				for each interrupt type in EMAC and clear interrupt pending
+ * 				if it is set.
+ * @param[in]	ulIntType	Interrupt Type, should be:
+ * 							- EMAC_INT_RX_OVERRUN: Receive Overrun
+ * 							- EMAC_INT_RX_ERR: Receive Error
+ * 							- EMAC_INT_RX_FIN: Receive Descriptor Finish
+ * 							- EMAC_INT_RX_DONE: Receive Done
+ * 							- EMAC_INT_TX_UNDERRUN: Transmit Under-run
+ * 							- EMAC_INT_TX_ERR: Transmit Error
+ * 							- EMAC_INT_TX_FIN: Transmit descriptor finish
+ * 							- EMAC_INT_TX_DONE: Transmit Done
+ * 							- EMAC_INT_SOFT_INT: Software interrupt
+ * 							- EMAC_INT_WAKEUP: Wakeup interrupt
+ * @return		New state of specified interrupt (SET or RESET)
+ **********************************************************************/
+IntStatus EMAC_IntGetStatus(uint32_t ulIntType)
+{
+	if (LPC_EMAC->IntStatus & ulIntType) {
+		LPC_EMAC->IntClear = ulIntType;
+		return SET;
+	} else {
+		return RESET;
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Check whether if the current RxConsumeIndex is not equal to the
+ * 				current RxProduceIndex.
+ * @param[in]	None
+ * @return		TRUE if they're not equal, otherwise return FALSE
+ *
+ * Note: In case the RxConsumeIndex is not equal to the RxProduceIndex,
+ * it means there're available data has been received. They should be read
+ * out and released the Receive Data Buffer by updating the RxConsumeIndex value.
+ **********************************************************************/
+Bool EMAC_CheckReceiveIndex(void)
+{
+	if (LPC_EMAC->RxConsumeIndex != LPC_EMAC->RxProduceIndex) {
+		return TRUE;
+	} else {
+		return FALSE;
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Check whether if the current TxProduceIndex is not equal to the
+ * 				current RxProduceIndex - 1.
+ * @param[in]	None
+ * @return		TRUE if they're not equal, otherwise return FALSE
+ *
+ * Note: In case the RxConsumeIndex is equal to the RxProduceIndex - 1,
+ * it means the transmit buffer is available and data can be written to transmit
+ * buffer to be sent.
+ **********************************************************************/
+Bool EMAC_CheckTransmitIndex(void)
+{
+	uint32_t tmp = LPC_EMAC->TxConsumeIndex -1;
+	if (LPC_EMAC->TxProduceIndex == tmp) {
+		return FALSE;
+	} else {
+		return TRUE;
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Get current status value of receive data (due to RxConsumeIndex)
+ * @param[in]	ulRxStatType	Received Status type, should be one of following:
+ * 							- EMAC_RINFO_CTRL_FRAME: Control Frame
+ * 							- EMAC_RINFO_VLAN: VLAN Frame
+ * 							- EMAC_RINFO_FAIL_FILT: RX Filter Failed
+ * 							- EMAC_RINFO_MCAST: Multicast Frame
+ * 							- EMAC_RINFO_BCAST: Broadcast Frame
+ * 							- EMAC_RINFO_CRC_ERR: CRC Error in Frame
+ * 							- EMAC_RINFO_SYM_ERR: Symbol Error from PHY
+ * 							- EMAC_RINFO_LEN_ERR: Length Error
+ * 							- EMAC_RINFO_RANGE_ERR: Range error(exceeded max size)
+ * 							- EMAC_RINFO_ALIGN_ERR: Alignment error
+ * 							- EMAC_RINFO_OVERRUN: Receive overrun
+ * 							- EMAC_RINFO_NO_DESCR: No new Descriptor available
+ * 							- EMAC_RINFO_LAST_FLAG: last Fragment in Frame
+ * 							- EMAC_RINFO_ERR: Error Occurred (OR of all error)
+ * @return		Current value of receive data (due to RxConsumeIndex)
+ **********************************************************************/
+FlagStatus EMAC_CheckReceiveDataStatus(uint32_t ulRxStatType)
+{
+	uint32_t idx;
+	idx = LPC_EMAC->RxConsumeIndex;
+	return (((Rx_Stat[idx].Info) & ulRxStatType) ? SET : RESET);
+}
+
+
+/*********************************************************************//**
+ * @brief		Get size of current Received data in received buffer (due to
+ * 				RxConsumeIndex)
+ * @param[in]	None
+ * @return		Size of received data
+ **********************************************************************/
+uint32_t EMAC_GetReceiveDataSize(void)
+{
+	uint32_t idx;
+	idx =LPC_EMAC->RxConsumeIndex;
+	return ((Rx_Stat[idx].Info) & EMAC_RINFO_SIZE);
+}
+
+/*********************************************************************//**
+ * @brief		Increase the RxConsumeIndex (after reading the Receive buffer
+ * 				to release the Receive buffer) and wrap-around the index if
+ * 				it reaches the maximum Receive Number
+ * @param[in]	None
+ * @return		None
+ **********************************************************************/
+void EMAC_UpdateRxConsumeIndex(void)
+{
+	// Get current Rx consume index
+	uint32_t idx = LPC_EMAC->RxConsumeIndex;
+
+	/* Release frame from EMAC buffer */
+	if (++idx == EMAC_NUM_RX_FRAG) idx = 0;
+	LPC_EMAC->RxConsumeIndex = idx;
+}
+
+/*********************************************************************//**
+ * @brief		Increase the TxProduceIndex (after writting to the Transmit buffer
+ * 				to enable the Transmit buffer) and wrap-around the index if
+ * 				it reaches the maximum Transmit Number
+ * @param[in]	None
+ * @return		None
+ **********************************************************************/
+void EMAC_UpdateTxProduceIndex(void)
+{
+	// Get current Tx produce index
+	uint32_t idx = LPC_EMAC->TxProduceIndex;
+
+	/* Start frame transmission */
+	if (++idx == EMAC_NUM_TX_FRAG) idx = 0;
+	LPC_EMAC->TxProduceIndex = idx;
+}
+
+
+/**
+ * @}
+ */
+
+#endif /* _EMAC */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
--- a/lpc17xx_emac.h	Sun Jun 12 11:23:03 2011 +0000
+++ b/lpc17xx_emac.h	Sun Jun 12 19:17:11 2011 +0000
@@ -68,8 +68,8 @@
 
 
 /* EMAC Memory Buffer configuration for 16K Ethernet RAM */
-#define EMAC_NUM_RX_FRAG         4           /**< Num.of RX Fragments 4*1536= 6.0kB */
-#define EMAC_NUM_TX_FRAG         3           /**< Num.of TX Fragments 3*1536= 4.6kB */
+#define EMAC_NUM_RX_FRAG         6           /**< Num.of RX Fragments 6*1536= 9kB */
+#define EMAC_NUM_TX_FRAG         4           /**< Num.of TX Fragments 4*1536= 6kB */
 #define EMAC_ETH_MAX_FLEN        1536        /**< Max. Ethernet Frame Size          */
 #define EMAC_TX_FRAME_TOUT       0x00100000  /**< Frame Transmit timeout count      */
 
@@ -673,8 +673,8 @@
 IntStatus EMAC_IntGetStatus(uint32_t ulIntType);
 
 /* EMAC Index functions -----------*/
-bool EMAC_CheckReceiveIndex(void);
-bool EMAC_CheckTransmitIndex(void);
+Bool EMAC_CheckReceiveIndex(void);
+Bool EMAC_CheckTransmitIndex(void);
 void EMAC_UpdateRxConsumeIndex(void);
 void EMAC_UpdateTxProduceIndex(void);
 
--- a/lpc17xx_pinsel.c	Sun Jun 12 11:23:03 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,306 +0,0 @@
-/***********************************************************************//**
- * @file        lpc17xx_pinsel.c
- * @brief        Contains all functions support for Pin connect block firmware
- *                 library on LPC17xx
- * @version        2.0
- * @date        21. May. 2010
- * @author        NXP MCU SW Application Team
- **************************************************************************
- * Software that is described herein is for illustrative purposes only
- * which provides customers with programming information regarding the
- * products. This software is supplied "AS IS" without any warranties.
- * NXP Semiconductors assumes no responsibility or liability for the
- * use of the software, conveys no license or title under any patent,
- * copyright, or mask work right to the product. NXP Semiconductors
- * reserves the right to make changes in the software without
- * notification. NXP Semiconductors also make no representation or
- * warranty that such application will be suitable for the specified
- * use without further testing or modification.
- **********************************************************************/
-
-/* Peripheral group ----------------------------------------------------------- */
-/** @addtogroup PINSEL
- * @{
- */
-
-/* Includes ------------------------------------------------------------------- */
-#include "lpc17xx_pinsel.h"
-
-/* Public Functions ----------------------------------------------------------- */
-
-static void set_PinFunc ( uint8_t portnum, uint8_t pinnum, uint8_t funcnum);
-static void set_ResistorMode ( uint8_t portnum, uint8_t pinnum, uint8_t modenum);
-static void set_OpenDrainMode( uint8_t portnum, uint8_t pinnum, uint8_t modenum);
-
-/*********************************************************************//**
- * @brief         Setup the pin selection function
- * @param[in]    portnum PORT number,
- *                 should be one of the following:
- *                 - PINSEL_PORT_0    : Port 0
- *                 - PINSEL_PORT_1    : Port 1
- *                 - PINSEL_PORT_2    : Port 2
- *                 - PINSEL_PORT_3    : Port 3
- *
- * @param[in]    pinnum    Pin number,
- *                 should be one of the following:
-                - PINSEL_PIN_0 : Pin 0
-                - PINSEL_PIN_1 : Pin 1
-                - PINSEL_PIN_2 : Pin 2
-                - PINSEL_PIN_3 : Pin 3
-                - PINSEL_PIN_4 : Pin 4
-                - PINSEL_PIN_5 : Pin 5
-                - PINSEL_PIN_6 : Pin 6
-                - PINSEL_PIN_7 : Pin 7
-                - PINSEL_PIN_8 : Pin 8
-                - PINSEL_PIN_9 : Pin 9
-                - PINSEL_PIN_10 : Pin 10
-                - PINSEL_PIN_11 : Pin 11
-                - PINSEL_PIN_12 : Pin 12
-                - PINSEL_PIN_13 : Pin 13
-                - PINSEL_PIN_14 : Pin 14
-                - PINSEL_PIN_15 : Pin 15
-                - PINSEL_PIN_16 : Pin 16
-                - PINSEL_PIN_17 : Pin 17
-                - PINSEL_PIN_18 : Pin 18
-                - PINSEL_PIN_19 : Pin 19
-                - PINSEL_PIN_20 : Pin 20
-                - PINSEL_PIN_21 : Pin 21
-                - PINSEL_PIN_22 : Pin 22
-                - PINSEL_PIN_23 : Pin 23
-                - PINSEL_PIN_24 : Pin 24
-                - PINSEL_PIN_25 : Pin 25
-                - PINSEL_PIN_26 : Pin 26
-                - PINSEL_PIN_27 : Pin 27
-                - PINSEL_PIN_28 : Pin 28
-                - PINSEL_PIN_29 : Pin 29
-                - PINSEL_PIN_30 : Pin 30
-                - PINSEL_PIN_31 : Pin 31
-
- * @param[in]     funcnum Function number,
- *                 should be one of the following:
- *                - PINSEL_FUNC_0 : default function
- *                - PINSEL_FUNC_1 : first alternate function
- *                - PINSEL_FUNC_2 : second alternate function
- *                - PINSEL_FUNC_3 : third alternate function
- *
- * @return         None
- **********************************************************************/
-static void set_PinFunc ( uint8_t portnum, uint8_t pinnum, uint8_t funcnum)
-{
-    uint32_t pinnum_t = pinnum;
-    uint32_t pinselreg_idx = 2 * portnum;
-    uint32_t *pPinCon = (uint32_t *)&LPC_PINCON->PINSEL0;
-
-    if (pinnum_t >= 16) {
-        pinnum_t -= 16;
-        pinselreg_idx++;
-    }
-    *(uint32_t *)(pPinCon + pinselreg_idx) &= ~(0x03UL << (pinnum_t * 2));
-    *(uint32_t *)(pPinCon + pinselreg_idx) |= ((uint32_t)funcnum) << (pinnum_t * 2);
-}
-
-/*********************************************************************//**
- * @brief         Setup resistor mode for each pin
- * @param[in]    portnum PORT number,
- *                 should be one of the following:
- *                 - PINSEL_PORT_0    : Port 0
- *                 - PINSEL_PORT_1    : Port 1
- *                 - PINSEL_PORT_2    : Port 2
- *                 - PINSEL_PORT_3    : Port 3
- * @param[in]    pinnum    Pin number,
- *                 should be one of the following:
-                - PINSEL_PIN_0 : Pin 0
-                - PINSEL_PIN_1 : Pin 1
-                - PINSEL_PIN_2 : Pin 2
-                - PINSEL_PIN_3 : Pin 3
-                - PINSEL_PIN_4 : Pin 4
-                - PINSEL_PIN_5 : Pin 5
-                - PINSEL_PIN_6 : Pin 6
-                - PINSEL_PIN_7 : Pin 7
-                - PINSEL_PIN_8 : Pin 8
-                - PINSEL_PIN_9 : Pin 9
-                - PINSEL_PIN_10 : Pin 10
-                - PINSEL_PIN_11 : Pin 11
-                - PINSEL_PIN_12 : Pin 12
-                - PINSEL_PIN_13 : Pin 13
-                - PINSEL_PIN_14 : Pin 14
-                - PINSEL_PIN_15 : Pin 15
-                - PINSEL_PIN_16 : Pin 16
-                - PINSEL_PIN_17 : Pin 17
-                - PINSEL_PIN_18 : Pin 18
-                - PINSEL_PIN_19 : Pin 19
-                - PINSEL_PIN_20 : Pin 20
-                - PINSEL_PIN_21 : Pin 21
-                - PINSEL_PIN_22 : Pin 22
-                - PINSEL_PIN_23 : Pin 23
-                - PINSEL_PIN_24 : Pin 24
-                - PINSEL_PIN_25 : Pin 25
-                - PINSEL_PIN_26 : Pin 26
-                - PINSEL_PIN_27 : Pin 27
-                - PINSEL_PIN_28 : Pin 28
-                - PINSEL_PIN_29 : Pin 29
-                - PINSEL_PIN_30 : Pin 30
-                - PINSEL_PIN_31 : Pin 31
-
- * @param[in]     modenum: Mode number,
- *                 should be one of the following:
-                - PINSEL_PINMODE_PULLUP    : Internal pull-up resistor
-                - PINSEL_PINMODE_TRISTATE : Tri-state
-                - PINSEL_PINMODE_PULLDOWN : Internal pull-down resistor
-
- * @return         None
- **********************************************************************/
-void set_ResistorMode ( uint8_t portnum, uint8_t pinnum, uint8_t modenum)
-{
-    uint32_t pinnum_t = pinnum;
-    uint32_t pinmodereg_idx = 2 * portnum;
-    uint32_t *pPinCon = (uint32_t *)&LPC_PINCON->PINMODE0;
-
-    if (pinnum_t >= 16) {
-        pinnum_t -= 16;
-        pinmodereg_idx++ ;
-    }
-
-    *(uint32_t *)(pPinCon + pinmodereg_idx) &= ~(0x03UL << (pinnum_t * 2));
-    *(uint32_t *)(pPinCon + pinmodereg_idx) |= ((uint32_t)modenum) << (pinnum_t * 2);
-}
-
-/*********************************************************************//**
- * @brief         Setup Open drain mode for each pin
- * @param[in]    portnum PORT number,
- *                 should be one of the following:
- *                 - PINSEL_PORT_0    : Port 0
- *                 - PINSEL_PORT_1    : Port 1
- *                 - PINSEL_PORT_2    : Port 2
- *                 - PINSEL_PORT_3    : Port 3
- *
- * @param[in]    pinnum    Pin number,
- *                 should be one of the following:
-                - PINSEL_PIN_0 : Pin 0
-                - PINSEL_PIN_1 : Pin 1
-                - PINSEL_PIN_2 : Pin 2
-                - PINSEL_PIN_3 : Pin 3
-                - PINSEL_PIN_4 : Pin 4
-                - PINSEL_PIN_5 : Pin 5
-                - PINSEL_PIN_6 : Pin 6
-                - PINSEL_PIN_7 : Pin 7
-                - PINSEL_PIN_8 : Pin 8
-                - PINSEL_PIN_9 : Pin 9
-                - PINSEL_PIN_10 : Pin 10
-                - PINSEL_PIN_11 : Pin 11
-                - PINSEL_PIN_12 : Pin 12
-                - PINSEL_PIN_13 : Pin 13
-                - PINSEL_PIN_14 : Pin 14
-                - PINSEL_PIN_15 : Pin 15
-                - PINSEL_PIN_16 : Pin 16
-                - PINSEL_PIN_17 : Pin 17
-                - PINSEL_PIN_18 : Pin 18
-                - PINSEL_PIN_19 : Pin 19
-                - PINSEL_PIN_20 : Pin 20
-                - PINSEL_PIN_21 : Pin 21
-                - PINSEL_PIN_22 : Pin 22
-                - PINSEL_PIN_23 : Pin 23
-                - PINSEL_PIN_24 : Pin 24
-                - PINSEL_PIN_25 : Pin 25
-                - PINSEL_PIN_26 : Pin 26
-                - PINSEL_PIN_27 : Pin 27
-                - PINSEL_PIN_28 : Pin 28
-                - PINSEL_PIN_29 : Pin 29
-                - PINSEL_PIN_30 : Pin 30
-                - PINSEL_PIN_31 : Pin 31
-
- * @param[in]    modenum  Open drain mode number,
- *                 should be one of the following:
- *                 - PINSEL_PINMODE_NORMAL : Pin is in the normal (not open drain) mode
- *                 - PINSEL_PINMODE_OPENDRAIN : Pin is in the open drain mode
- *
- * @return         None
- **********************************************************************/
-void set_OpenDrainMode( uint8_t portnum, uint8_t pinnum, uint8_t modenum)
-{
-    uint32_t *pPinCon = (uint32_t *)&LPC_PINCON->PINMODE_OD0;
-
-    if (modenum == PINSEL_PINMODE_OPENDRAIN){
-        *(uint32_t *)(pPinCon + portnum) |= (0x01UL << pinnum);
-    } else {
-        *(uint32_t *)(pPinCon + portnum) &= ~(0x01UL << pinnum);
-    }
-}
-
-/* End of Public Functions ---------------------------------------------------- */
-
-/* Public Functions ----------------------------------------------------------- */
-/** @addtogroup PINSEL_Public_Functions
- * @{
- */
-/*********************************************************************//**
- * @brief         Configure trace function
- * @param[in]     NewState State of the Trace function configuration,
- *                 should be one of the following:
- *                 - ENABLE : Enable Trace Function
- *                 - DISABLE : Disable Trace Function
- *
- * @return         None
- **********************************************************************/
-void PINSEL_ConfigTraceFunc(FunctionalState NewState)
-{
-    if (NewState == ENABLE) {
-        LPC_PINCON->PINSEL10 |= (0x01UL << 3);
-    } else if (NewState == DISABLE) {
-        LPC_PINCON->PINSEL10 &= ~(0x01UL << 3);
-    }
-}
-
-/*********************************************************************//**
- * @brief         Setup I2C0 pins
- * @param[in]    i2cPinMode I2C pin mode,
- *                 should be one of the following:
- *                 - PINSEL_I2C_Normal_Mode : The standard drive mode
- *                 - PINSEL_I2C_Fast_Mode : Fast Mode Plus drive mode
- *
- * @param[in]    filterSlewRateEnable  should be:
- *                 - ENABLE: Enable filter and slew rate.
- *                 - DISABLE: Disable filter and slew rate.
- *
- * @return         None
- **********************************************************************/
-void PINSEL_SetI2C0Pins(uint8_t i2cPinMode, FunctionalState filterSlewRateEnable)
-{
-    uint32_t regVal = 0;
-
-    if (i2cPinMode == PINSEL_I2C_Fast_Mode){
-        regVal = PINSEL_I2CPADCFG_SCLDRV0 | PINSEL_I2CPADCFG_SDADRV0;
-    }
-
-    if (filterSlewRateEnable == DISABLE){
-        regVal = PINSEL_I2CPADCFG_SCLI2C0 | PINSEL_I2CPADCFG_SDAI2C0;
-    }
-    LPC_PINCON->I2CPADCFG = regVal;
-}
-
-
-/*********************************************************************//**
- * @brief         Configure Pin corresponding to specified parameters passed
- *                 in the PinCfg
- * @param[in]    PinCfg    Pointer to a PINSEL_CFG_Type structure
- *                    that contains the configuration information for the
- *                    specified pin.
- * @return         None
- **********************************************************************/
-void PINSEL_ConfigPin(PINSEL_CFG_Type *PinCfg)
-{
-    set_PinFunc(PinCfg->Portnum, PinCfg->Pinnum, PinCfg->Funcnum);
-    set_ResistorMode(PinCfg->Portnum, PinCfg->Pinnum, PinCfg->Pinmode);
-    set_OpenDrainMode(PinCfg->Portnum, PinCfg->Pinnum, PinCfg->OpenDrain);
-}
-
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* --------------------------------- End Of File ------------------------------ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lpc17xx_pinsel.cpp	Sun Jun 12 19:17:11 2011 +0000
@@ -0,0 +1,306 @@
+/***********************************************************************//**
+ * @file        lpc17xx_pinsel.c
+ * @brief        Contains all functions support for Pin connect block firmware
+ *                 library on LPC17xx
+ * @version        2.0
+ * @date        21. May. 2010
+ * @author        NXP MCU SW Application Team
+ **************************************************************************
+ * Software that is described herein is for illustrative purposes only
+ * which provides customers with programming information regarding the
+ * products. This software is supplied "AS IS" without any warranties.
+ * NXP Semiconductors assumes no responsibility or liability for the
+ * use of the software, conveys no license or title under any patent,
+ * copyright, or mask work right to the product. NXP Semiconductors
+ * reserves the right to make changes in the software without
+ * notification. NXP Semiconductors also make no representation or
+ * warranty that such application will be suitable for the specified
+ * use without further testing or modification.
+ **********************************************************************/
+
+/* Peripheral group ----------------------------------------------------------- */
+/** @addtogroup PINSEL
+ * @{
+ */
+
+/* Includes ------------------------------------------------------------------- */
+#include "lpc17xx_pinsel.h"
+
+/* Public Functions ----------------------------------------------------------- */
+
+static void set_PinFunc ( uint8_t portnum, uint8_t pinnum, uint8_t funcnum);
+static void set_ResistorMode ( uint8_t portnum, uint8_t pinnum, uint8_t modenum);
+static void set_OpenDrainMode( uint8_t portnum, uint8_t pinnum, uint8_t modenum);
+
+/*********************************************************************//**
+ * @brief         Setup the pin selection function
+ * @param[in]    portnum PORT number,
+ *                 should be one of the following:
+ *                 - PINSEL_PORT_0    : Port 0
+ *                 - PINSEL_PORT_1    : Port 1
+ *                 - PINSEL_PORT_2    : Port 2
+ *                 - PINSEL_PORT_3    : Port 3
+ *
+ * @param[in]    pinnum    Pin number,
+ *                 should be one of the following:
+                - PINSEL_PIN_0 : Pin 0
+                - PINSEL_PIN_1 : Pin 1
+                - PINSEL_PIN_2 : Pin 2
+                - PINSEL_PIN_3 : Pin 3
+                - PINSEL_PIN_4 : Pin 4
+                - PINSEL_PIN_5 : Pin 5
+                - PINSEL_PIN_6 : Pin 6
+                - PINSEL_PIN_7 : Pin 7
+                - PINSEL_PIN_8 : Pin 8
+                - PINSEL_PIN_9 : Pin 9
+                - PINSEL_PIN_10 : Pin 10
+                - PINSEL_PIN_11 : Pin 11
+                - PINSEL_PIN_12 : Pin 12
+                - PINSEL_PIN_13 : Pin 13
+                - PINSEL_PIN_14 : Pin 14
+                - PINSEL_PIN_15 : Pin 15
+                - PINSEL_PIN_16 : Pin 16
+                - PINSEL_PIN_17 : Pin 17
+                - PINSEL_PIN_18 : Pin 18
+                - PINSEL_PIN_19 : Pin 19
+                - PINSEL_PIN_20 : Pin 20
+                - PINSEL_PIN_21 : Pin 21
+                - PINSEL_PIN_22 : Pin 22
+                - PINSEL_PIN_23 : Pin 23
+                - PINSEL_PIN_24 : Pin 24
+                - PINSEL_PIN_25 : Pin 25
+                - PINSEL_PIN_26 : Pin 26
+                - PINSEL_PIN_27 : Pin 27
+                - PINSEL_PIN_28 : Pin 28
+                - PINSEL_PIN_29 : Pin 29
+                - PINSEL_PIN_30 : Pin 30
+                - PINSEL_PIN_31 : Pin 31
+
+ * @param[in]     funcnum Function number,
+ *                 should be one of the following:
+ *                - PINSEL_FUNC_0 : default function
+ *                - PINSEL_FUNC_1 : first alternate function
+ *                - PINSEL_FUNC_2 : second alternate function
+ *                - PINSEL_FUNC_3 : third alternate function
+ *
+ * @return         None
+ **********************************************************************/
+static void set_PinFunc ( uint8_t portnum, uint8_t pinnum, uint8_t funcnum)
+{
+    uint32_t pinnum_t = pinnum;
+    uint32_t pinselreg_idx = 2 * portnum;
+    uint32_t *pPinCon = (uint32_t *)&LPC_PINCON->PINSEL0;
+
+    if (pinnum_t >= 16) {
+        pinnum_t -= 16;
+        pinselreg_idx++;
+    }
+    *(uint32_t *)(pPinCon + pinselreg_idx) &= ~(0x03UL << (pinnum_t * 2));
+    *(uint32_t *)(pPinCon + pinselreg_idx) |= ((uint32_t)funcnum) << (pinnum_t * 2);
+}
+
+/*********************************************************************//**
+ * @brief         Setup resistor mode for each pin
+ * @param[in]    portnum PORT number,
+ *                 should be one of the following:
+ *                 - PINSEL_PORT_0    : Port 0
+ *                 - PINSEL_PORT_1    : Port 1
+ *                 - PINSEL_PORT_2    : Port 2
+ *                 - PINSEL_PORT_3    : Port 3
+ * @param[in]    pinnum    Pin number,
+ *                 should be one of the following:
+                - PINSEL_PIN_0 : Pin 0
+                - PINSEL_PIN_1 : Pin 1
+                - PINSEL_PIN_2 : Pin 2
+                - PINSEL_PIN_3 : Pin 3
+                - PINSEL_PIN_4 : Pin 4
+                - PINSEL_PIN_5 : Pin 5
+                - PINSEL_PIN_6 : Pin 6
+                - PINSEL_PIN_7 : Pin 7
+                - PINSEL_PIN_8 : Pin 8
+                - PINSEL_PIN_9 : Pin 9
+                - PINSEL_PIN_10 : Pin 10
+                - PINSEL_PIN_11 : Pin 11
+                - PINSEL_PIN_12 : Pin 12
+                - PINSEL_PIN_13 : Pin 13
+                - PINSEL_PIN_14 : Pin 14
+                - PINSEL_PIN_15 : Pin 15
+                - PINSEL_PIN_16 : Pin 16
+                - PINSEL_PIN_17 : Pin 17
+                - PINSEL_PIN_18 : Pin 18
+                - PINSEL_PIN_19 : Pin 19
+                - PINSEL_PIN_20 : Pin 20
+                - PINSEL_PIN_21 : Pin 21
+                - PINSEL_PIN_22 : Pin 22
+                - PINSEL_PIN_23 : Pin 23
+                - PINSEL_PIN_24 : Pin 24
+                - PINSEL_PIN_25 : Pin 25
+                - PINSEL_PIN_26 : Pin 26
+                - PINSEL_PIN_27 : Pin 27
+                - PINSEL_PIN_28 : Pin 28
+                - PINSEL_PIN_29 : Pin 29
+                - PINSEL_PIN_30 : Pin 30
+                - PINSEL_PIN_31 : Pin 31
+
+ * @param[in]     modenum: Mode number,
+ *                 should be one of the following:
+                - PINSEL_PINMODE_PULLUP    : Internal pull-up resistor
+                - PINSEL_PINMODE_TRISTATE : Tri-state
+                - PINSEL_PINMODE_PULLDOWN : Internal pull-down resistor
+
+ * @return         None
+ **********************************************************************/
+void set_ResistorMode ( uint8_t portnum, uint8_t pinnum, uint8_t modenum)
+{
+    uint32_t pinnum_t = pinnum;
+    uint32_t pinmodereg_idx = 2 * portnum;
+    uint32_t *pPinCon = (uint32_t *)&LPC_PINCON->PINMODE0;
+
+    if (pinnum_t >= 16) {
+        pinnum_t -= 16;
+        pinmodereg_idx++ ;
+    }
+
+    *(uint32_t *)(pPinCon + pinmodereg_idx) &= ~(0x03UL << (pinnum_t * 2));
+    *(uint32_t *)(pPinCon + pinmodereg_idx) |= ((uint32_t)modenum) << (pinnum_t * 2);
+}
+
+/*********************************************************************//**
+ * @brief         Setup Open drain mode for each pin
+ * @param[in]    portnum PORT number,
+ *                 should be one of the following:
+ *                 - PINSEL_PORT_0    : Port 0
+ *                 - PINSEL_PORT_1    : Port 1
+ *                 - PINSEL_PORT_2    : Port 2
+ *                 - PINSEL_PORT_3    : Port 3
+ *
+ * @param[in]    pinnum    Pin number,
+ *                 should be one of the following:
+                - PINSEL_PIN_0 : Pin 0
+                - PINSEL_PIN_1 : Pin 1
+                - PINSEL_PIN_2 : Pin 2
+                - PINSEL_PIN_3 : Pin 3
+                - PINSEL_PIN_4 : Pin 4
+                - PINSEL_PIN_5 : Pin 5
+                - PINSEL_PIN_6 : Pin 6
+                - PINSEL_PIN_7 : Pin 7
+                - PINSEL_PIN_8 : Pin 8
+                - PINSEL_PIN_9 : Pin 9
+                - PINSEL_PIN_10 : Pin 10
+                - PINSEL_PIN_11 : Pin 11
+                - PINSEL_PIN_12 : Pin 12
+                - PINSEL_PIN_13 : Pin 13
+                - PINSEL_PIN_14 : Pin 14
+                - PINSEL_PIN_15 : Pin 15
+                - PINSEL_PIN_16 : Pin 16
+                - PINSEL_PIN_17 : Pin 17
+                - PINSEL_PIN_18 : Pin 18
+                - PINSEL_PIN_19 : Pin 19
+                - PINSEL_PIN_20 : Pin 20
+                - PINSEL_PIN_21 : Pin 21
+                - PINSEL_PIN_22 : Pin 22
+                - PINSEL_PIN_23 : Pin 23
+                - PINSEL_PIN_24 : Pin 24
+                - PINSEL_PIN_25 : Pin 25
+                - PINSEL_PIN_26 : Pin 26
+                - PINSEL_PIN_27 : Pin 27
+                - PINSEL_PIN_28 : Pin 28
+                - PINSEL_PIN_29 : Pin 29
+                - PINSEL_PIN_30 : Pin 30
+                - PINSEL_PIN_31 : Pin 31
+
+ * @param[in]    modenum  Open drain mode number,
+ *                 should be one of the following:
+ *                 - PINSEL_PINMODE_NORMAL : Pin is in the normal (not open drain) mode
+ *                 - PINSEL_PINMODE_OPENDRAIN : Pin is in the open drain mode
+ *
+ * @return         None
+ **********************************************************************/
+void set_OpenDrainMode( uint8_t portnum, uint8_t pinnum, uint8_t modenum)
+{
+    uint32_t *pPinCon = (uint32_t *)&LPC_PINCON->PINMODE_OD0;
+
+    if (modenum == PINSEL_PINMODE_OPENDRAIN){
+        *(uint32_t *)(pPinCon + portnum) |= (0x01UL << pinnum);
+    } else {
+        *(uint32_t *)(pPinCon + portnum) &= ~(0x01UL << pinnum);
+    }
+}
+
+/* End of Public Functions ---------------------------------------------------- */
+
+/* Public Functions ----------------------------------------------------------- */
+/** @addtogroup PINSEL_Public_Functions
+ * @{
+ */
+/*********************************************************************//**
+ * @brief         Configure trace function
+ * @param[in]     NewState State of the Trace function configuration,
+ *                 should be one of the following:
+ *                 - ENABLE : Enable Trace Function
+ *                 - DISABLE : Disable Trace Function
+ *
+ * @return         None
+ **********************************************************************/
+void PINSEL_ConfigTraceFunc(FunctionalState NewState)
+{
+    if (NewState == ENABLE) {
+        LPC_PINCON->PINSEL10 |= (0x01UL << 3);
+    } else if (NewState == DISABLE) {
+        LPC_PINCON->PINSEL10 &= ~(0x01UL << 3);
+    }
+}
+
+/*********************************************************************//**
+ * @brief         Setup I2C0 pins
+ * @param[in]    i2cPinMode I2C pin mode,
+ *                 should be one of the following:
+ *                 - PINSEL_I2C_Normal_Mode : The standard drive mode
+ *                 - PINSEL_I2C_Fast_Mode : Fast Mode Plus drive mode
+ *
+ * @param[in]    filterSlewRateEnable  should be:
+ *                 - ENABLE: Enable filter and slew rate.
+ *                 - DISABLE: Disable filter and slew rate.
+ *
+ * @return         None
+ **********************************************************************/
+void PINSEL_SetI2C0Pins(uint8_t i2cPinMode, FunctionalState filterSlewRateEnable)
+{
+    uint32_t regVal = 0;
+
+    if (i2cPinMode == PINSEL_I2C_Fast_Mode){
+        regVal = PINSEL_I2CPADCFG_SCLDRV0 | PINSEL_I2CPADCFG_SDADRV0;
+    }
+
+    if (filterSlewRateEnable == DISABLE){
+        regVal = PINSEL_I2CPADCFG_SCLI2C0 | PINSEL_I2CPADCFG_SDAI2C0;
+    }
+    LPC_PINCON->I2CPADCFG = regVal;
+}
+
+
+/*********************************************************************//**
+ * @brief         Configure Pin corresponding to specified parameters passed
+ *                 in the PinCfg
+ * @param[in]    PinCfg    Pointer to a PINSEL_CFG_Type structure
+ *                    that contains the configuration information for the
+ *                    specified pin.
+ * @return         None
+ **********************************************************************/
+void PINSEL_ConfigPin(PINSEL_CFG_Type *PinCfg)
+{
+    set_PinFunc(PinCfg->Portnum, PinCfg->Pinnum, PinCfg->Funcnum);
+    set_ResistorMode(PinCfg->Portnum, PinCfg->Pinnum, PinCfg->Pinmode);
+    set_OpenDrainMode(PinCfg->Portnum, PinCfg->Pinnum, PinCfg->OpenDrain);
+}
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
--- a/mbedNet.h	Sun Jun 12 11:23:03 2011 +0000
+++ b/mbedNet.h	Sun Jun 12 19:17:11 2011 +0000
@@ -17,12 +17,6 @@
 #include <stdint.h>
 
 
-#ifdef __cplusplus
-#define    CAPI
-#else
-#define    CAPI
-#endif    /* __cplusplus */
-
 enum Bool
 {
     False = 0,
@@ -31,7 +25,7 @@
 typedef enum Bool Bool_t;
 
 
-#define         DEBUG_ON        1
+#define        DEBUG_ON        1
 
 #define        NET_DEFAULT_TTL                    128            /* Default TTL */
 #define        NET_ENCAPSULATION_MAX_DEPTH        5            /* Maximum protocol encapsulation depth */
@@ -59,6 +53,8 @@
     mbedNetResult_NotEnoughMemory,
     mbedNetResult_TooManyInterfaces,
     mbedNetResult_InvalidInterface,
+    mbedNetResult_InterfaceAlreadyUp,
+    mbedNetResult_InterfaceAlreadyDown,
     mbedNetResult_TooManyPeriodicFunctions,
     mbedNetResult_TooManyDrivers,
     mbedNetResult_InvalidDriver,
--- a/mbedNetIF.c	Sun Jun 12 11:23:03 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,197 +0,0 @@
-/*
- * $Id: mbedNetIF.c 28 2011-06-10 10:16:30Z benoit $
- * $Author: benoit $
- * $Date: 2011-06-10 12:16:30 +0200 (ven., 10 juin 2011) $
- * $Rev: 28 $
- * 
- * 
- * 
- * 
- * 
- */
- 
-#include "mbedNetIF.h"
-#include "Ethernet.h"
-#include "mbedNet.h"
-#include "NetIF.h"
-#include "Debug.h"
-#include "lpc17xx_pinsel.h"
-#include "lpc17xx_emac.h"
-#include <string.h>
-
-
-#define    DEBUG_CURRENT_MODULE_NAME    "mbedNetIF"
-#define    DEBUG_CURRENT_MODULE_ID        DEBUG_MODULE_MBEDNETIF
-
-
-static int32_t Init(NetIF_t *netif);
-static int32_t Read(uint8_t **packet, int32_t *length);
-static int32_t Write(uint8_t *packet, int32_t length);
-static uint8_t *GetTxBuffer(void);
-
-
-#define    MBEDNETIF_DRIVER_NAME    "mbedEMAC"
-
-
-static EMAC_CFG_Type         Emac_Config;
-static PINSEL_CFG_Type        PinCfg;
-static uint8_t                rxPacket[EMAC_ETH_MAX_FLEN],
-                            txPacket[EMAC_ETH_MAX_FLEN];
-static EMAC_PACKETBUF_Type    rxBuffer,
-                            txBuffer;
-
-
-static Bool_t EMAC_TxBufferNotFull(void);
-
-
-NetIF_Driver_t mbedNetIF_Driver = 
-{ 
-    MBEDNETIF_DRIVER_NAME,  
-    Init, 
-    Read, 
-    Write, 
-    GetTxBuffer,
-    &ethernet,
-    EMAC_ETH_MAX_FLEN
-};
-
-
-static int32_t Init(NetIF_t *netIF)
-{
-    int32_t                result = 0;
-    uint8_t                initMac[6];
-    Ethernet_Addr_t        *hwAddress = (Ethernet_Addr_t *)netIF->driverParameter;
-
-    initMac[0] = hwAddress->MA0;
-    initMac[1] = hwAddress->MA1;
-    initMac[2] = hwAddress->MA2;
-    initMac[3] = hwAddress->MA3;
-    initMac[4] = hwAddress->MA4;
-    initMac[5] = hwAddress->MA5;
-    
-    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing device driver '%s' with hardware address %02x:%02x:%02x:%02x:%02x:%02x",
-        netIF->driver->name,
-        initMac[0],
-        initMac[1],
-        initMac[2],
-        initMac[3],
-        initMac[4],
-        initMac[5]
-    ));
-
-    rxBuffer.pbDataBuf = (uint32_t *)&rxPacket;
-    
-    PinCfg.Funcnum = 1;
-    PinCfg.OpenDrain = 0;
-    PinCfg.Pinmode = 0;
-    PinCfg.Portnum = 1;
-
-    PinCfg.Pinnum = 0;
-    PINSEL_ConfigPin(&PinCfg);
-    PinCfg.Pinnum = 1;
-    PINSEL_ConfigPin(&PinCfg);
-    PinCfg.Pinnum = 4;
-    PINSEL_ConfigPin(&PinCfg);
-    PinCfg.Pinnum = 8;
-    PINSEL_ConfigPin(&PinCfg);
-    PinCfg.Pinnum = 9;
-    PINSEL_ConfigPin(&PinCfg);
-    PinCfg.Pinnum = 10;
-    PINSEL_ConfigPin(&PinCfg);
-    PinCfg.Pinnum = 14;
-    PINSEL_ConfigPin(&PinCfg);
-    PinCfg.Pinnum = 15;
-    PINSEL_ConfigPin(&PinCfg);
-    PinCfg.Pinnum = 16;
-    PINSEL_ConfigPin(&PinCfg);
-    PinCfg.Pinnum = 17;
-    PINSEL_ConfigPin(&PinCfg);
-    
-    Emac_Config.Mode = EMAC_MODE_AUTO;
-    Emac_Config.pbEMAC_Addr = initMac;
-    
-    memset(txPacket, 0, sizeof(txPacket));
-    
-    if (EMAC_Init(&Emac_Config) == ERROR)
-    {
-        DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Error during initializing EMAC, restart after a while"));
-    }
-
-    Write(txPacket, 14);    /* Send dummy frame at init as workaround described in chapter 3.3 of errata sheet document 'ES_LPC176x' rev 9 from June 2011 page 6 */
-
-    goto Exit;
-
-Exit:
-    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE2, ("leaving with code %d", result));
-    return result;
-}
-
-
-static int32_t Read(uint8_t **packet, int32_t *length)
-{
-    int32_t        result = 0;
-
-
-    if (EMAC_CheckReceiveIndex() == FALSE)
-    {
-        mbedNet_LastError = mbedNetResult_QueueEmpty;
-        result = -1;
-        goto Exit;
-    }
-    rxBuffer.ulDataLen = EMAC_GetReceiveDataSize();
-    *length = rxBuffer.ulDataLen;
-    EMAC_ReadPacketBuffer(&rxBuffer);
-    EMAC_UpdateRxConsumeIndex();
-    
-    *packet = (uint8_t *)rxBuffer.pbDataBuf;
-    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("received %d byte frame", *length));
-    
-Exit:
-    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE2, ("leaving with code %d", result));
-    return result;
-}
-
-
-static int32_t Write(uint8_t *packet, int32_t length)
-{
-    int32_t        result = 0;
-    
-    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE2, ("request to send %d bytes", length));
-    
-    if (EMAC_TxBufferNotFull())
-    {
-        DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE0)
-        {
-            Debug_DumpBufferHex(packet, length);
-        }
-        txBuffer.ulDataLen = length;
-        txBuffer.pbDataBuf = (uint32_t *)packet;
-        EMAC_WritePacketBuffer(&txBuffer);
-        EMAC_UpdateTxProduceIndex();
-        DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("transmitted %d byte frame", length));
-    }
-    else
-    {
-        DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("transmission queue is full"));
-        mbedNet_LastError = mbedNetResult_QueueEmpty;
-        result = -1;
-    }
-    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE2, ("leaving with code %d", result));
-    return result;
-}
-
-
-static uint8_t *GetTxBuffer(void)
-{
-    return txPacket;
-}
-
-
-static Bool_t EMAC_TxBufferNotFull(void)
-{
-    uint32_t    tmp = LPC_EMAC->TxProduceIndex + 1;
-    
-    if (tmp == EMAC_NUM_TX_FRAG) tmp = 0;
-    return (LPC_EMAC->TxConsumeIndex != tmp) ? True : False;
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbedNetIF.cpp	Sun Jun 12 19:17:11 2011 +0000
@@ -0,0 +1,244 @@
+/*
+ * $Id: mbedNetIF.c 28 2011-06-10 10:16:30Z benoit $
+ * $Author: benoit $
+ * $Date: 2011-06-10 12:16:30 +0200 (ven., 10 juin 2011) $
+ * $Rev: 28 $
+ * 
+ * 
+ * 
+ * 
+ * 
+ */
+ 
+#include "mbedNetIF.h"
+#include "Ethernet.h"
+#include "mbedNet.h"
+#include "NetIF.h"
+#include "Debug.h"
+#include "lpc17xx_pinsel.h"
+#include "lpc17xx_emac.h"
+#include <string.h>
+
+
+#define    DEBUG_CURRENT_MODULE_NAME    "mbedNetIF"
+#define    DEBUG_CURRENT_MODULE_ID        DEBUG_MODULE_MBEDNETIF
+
+
+static int32_t Init(NetIF_t *netif);
+static int32_t Read(uint8_t **packet, int32_t *length);
+static int32_t Write(uint8_t *packet, int32_t length);
+static void Enable(void);
+static void Disable(void);
+static uint8_t *GetTxBuffer(void);
+
+
+#define    MBEDNETIF_DRIVER_NAME    "mbedEMAC"
+
+
+static EMAC_CFG_Type			Emac_Config;
+static PINSEL_CFG_Type			PinCfg;
+static uint8_t					rxPacket[EMAC_ETH_MAX_FLEN],
+								txPacket[EMAC_ETH_MAX_FLEN];
+static EMAC_PACKETBUF_Type		rxBuffer,
+								txBuffer;
+static NetIF_t					*mbedNetIF = NULL;
+
+static Bool_t EMAC_TxBufferNotFull(void);
+
+
+NetIF_Driver_t mbedNetIF_Driver = 
+{ 
+    MBEDNETIF_DRIVER_NAME,  
+    Init, 
+    Read, 
+    Write, 
+	Enable,
+	Disable,
+    GetTxBuffer,
+    &ethernet,
+    EMAC_ETH_MAX_FLEN
+};
+
+
+static int32_t Init(NetIF_t *netIF)
+{
+    int32_t                result = 0;
+    uint8_t                initMac[6];
+    Ethernet_Addr_t        *hwAddress = (Ethernet_Addr_t *)netIF->driverParameter;
+
+    initMac[0] = hwAddress->MA0;
+    initMac[1] = hwAddress->MA1;
+    initMac[2] = hwAddress->MA2;
+    initMac[3] = hwAddress->MA3;
+    initMac[4] = hwAddress->MA4;
+    initMac[5] = hwAddress->MA5;
+    
+    DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing device driver '%s' with hardware address %02x:%02x:%02x:%02x:%02x:%02x",
+        netIF->driver->name,
+        initMac[0],
+        initMac[1],
+        initMac[2],
+        initMac[3],
+        initMac[4],
+        initMac[5]
+    ));
+
+    rxBuffer.pbDataBuf = (uint32_t *)&rxPacket;
+	
+	mbedNetIF = netIF;
+    
+    PinCfg.Funcnum = 1;
+    PinCfg.OpenDrain = 0;
+    PinCfg.Pinmode = 0;
+    PinCfg.Portnum = 1;
+
+    PinCfg.Pinnum = 0;
+    PINSEL_ConfigPin(&PinCfg);
+    PinCfg.Pinnum = 1;
+    PINSEL_ConfigPin(&PinCfg);
+    PinCfg.Pinnum = 4;
+    PINSEL_ConfigPin(&PinCfg);
+    PinCfg.Pinnum = 8;
+    PINSEL_ConfigPin(&PinCfg);
+    PinCfg.Pinnum = 9;
+    PINSEL_ConfigPin(&PinCfg);
+    PinCfg.Pinnum = 10;
+    PINSEL_ConfigPin(&PinCfg);
+    PinCfg.Pinnum = 14;
+    PINSEL_ConfigPin(&PinCfg);
+    PinCfg.Pinnum = 15;
+    PINSEL_ConfigPin(&PinCfg);
+    PinCfg.Pinnum = 16;
+    PINSEL_ConfigPin(&PinCfg);
+    PinCfg.Pinnum = 17;
+    PINSEL_ConfigPin(&PinCfg);
+    
+    Emac_Config.Mode = EMAC_MODE_AUTO;
+    Emac_Config.pbEMAC_Addr = initMac;
+    
+    memset(txPacket, 0, sizeof(txPacket));
+    
+    if (EMAC_Init(&Emac_Config) == ERROR)
+    {
+        DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Error during initializing EMAC, restart after a while"));
+    }
+
+    Write(txPacket, 14);    /* Send dummy frame at init as workaround described in chapter 3.3 of errata sheet document 'ES_LPC176x' rev 9 from June 2011 page 6 */
+	
+	//NVIC_SetPriority(ENET_IRQn, 10);
+	
+	Disable();
+		
+    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE2, ("leaving with code %d", result));
+    return result;
+}
+
+
+static int32_t Read(uint8_t **packet, int32_t *length)
+{
+    int32_t        result = 0;
+
+    if (EMAC_CheckReceiveIndex() == FALSE)
+    {
+        mbedNet_LastError = mbedNetResult_QueueEmpty;
+        result = -1;
+    }
+	else
+	{
+	    rxBuffer.ulDataLen = EMAC_GetReceiveDataSize();
+	    *length = rxBuffer.ulDataLen;
+	    EMAC_ReadPacketBuffer(&rxBuffer);
+	    EMAC_UpdateRxConsumeIndex();
+	    
+	    *packet = (uint8_t *)rxBuffer.pbDataBuf;
+	    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("received %d byte frame", *length));
+	}
+    
+    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE2, ("leaving with code %d", result));
+    return result;
+}
+
+
+static int32_t Write(uint8_t *packet, int32_t length)
+{
+    int32_t        result = 0;
+    
+    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE2, ("request to send %d bytes", length));
+    
+    if (EMAC_TxBufferNotFull())
+    {
+        DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE0)
+        {
+            Debug_DumpBufferHex(packet, length);
+        }
+        txBuffer.ulDataLen = length;
+        txBuffer.pbDataBuf = (uint32_t *)packet;
+        EMAC_WritePacketBuffer(&txBuffer);
+        EMAC_UpdateTxProduceIndex();
+        DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("transmitted %d byte frame", length));
+    }
+    else
+    {
+        DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("transmission queue is full"));
+        mbedNet_LastError = mbedNetResult_QueueEmpty;
+        result = -1;
+    }
+    DEBUG_MODULE(DEBUG_LEVEL_VERBOSE2, ("leaving with code %d", result));
+    return result;
+}
+
+
+static void Enable(void)
+{
+	/* Enable receive and transmit mode of MAC Ethernet core */
+	LPC_EMAC->Command  |= (EMAC_CR_RX_EN | EMAC_CR_TX_EN);
+	LPC_EMAC->MAC1     |= EMAC_MAC1_REC_EN;	
+	NVIC_EnableIRQ(ENET_IRQn);
+}
+
+
+static void Disable(void)
+{
+	/* Disable receive and transmit mode of MAC Ethernet core */
+	NVIC_DisableIRQ(ENET_IRQn);
+	LPC_EMAC->Command  &= ~(EMAC_CR_RX_EN | EMAC_CR_TX_EN);
+	LPC_EMAC->MAC1     &= ~EMAC_MAC1_REC_EN;	
+	while(EMAC_CheckReceiveIndex()) EMAC_UpdateRxConsumeIndex();
+}
+
+
+static uint8_t *GetTxBuffer(void)
+{
+    return txPacket;
+}
+
+
+static Bool_t EMAC_TxBufferNotFull(void)
+{
+    uint32_t    tmp = LPC_EMAC->TxProduceIndex + 1;
+    
+    if (tmp == EMAC_NUM_TX_FRAG) tmp = 0;
+    return (LPC_EMAC->TxConsumeIndex != tmp) ? True : False;
+}
+
+
+extern "C" void ENET_IRQHandler(void)
+{
+	uint32_t 		status;
+	Packet_t		rxP;
+	
+	status = LPC_EMAC->IntStatus;
+	LPC_EMAC->IntClear = status;
+	
+	if(status & EMAC_INT_RX_DONE) 
+	{
+		while(EMAC_CheckReceiveIndex() == TRUE)
+		{
+			if (Read(&rxP.data, &rxP.length) == 0)
+			{
+				rxP.depth = -1;
+				ethernet.HandlePacket(mbedNetIF, &rxP);
+			}
+		}
+	}
+}