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.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers NetIF.cpp Source File

NetIF.cpp

00001 /*
00002  * $Id: NetIF.c 29 2011-06-11 14:53:08Z benoit $
00003  * $Author: benoit $
00004  * $Date: 2011-06-11 16:53:08 +0200 (sam., 11 juin 2011) $
00005  * $Rev: 29 $
00006  * 
00007  * 
00008  * 
00009  * 
00010  * 
00011  */
00012  
00013 #include "NetIF.h"
00014 #include "Ethernet.h"
00015 #include "ARP.h"
00016 #include "Debug.h"
00017 #include <string.h>
00018 
00019 
00020 #define    DEBUG_CURRENT_MODULE_NAME    "NetIF"
00021 #define    DEBUG_CURRENT_MODULE_ID        DEBUG_MODULE_NETIF
00022 
00023 
00024 struct PeriodicFunctionTimer
00025 {
00026     char                *name;
00027     PeriodicFunction_t    function;
00028     FunctionPeriod_t    period;
00029     int32_t                age;
00030 };
00031 typedef struct PeriodicFunctionTimer PeriodicFunctionTimer_t;
00032 
00033 
00034 static NetIF_t                    netIF_Table[NETIF_MAX_COUNT];
00035 static int32_t                    netIF_Count = 0;
00036 static RTOS_Mutex_t                netIF_TableMutex;
00037 
00038 static PeriodicFunctionTimer_t    netIF_PeriodicFunctionTable[NET_PERIODIC_FUNCTION_MAX_COUNT];
00039 static int32_t                    netIF_PeriodicFunctionCount = 0;
00040 static RTOS_Mutex_t                netIF_PeriodicFunctionTableMutex;
00041 
00042 static Bool_t                    netIFLayerInitialized = False;
00043 static NetPacket_t                    rxPacket,
00044                                 txPacket;
00045 static int32_t                    gatewayNetIFIndex = -1;
00046 
00047 
00048 static void  NetIF_Init(void);
00049 
00050 
00051 mbedNetResult_t                    mbedNet_LastError;
00052 const char                         *protocol_IDNames[Protocol_ID_Count] = 
00053 {
00054     "Ethernet",
00055     "ARP",
00056     "IPv4",
00057     "ICMPv4",
00058     "UDPv4",
00059     "TCPv4",
00060 };
00061 
00062 
00063 const char                        *api_IDNames[API_ID_Count] = 
00064 {
00065     "sockets"
00066 };
00067 
00068 
00069 static void NetIF_Init(void)
00070 {
00071     mbedNet_LastError = mbedNetResult_Success;
00072     
00073     DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing NetIF layer"));
00074     
00075     netIF_Count = 0;
00076     memset(netIF_Table, 0, sizeof(netIF_Table));
00077     netIF_TableMutex = RTOS_MUTEX_CREATE();
00078     
00079     netIF_PeriodicFunctionCount = 0;
00080     memset(netIF_PeriodicFunctionTable, 0, sizeof(netIF_PeriodicFunctionTable));
00081     netIF_PeriodicFunctionTableMutex = RTOS_MUTEX_CREATE();
00082     
00083     memset(&rxPacket, 0, sizeof(rxPacket));
00084     memset(&txPacket, 0, sizeof(txPacket));
00085     
00086     gatewayNetIFIndex = -1;
00087     
00088     netIFLayerInitialized = True;
00089 }
00090 
00091 
00092 NetIF_t *NetIF_RegisterInterface(IPv4_Addr_t *address, IPv4_Addr_t *netmask, IPv4_Addr_t *gateway, NetIF_Driver_t *driver , void *driverParameter)
00093 {
00094     NetIF_t            *netIF = NULL;
00095 
00096     if (netIFLayerInitialized == False)
00097     {
00098         NetIF_Init();
00099     }
00100 
00101     if (netIF_Count >= NETIF_MAX_COUNT)
00102     {
00103         DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Too many interfaces registered"));
00104         mbedNet_LastError = mbedNetResult_TooManyInterfaces;
00105         goto Exit;
00106     }
00107 
00108     if (driver == NULL)
00109     {
00110         DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Invalid driver specified"));
00111         mbedNet_LastError = mbedNetResult_InvalidDriver;
00112         goto Exit;
00113     }
00114 
00115     RTOS_MUTEX_LOCK(netIF_TableMutex);
00116     netIF = netIF_Table + netIF_Count;
00117     netIF->index = netIF_Count;
00118     netIF->name = "en";
00119     netIF->ipv4Address = *address;
00120     netIF->ipv4Netmask = *netmask;
00121     netIF->ipv4Network.addr = address->addr & netmask->addr;
00122     netIF->ipv4Gateway = *gateway;
00123     netIF->ipv4Broadcast.addr = (address->addr & netmask->addr) | (~netmask->addr);
00124     netIF->driverParameter = driverParameter;
00125     netIF->driver = driver;
00126     netIF->driver->Init(netIF);
00127     netIF->driver->protocolHandler->Init();
00128     
00129     if (gateway != NULL)
00130     {
00131         gatewayNetIFIndex = netIF_Count;
00132     }
00133     
00134     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'",
00135         netIF->name,
00136         netIF_Count,
00137         netIF->ipv4Address.IP0, netIF->ipv4Address.IP1, netIF->ipv4Address.IP2, netIF->ipv4Address.IP3,
00138         netIF->ipv4Netmask.IP0, netIF->ipv4Netmask.IP1, netIF->ipv4Netmask.IP2, netIF->ipv4Netmask.IP3,
00139         netIF->ipv4Gateway.IP0, netIF->ipv4Gateway.IP1, netIF->ipv4Gateway.IP2, netIF->ipv4Gateway.IP3,
00140         netIF->driver->name
00141     ));
00142     
00143     netIF_Count++;
00144     RTOS_MUTEX_UNLOCK(netIF_TableMutex);
00145     
00146 Exit:
00147     return netIF;
00148 }
00149 
00150 
00151 /*
00152 int32_t NetIF_ProcessFrames(void)
00153 {
00154     NetIF_Index_t        netIFIndex;
00155     NetIF_t                *netIF;
00156     int32_t                result = 0, 
00157                         readResult;
00158 
00159     DEBUG_SOURCE(DEBUG_LEVEL_VERBOSE2, ("enter"));
00160     RTOS_MUTEX_LOCK(netIF_TableMutex);
00161     for (netIFIndex = 0; netIFIndex < netIF_Count; netIFIndex++)
00162     {
00163         netIF = netIF_Table + netIFIndex;
00164         readResult = netIF->driver->Read(&rxPacket.data, &rxPacket.length);
00165         if (readResult == 0)
00166         {
00167             rxPacket.depth = -1;
00168             netIF->driver->protocolHandler->HandlePacket(netIF, &rxPacket);
00169         }
00170     }
00171     RTOS_MUTEX_UNLOCK(netIF_TableMutex);
00172     
00173     DEBUG_SOURCE(DEBUG_LEVEL_VERBOSE2, ("leave"));
00174     return result;
00175 }
00176 */
00177 
00178 
00179 int32_t NetIF_RegisterPeriodicFunction(char *name, PeriodicFunction_t function, FunctionPeriod_t period)
00180 {
00181     int32_t                        result = 0;
00182     PeriodicFunctionTimer_t        *timerEntry;
00183 
00184     if (netIF_PeriodicFunctionCount >= NET_PERIODIC_FUNCTION_MAX_COUNT)
00185     {
00186         DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Too many periodic functions registered"));
00187         mbedNet_LastError = mbedNetResult_TooManyPeriodicFunctions;
00188         goto Exit;
00189     }
00190     
00191     RTOS_MUTEX_LOCK(netIF_PeriodicFunctionTableMutex);
00192     timerEntry = netIF_PeriodicFunctionTable + netIF_PeriodicFunctionCount;
00193     timerEntry->name = name;
00194     timerEntry->function = function;
00195     timerEntry->period = period;
00196     timerEntry->age = 0;
00197     
00198     DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Registered periodic function '%s' with period %d seconds",
00199         name, 
00200         period
00201     ));
00202     
00203     netIF_PeriodicFunctionCount++;
00204     RTOS_MUTEX_UNLOCK(netIF_PeriodicFunctionTableMutex);
00205 
00206 Exit:
00207     return result;    
00208 }
00209 
00210 
00211 int32_t NetIF_ProcessTimers(int32_t elapsedTime)
00212 {
00213     int32_t                        result = 0,
00214                                 timerIndex;
00215     PeriodicFunctionTimer_t        *timerEntry;
00216     static int64_t                seconds = 0;
00217     
00218     seconds++;
00219     
00220     RTOS_MUTEX_LOCK(netIF_PeriodicFunctionTableMutex);
00221     for (timerIndex = 0; timerIndex < netIF_PeriodicFunctionCount; timerIndex++)
00222     {
00223         timerEntry = netIF_PeriodicFunctionTable + timerIndex;
00224         if (elapsedTime == 0)
00225         {
00226             timerEntry->age = 0;
00227             continue;
00228         }
00229         
00230         timerEntry->age += elapsedTime;
00231         if (timerEntry->age >= timerEntry->period)
00232         {
00233             timerEntry->age = 0;
00234             timerEntry->function();
00235         }
00236     }
00237     RTOS_MUTEX_UNLOCK(netIF_PeriodicFunctionTableMutex);
00238     
00239     return result;        
00240 }
00241 
00242 
00243 int32_t NetIF_SendIPv4Packet(IPv4_Header_t *ipv4Header)
00244 {
00245     int32_t                result = -1, 
00246                         mtu,
00247                         lengthToSend;
00248     NetIF_Index_t        netIFIndex;
00249     NetIF_t                *netIF = NULL;
00250     Ethernet_Header_t    *ethernetHeader;
00251     Bool_t                useGateway = False;
00252 
00253     RTOS_MUTEX_LOCK(netIF_TableMutex);
00254     
00255     /* Look for netif having same network */
00256     for (netIFIndex = 0; netIFIndex < netIF_Count; netIFIndex++)
00257     {
00258         netIF = netIF_Table + netIFIndex;
00259         if ( (netIF->up) && ((netIF->ipv4Netmask.addr & ipv4Header->dest.addr) == netIF->ipv4Network.addr)) break;
00260         netIF = NULL;
00261     }
00262     
00263     /* if not found, use gateway netif */
00264     if ((netIF == NULL) && (gatewayNetIFIndex >= 0))
00265     {
00266         netIF = netIF_Table + gatewayNetIFIndex;
00267         if (netIF->up)
00268         {
00269             DEBUG_MODULE(DEBUG_LEVEL_INFO, ("using gateway %d.%d.%d.%d to talk to %d.%d.%d.%d",
00270                 netIF->ipv4Gateway.IP0,    
00271                 netIF->ipv4Gateway.IP1,    
00272                 netIF->ipv4Gateway.IP2,    
00273                 netIF->ipv4Gateway.IP3,    
00274 
00275                 ipv4Header->dest.IP0,
00276                 ipv4Header->dest.IP1,
00277                 ipv4Header->dest.IP2,
00278                 ipv4Header->dest.IP3
00279             ));
00280             useGateway = True;
00281         }
00282     }
00283     
00284     /* Still no interface able to send, then return error */
00285     if (netIF == NULL)
00286     {
00287         DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("No route to host"));
00288         mbedNet_LastError = mbedNetResult_NoRouteToHost;
00289         goto Exit;
00290     }
00291     
00292     /* Prepare to send the IPv4 packet */
00293     mtu = netIF->driver->mtu;
00294     
00295     lengthToSend = (sizeof(Ethernet_Header_t) + ntohs(ipv4Header->totalLength));
00296     /* Check that total length doesn't exceed MTU */
00297     if (lengthToSend > mtu)
00298     {
00299         DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Too much data: %d bytes", lengthToSend));
00300         mbedNet_LastError = mbedNetResult_TooMuchData;
00301         goto Exit;
00302     }
00303     
00304     /* Set source address and compute checksum of IPv4 header */
00305     ipv4Header->source.addr = netIF->ipv4Address.addr;
00306     ipv4Header->crc = 0;
00307     ipv4Header->crc = IPv4_ComputeCRC(ipv4Header);
00308     
00309     /* Prepare packet with ethernet data */
00310     txPacket.depth = -1;
00311     txPacket.length = lengthToSend;
00312     txPacket.data = netIF->driver->GetTxBuffer();
00313     ethernetHeader = (Ethernet_Header_t *)txPacket.data;
00314     
00315     /* Copy destination MAC address */
00316     if (useGateway)
00317     {
00318         while (ARP_ResolveIPv4Address(netIF, netIF->ipv4Gateway, &ethernetHeader->destination) == -1)
00319         {
00320             DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("%d.%d.%d.%d not in ARP cache",
00321                 netIF->ipv4Gateway.IP0,
00322                 netIF->ipv4Gateway.IP1,
00323                 netIF->ipv4Gateway.IP2,
00324                 netIF->ipv4Gateway.IP3
00325             ));
00326         }
00327     }
00328     else
00329     {
00330         while (ARP_ResolveIPv4Address(netIF, ipv4Header->dest, &ethernetHeader->destination) == -1)
00331         {
00332             DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("%d.%d.%d.%d not in ARP cache",
00333                 ipv4Header->dest.IP0,
00334                 ipv4Header->dest.IP1,
00335                 ipv4Header->dest.IP2,
00336                 ipv4Header->dest.IP3
00337             ));
00338         }
00339     }
00340     
00341     DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("IPv4 sending %d bytes %d.%d.%d.%d --> %d.%d.%d.%d using %s%d",
00342         ntohs(ipv4Header->totalLength),
00343         
00344         ipv4Header->source.IP0,
00345         ipv4Header->source.IP1,
00346         ipv4Header->source.IP2,
00347         ipv4Header->source.IP3,
00348         
00349         ipv4Header->dest.IP0,
00350         ipv4Header->dest.IP1,
00351         ipv4Header->dest.IP2,
00352         ipv4Header->dest.IP3,
00353         
00354         netIF->name,
00355         netIF->index
00356     ));
00357 
00358     /* Copy source MAC address */
00359     memcpy(&ethernetHeader->source, (uint8_t *)netIF->driverParameter, 6);
00360     ethernetHeader->protocol = htons(ETHERNET_PROTO_IPV4);
00361     NetIF_ProtoPush(&txPacket, sizeof(Ethernet_Header_t), Protocol_ID_Ethernet);
00362     
00363     /* Copy ethernet payload */
00364     //ipv4Header = (IPv4_Header_t *)txPacket.data;
00365     memcpy(txPacket.data, ipv4Header, ntohs(ipv4Header->totalLength));
00366     NetIF_ProtoPop(&txPacket);
00367     
00368     /* Send packet */
00369     result = netIF->driver->Write(txPacket.data, txPacket.length);
00370         
00371 Exit:
00372     RTOS_MUTEX_UNLOCK(netIF_TableMutex);
00373     return result;
00374 }
00375 
00376 
00377 int32_t NetIF_Up(NetIF_t *netIF)
00378 {
00379     int32_t result = 0;
00380 
00381     if (netIF->up)
00382     {
00383         result = -1;
00384         mbedNet_LastError = mbedNetResult_InterfaceAlreadyUp;
00385         goto Exit;
00386     }
00387     
00388     netIF->driver->Enable();
00389     netIF->up = True;
00390     
00391 Exit:
00392     return result;
00393 }
00394 
00395 
00396 int32_t NetIF_Down(NetIF_t *netIF)
00397 {
00398     int32_t result = 0;
00399 
00400     if (!netIF->up)
00401     {
00402         result = -1;
00403         mbedNet_LastError = mbedNetResult_InterfaceAlreadyDown;
00404         goto Exit;
00405     }
00406     
00407     netIF->driver->Disable();
00408     netIF->up = False;
00409     
00410 Exit:
00411     return result;
00412 }
00413 
00414 
00415 void NetIF_ProtoPop(NetPacket_t *packet)
00416 {
00417     static int32_t    depth, headerSize, index;
00418     
00419     DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length));
00420     if (packet->depth >= 0)
00421     {    
00422         depth = packet->depth;
00423         headerSize = packet->headerLenTable[depth];
00424         
00425         packet->data -= headerSize;
00426         packet->length += headerSize;
00427     
00428         packet->depth--;
00429     }
00430     
00431     DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("  > Decapsulate: "));
00432     DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE1)
00433     {
00434         for (index = 0; index <= packet->depth; index++)
00435         {
00436             DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("  > %d %s header:%d bytes", index, protocol_IDNames[packet->protocolTable[index]], packet->headerLenTable[index]));
00437         }
00438     }
00439     DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length));
00440 }
00441 
00442 
00443 void NetIF_ProtoPush(NetPacket_t *packet, int32_t headerSize, Protocol_ID_t protocol)
00444 {
00445     static int32_t    depth, index;
00446     
00447     DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length));
00448     
00449     packet->depth++;
00450     depth = packet->depth;
00451     
00452     packet->headerPtrTable[depth] = packet->data;
00453     packet->headerLenTable[depth] = headerSize;
00454     packet->protocolTable[depth] = protocol;
00455     packet->data += headerSize;
00456     packet->length -= headerSize;
00457     
00458     DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("  > Encapsulate: "));
00459     DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE1)
00460     {
00461         for (index = 0; index <= depth; index++)
00462         {
00463             DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("  > %d %s header:%d bytes", index, protocol_IDNames[packet->protocolTable[index]], packet->headerLenTable[index]));
00464         }
00465     }
00466     DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length));
00467 }
00468