Benoît Locher / mbedNet
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