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.
NetIF.cpp@5:3cd83fcb1467, 2011-06-13 (annotated)
- Committer:
- Benoit
- Date:
- Mon Jun 13 13:13:59 2011 +0000
- Revision:
- 5:3cd83fcb1467
- Parent:
- 2:3d1c0fbd10e6
Renamed some types to avoid conflicts with other objects
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Benoit | 1:f4040665bc61 | 1 | /* |
Benoit | 1:f4040665bc61 | 2 | * $Id: NetIF.c 29 2011-06-11 14:53:08Z benoit $ |
Benoit | 1:f4040665bc61 | 3 | * $Author: benoit $ |
Benoit | 1:f4040665bc61 | 4 | * $Date: 2011-06-11 16:53:08 +0200 (sam., 11 juin 2011) $ |
Benoit | 1:f4040665bc61 | 5 | * $Rev: 29 $ |
Benoit | 1:f4040665bc61 | 6 | * |
Benoit | 1:f4040665bc61 | 7 | * |
Benoit | 1:f4040665bc61 | 8 | * |
Benoit | 1:f4040665bc61 | 9 | * |
Benoit | 1:f4040665bc61 | 10 | * |
Benoit | 1:f4040665bc61 | 11 | */ |
Benoit | 1:f4040665bc61 | 12 | |
Benoit | 1:f4040665bc61 | 13 | #include "NetIF.h" |
Benoit | 1:f4040665bc61 | 14 | #include "Ethernet.h" |
Benoit | 1:f4040665bc61 | 15 | #include "ARP.h" |
Benoit | 1:f4040665bc61 | 16 | #include "Debug.h" |
Benoit | 1:f4040665bc61 | 17 | #include <string.h> |
Benoit | 1:f4040665bc61 | 18 | |
Benoit | 1:f4040665bc61 | 19 | |
Benoit | 1:f4040665bc61 | 20 | #define DEBUG_CURRENT_MODULE_NAME "NetIF" |
Benoit | 1:f4040665bc61 | 21 | #define DEBUG_CURRENT_MODULE_ID DEBUG_MODULE_NETIF |
Benoit | 1:f4040665bc61 | 22 | |
Benoit | 1:f4040665bc61 | 23 | |
Benoit | 1:f4040665bc61 | 24 | struct PeriodicFunctionTimer |
Benoit | 1:f4040665bc61 | 25 | { |
Benoit | 1:f4040665bc61 | 26 | char *name; |
Benoit | 1:f4040665bc61 | 27 | PeriodicFunction_t function; |
Benoit | 1:f4040665bc61 | 28 | FunctionPeriod_t period; |
Benoit | 1:f4040665bc61 | 29 | int32_t age; |
Benoit | 1:f4040665bc61 | 30 | }; |
Benoit | 1:f4040665bc61 | 31 | typedef struct PeriodicFunctionTimer PeriodicFunctionTimer_t; |
Benoit | 1:f4040665bc61 | 32 | |
Benoit | 1:f4040665bc61 | 33 | |
Benoit | 1:f4040665bc61 | 34 | static NetIF_t netIF_Table[NETIF_MAX_COUNT]; |
Benoit | 1:f4040665bc61 | 35 | static int32_t netIF_Count = 0; |
Benoit | 1:f4040665bc61 | 36 | static RTOS_Mutex_t netIF_TableMutex; |
Benoit | 1:f4040665bc61 | 37 | |
Benoit | 1:f4040665bc61 | 38 | static PeriodicFunctionTimer_t netIF_PeriodicFunctionTable[NET_PERIODIC_FUNCTION_MAX_COUNT]; |
Benoit | 1:f4040665bc61 | 39 | static int32_t netIF_PeriodicFunctionCount = 0; |
Benoit | 1:f4040665bc61 | 40 | static RTOS_Mutex_t netIF_PeriodicFunctionTableMutex; |
Benoit | 1:f4040665bc61 | 41 | |
Benoit | 1:f4040665bc61 | 42 | static Bool_t netIFLayerInitialized = False; |
Benoit | 5:3cd83fcb1467 | 43 | static NetPacket_t rxPacket, |
Benoit | 1:f4040665bc61 | 44 | txPacket; |
Benoit | 1:f4040665bc61 | 45 | static int32_t gatewayNetIFIndex = -1; |
Benoit | 1:f4040665bc61 | 46 | |
Benoit | 1:f4040665bc61 | 47 | |
Benoit | 1:f4040665bc61 | 48 | static void NetIF_Init(void); |
Benoit | 1:f4040665bc61 | 49 | |
Benoit | 1:f4040665bc61 | 50 | |
Benoit | 1:f4040665bc61 | 51 | mbedNetResult_t mbedNet_LastError; |
Benoit | 1:f4040665bc61 | 52 | const char *protocol_IDNames[Protocol_ID_Count] = |
Benoit | 1:f4040665bc61 | 53 | { |
Benoit | 1:f4040665bc61 | 54 | "Ethernet", |
Benoit | 1:f4040665bc61 | 55 | "ARP", |
Benoit | 1:f4040665bc61 | 56 | "IPv4", |
Benoit | 1:f4040665bc61 | 57 | "ICMPv4", |
Benoit | 1:f4040665bc61 | 58 | "UDPv4", |
Benoit | 1:f4040665bc61 | 59 | "TCPv4", |
Benoit | 1:f4040665bc61 | 60 | }; |
Benoit | 1:f4040665bc61 | 61 | |
Benoit | 1:f4040665bc61 | 62 | |
Benoit | 1:f4040665bc61 | 63 | const char *api_IDNames[API_ID_Count] = |
Benoit | 1:f4040665bc61 | 64 | { |
Benoit | 1:f4040665bc61 | 65 | "sockets" |
Benoit | 1:f4040665bc61 | 66 | }; |
Benoit | 1:f4040665bc61 | 67 | |
Benoit | 1:f4040665bc61 | 68 | |
Benoit | 1:f4040665bc61 | 69 | static void NetIF_Init(void) |
Benoit | 1:f4040665bc61 | 70 | { |
Benoit | 1:f4040665bc61 | 71 | mbedNet_LastError = mbedNetResult_Success; |
Benoit | 1:f4040665bc61 | 72 | |
Benoit | 1:f4040665bc61 | 73 | DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing NetIF layer")); |
Benoit | 1:f4040665bc61 | 74 | |
Benoit | 1:f4040665bc61 | 75 | netIF_Count = 0; |
Benoit | 1:f4040665bc61 | 76 | memset(netIF_Table, 0, sizeof(netIF_Table)); |
Benoit | 1:f4040665bc61 | 77 | netIF_TableMutex = RTOS_MUTEX_CREATE(); |
Benoit | 1:f4040665bc61 | 78 | |
Benoit | 1:f4040665bc61 | 79 | netIF_PeriodicFunctionCount = 0; |
Benoit | 1:f4040665bc61 | 80 | memset(netIF_PeriodicFunctionTable, 0, sizeof(netIF_PeriodicFunctionTable)); |
Benoit | 1:f4040665bc61 | 81 | netIF_PeriodicFunctionTableMutex = RTOS_MUTEX_CREATE(); |
Benoit | 1:f4040665bc61 | 82 | |
Benoit | 1:f4040665bc61 | 83 | memset(&rxPacket, 0, sizeof(rxPacket)); |
Benoit | 1:f4040665bc61 | 84 | memset(&txPacket, 0, sizeof(txPacket)); |
Benoit | 1:f4040665bc61 | 85 | |
Benoit | 1:f4040665bc61 | 86 | gatewayNetIFIndex = -1; |
Benoit | 1:f4040665bc61 | 87 | |
Benoit | 1:f4040665bc61 | 88 | netIFLayerInitialized = True; |
Benoit | 1:f4040665bc61 | 89 | } |
Benoit | 1:f4040665bc61 | 90 | |
Benoit | 1:f4040665bc61 | 91 | |
Benoit | 1:f4040665bc61 | 92 | NetIF_t *NetIF_RegisterInterface(IPv4_Addr_t *address, IPv4_Addr_t *netmask, IPv4_Addr_t *gateway, NetIF_Driver_t *driver , void *driverParameter) |
Benoit | 1:f4040665bc61 | 93 | { |
Benoit | 1:f4040665bc61 | 94 | NetIF_t *netIF = NULL; |
Benoit | 1:f4040665bc61 | 95 | |
Benoit | 1:f4040665bc61 | 96 | if (netIFLayerInitialized == False) |
Benoit | 1:f4040665bc61 | 97 | { |
Benoit | 1:f4040665bc61 | 98 | NetIF_Init(); |
Benoit | 1:f4040665bc61 | 99 | } |
Benoit | 1:f4040665bc61 | 100 | |
Benoit | 1:f4040665bc61 | 101 | if (netIF_Count >= NETIF_MAX_COUNT) |
Benoit | 1:f4040665bc61 | 102 | { |
Benoit | 1:f4040665bc61 | 103 | DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Too many interfaces registered")); |
Benoit | 1:f4040665bc61 | 104 | mbedNet_LastError = mbedNetResult_TooManyInterfaces; |
Benoit | 1:f4040665bc61 | 105 | goto Exit; |
Benoit | 1:f4040665bc61 | 106 | } |
Benoit | 1:f4040665bc61 | 107 | |
Benoit | 1:f4040665bc61 | 108 | if (driver == NULL) |
Benoit | 1:f4040665bc61 | 109 | { |
Benoit | 1:f4040665bc61 | 110 | DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Invalid driver specified")); |
Benoit | 1:f4040665bc61 | 111 | mbedNet_LastError = mbedNetResult_InvalidDriver; |
Benoit | 1:f4040665bc61 | 112 | goto Exit; |
Benoit | 1:f4040665bc61 | 113 | } |
Benoit | 1:f4040665bc61 | 114 | |
Benoit | 1:f4040665bc61 | 115 | RTOS_MUTEX_LOCK(netIF_TableMutex); |
Benoit | 1:f4040665bc61 | 116 | netIF = netIF_Table + netIF_Count; |
Benoit | 1:f4040665bc61 | 117 | netIF->index = netIF_Count; |
Benoit | 1:f4040665bc61 | 118 | netIF->name = "en"; |
Benoit | 1:f4040665bc61 | 119 | netIF->ipv4Address = *address; |
Benoit | 1:f4040665bc61 | 120 | netIF->ipv4Netmask = *netmask; |
Benoit | 1:f4040665bc61 | 121 | netIF->ipv4Network.addr = address->addr & netmask->addr; |
Benoit | 1:f4040665bc61 | 122 | netIF->ipv4Gateway = *gateway; |
Benoit | 1:f4040665bc61 | 123 | netIF->ipv4Broadcast.addr = (address->addr & netmask->addr) | (~netmask->addr); |
Benoit | 1:f4040665bc61 | 124 | netIF->driverParameter = driverParameter; |
Benoit | 1:f4040665bc61 | 125 | netIF->driver = driver; |
Benoit | 1:f4040665bc61 | 126 | netIF->driver->Init(netIF); |
Benoit | 1:f4040665bc61 | 127 | netIF->driver->protocolHandler->Init(); |
Benoit | 1:f4040665bc61 | 128 | |
Benoit | 1:f4040665bc61 | 129 | if (gateway != NULL) |
Benoit | 1:f4040665bc61 | 130 | { |
Benoit | 1:f4040665bc61 | 131 | gatewayNetIFIndex = netIF_Count; |
Benoit | 1:f4040665bc61 | 132 | } |
Benoit | 1:f4040665bc61 | 133 | |
Benoit | 1:f4040665bc61 | 134 | 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'", |
Benoit | 1:f4040665bc61 | 135 | netIF->name, |
Benoit | 1:f4040665bc61 | 136 | netIF_Count, |
Benoit | 1:f4040665bc61 | 137 | netIF->ipv4Address.IP0, netIF->ipv4Address.IP1, netIF->ipv4Address.IP2, netIF->ipv4Address.IP3, |
Benoit | 1:f4040665bc61 | 138 | netIF->ipv4Netmask.IP0, netIF->ipv4Netmask.IP1, netIF->ipv4Netmask.IP2, netIF->ipv4Netmask.IP3, |
Benoit | 1:f4040665bc61 | 139 | netIF->ipv4Gateway.IP0, netIF->ipv4Gateway.IP1, netIF->ipv4Gateway.IP2, netIF->ipv4Gateway.IP3, |
Benoit | 1:f4040665bc61 | 140 | netIF->driver->name |
Benoit | 1:f4040665bc61 | 141 | )); |
Benoit | 1:f4040665bc61 | 142 | |
Benoit | 1:f4040665bc61 | 143 | netIF_Count++; |
Benoit | 1:f4040665bc61 | 144 | RTOS_MUTEX_UNLOCK(netIF_TableMutex); |
Benoit | 1:f4040665bc61 | 145 | |
Benoit | 1:f4040665bc61 | 146 | Exit: |
Benoit | 1:f4040665bc61 | 147 | return netIF; |
Benoit | 1:f4040665bc61 | 148 | } |
Benoit | 1:f4040665bc61 | 149 | |
Benoit | 1:f4040665bc61 | 150 | |
Benoit | 2:3d1c0fbd10e6 | 151 | /* |
Benoit | 1:f4040665bc61 | 152 | int32_t NetIF_ProcessFrames(void) |
Benoit | 1:f4040665bc61 | 153 | { |
Benoit | 1:f4040665bc61 | 154 | NetIF_Index_t netIFIndex; |
Benoit | 1:f4040665bc61 | 155 | NetIF_t *netIF; |
Benoit | 1:f4040665bc61 | 156 | int32_t result = 0, |
Benoit | 1:f4040665bc61 | 157 | readResult; |
Benoit | 1:f4040665bc61 | 158 | |
Benoit | 1:f4040665bc61 | 159 | DEBUG_SOURCE(DEBUG_LEVEL_VERBOSE2, ("enter")); |
Benoit | 1:f4040665bc61 | 160 | RTOS_MUTEX_LOCK(netIF_TableMutex); |
Benoit | 1:f4040665bc61 | 161 | for (netIFIndex = 0; netIFIndex < netIF_Count; netIFIndex++) |
Benoit | 1:f4040665bc61 | 162 | { |
Benoit | 1:f4040665bc61 | 163 | netIF = netIF_Table + netIFIndex; |
Benoit | 1:f4040665bc61 | 164 | readResult = netIF->driver->Read(&rxPacket.data, &rxPacket.length); |
Benoit | 1:f4040665bc61 | 165 | if (readResult == 0) |
Benoit | 1:f4040665bc61 | 166 | { |
Benoit | 1:f4040665bc61 | 167 | rxPacket.depth = -1; |
Benoit | 1:f4040665bc61 | 168 | netIF->driver->protocolHandler->HandlePacket(netIF, &rxPacket); |
Benoit | 1:f4040665bc61 | 169 | } |
Benoit | 1:f4040665bc61 | 170 | } |
Benoit | 1:f4040665bc61 | 171 | RTOS_MUTEX_UNLOCK(netIF_TableMutex); |
Benoit | 1:f4040665bc61 | 172 | |
Benoit | 1:f4040665bc61 | 173 | DEBUG_SOURCE(DEBUG_LEVEL_VERBOSE2, ("leave")); |
Benoit | 1:f4040665bc61 | 174 | return result; |
Benoit | 1:f4040665bc61 | 175 | } |
Benoit | 2:3d1c0fbd10e6 | 176 | */ |
Benoit | 1:f4040665bc61 | 177 | |
Benoit | 1:f4040665bc61 | 178 | |
Benoit | 1:f4040665bc61 | 179 | int32_t NetIF_RegisterPeriodicFunction(char *name, PeriodicFunction_t function, FunctionPeriod_t period) |
Benoit | 1:f4040665bc61 | 180 | { |
Benoit | 1:f4040665bc61 | 181 | int32_t result = 0; |
Benoit | 1:f4040665bc61 | 182 | PeriodicFunctionTimer_t *timerEntry; |
Benoit | 1:f4040665bc61 | 183 | |
Benoit | 1:f4040665bc61 | 184 | if (netIF_PeriodicFunctionCount >= NET_PERIODIC_FUNCTION_MAX_COUNT) |
Benoit | 1:f4040665bc61 | 185 | { |
Benoit | 1:f4040665bc61 | 186 | DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Too many periodic functions registered")); |
Benoit | 1:f4040665bc61 | 187 | mbedNet_LastError = mbedNetResult_TooManyPeriodicFunctions; |
Benoit | 1:f4040665bc61 | 188 | goto Exit; |
Benoit | 1:f4040665bc61 | 189 | } |
Benoit | 1:f4040665bc61 | 190 | |
Benoit | 1:f4040665bc61 | 191 | RTOS_MUTEX_LOCK(netIF_PeriodicFunctionTableMutex); |
Benoit | 1:f4040665bc61 | 192 | timerEntry = netIF_PeriodicFunctionTable + netIF_PeriodicFunctionCount; |
Benoit | 1:f4040665bc61 | 193 | timerEntry->name = name; |
Benoit | 1:f4040665bc61 | 194 | timerEntry->function = function; |
Benoit | 1:f4040665bc61 | 195 | timerEntry->period = period; |
Benoit | 1:f4040665bc61 | 196 | timerEntry->age = 0; |
Benoit | 1:f4040665bc61 | 197 | |
Benoit | 1:f4040665bc61 | 198 | DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Registered periodic function '%s' with period %d seconds", |
Benoit | 1:f4040665bc61 | 199 | name, |
Benoit | 1:f4040665bc61 | 200 | period |
Benoit | 1:f4040665bc61 | 201 | )); |
Benoit | 1:f4040665bc61 | 202 | |
Benoit | 1:f4040665bc61 | 203 | netIF_PeriodicFunctionCount++; |
Benoit | 1:f4040665bc61 | 204 | RTOS_MUTEX_UNLOCK(netIF_PeriodicFunctionTableMutex); |
Benoit | 1:f4040665bc61 | 205 | |
Benoit | 1:f4040665bc61 | 206 | Exit: |
Benoit | 1:f4040665bc61 | 207 | return result; |
Benoit | 1:f4040665bc61 | 208 | } |
Benoit | 1:f4040665bc61 | 209 | |
Benoit | 1:f4040665bc61 | 210 | |
Benoit | 1:f4040665bc61 | 211 | int32_t NetIF_ProcessTimers(int32_t elapsedTime) |
Benoit | 1:f4040665bc61 | 212 | { |
Benoit | 1:f4040665bc61 | 213 | int32_t result = 0, |
Benoit | 1:f4040665bc61 | 214 | timerIndex; |
Benoit | 1:f4040665bc61 | 215 | PeriodicFunctionTimer_t *timerEntry; |
Benoit | 1:f4040665bc61 | 216 | static int64_t seconds = 0; |
Benoit | 1:f4040665bc61 | 217 | |
Benoit | 1:f4040665bc61 | 218 | seconds++; |
Benoit | 1:f4040665bc61 | 219 | |
Benoit | 1:f4040665bc61 | 220 | RTOS_MUTEX_LOCK(netIF_PeriodicFunctionTableMutex); |
Benoit | 1:f4040665bc61 | 221 | for (timerIndex = 0; timerIndex < netIF_PeriodicFunctionCount; timerIndex++) |
Benoit | 1:f4040665bc61 | 222 | { |
Benoit | 1:f4040665bc61 | 223 | timerEntry = netIF_PeriodicFunctionTable + timerIndex; |
Benoit | 1:f4040665bc61 | 224 | if (elapsedTime == 0) |
Benoit | 1:f4040665bc61 | 225 | { |
Benoit | 1:f4040665bc61 | 226 | timerEntry->age = 0; |
Benoit | 1:f4040665bc61 | 227 | continue; |
Benoit | 1:f4040665bc61 | 228 | } |
Benoit | 1:f4040665bc61 | 229 | |
Benoit | 1:f4040665bc61 | 230 | timerEntry->age += elapsedTime; |
Benoit | 1:f4040665bc61 | 231 | if (timerEntry->age >= timerEntry->period) |
Benoit | 1:f4040665bc61 | 232 | { |
Benoit | 1:f4040665bc61 | 233 | timerEntry->age = 0; |
Benoit | 1:f4040665bc61 | 234 | timerEntry->function(); |
Benoit | 1:f4040665bc61 | 235 | } |
Benoit | 1:f4040665bc61 | 236 | } |
Benoit | 1:f4040665bc61 | 237 | RTOS_MUTEX_UNLOCK(netIF_PeriodicFunctionTableMutex); |
Benoit | 1:f4040665bc61 | 238 | |
Benoit | 1:f4040665bc61 | 239 | return result; |
Benoit | 1:f4040665bc61 | 240 | } |
Benoit | 1:f4040665bc61 | 241 | |
Benoit | 1:f4040665bc61 | 242 | |
Benoit | 2:3d1c0fbd10e6 | 243 | int32_t NetIF_SendIPv4Packet(IPv4_Header_t *ipv4Header) |
Benoit | 1:f4040665bc61 | 244 | { |
Benoit | 1:f4040665bc61 | 245 | int32_t result = -1, |
Benoit | 1:f4040665bc61 | 246 | mtu, |
Benoit | 1:f4040665bc61 | 247 | lengthToSend; |
Benoit | 1:f4040665bc61 | 248 | NetIF_Index_t netIFIndex; |
Benoit | 1:f4040665bc61 | 249 | NetIF_t *netIF = NULL; |
Benoit | 1:f4040665bc61 | 250 | Ethernet_Header_t *ethernetHeader; |
Benoit | 1:f4040665bc61 | 251 | Bool_t useGateway = False; |
Benoit | 1:f4040665bc61 | 252 | |
Benoit | 1:f4040665bc61 | 253 | RTOS_MUTEX_LOCK(netIF_TableMutex); |
Benoit | 1:f4040665bc61 | 254 | |
Benoit | 1:f4040665bc61 | 255 | /* Look for netif having same network */ |
Benoit | 1:f4040665bc61 | 256 | for (netIFIndex = 0; netIFIndex < netIF_Count; netIFIndex++) |
Benoit | 1:f4040665bc61 | 257 | { |
Benoit | 1:f4040665bc61 | 258 | netIF = netIF_Table + netIFIndex; |
Benoit | 1:f4040665bc61 | 259 | if ( (netIF->up) && ((netIF->ipv4Netmask.addr & ipv4Header->dest.addr) == netIF->ipv4Network.addr)) break; |
Benoit | 1:f4040665bc61 | 260 | netIF = NULL; |
Benoit | 1:f4040665bc61 | 261 | } |
Benoit | 1:f4040665bc61 | 262 | |
Benoit | 1:f4040665bc61 | 263 | /* if not found, use gateway netif */ |
Benoit | 1:f4040665bc61 | 264 | if ((netIF == NULL) && (gatewayNetIFIndex >= 0)) |
Benoit | 1:f4040665bc61 | 265 | { |
Benoit | 1:f4040665bc61 | 266 | netIF = netIF_Table + gatewayNetIFIndex; |
Benoit | 2:3d1c0fbd10e6 | 267 | if (netIF->up) |
Benoit | 2:3d1c0fbd10e6 | 268 | { |
Benoit | 2:3d1c0fbd10e6 | 269 | DEBUG_MODULE(DEBUG_LEVEL_INFO, ("using gateway %d.%d.%d.%d to talk to %d.%d.%d.%d", |
Benoit | 2:3d1c0fbd10e6 | 270 | netIF->ipv4Gateway.IP0, |
Benoit | 2:3d1c0fbd10e6 | 271 | netIF->ipv4Gateway.IP1, |
Benoit | 2:3d1c0fbd10e6 | 272 | netIF->ipv4Gateway.IP2, |
Benoit | 2:3d1c0fbd10e6 | 273 | netIF->ipv4Gateway.IP3, |
Benoit | 1:f4040665bc61 | 274 | |
Benoit | 2:3d1c0fbd10e6 | 275 | ipv4Header->dest.IP0, |
Benoit | 2:3d1c0fbd10e6 | 276 | ipv4Header->dest.IP1, |
Benoit | 2:3d1c0fbd10e6 | 277 | ipv4Header->dest.IP2, |
Benoit | 2:3d1c0fbd10e6 | 278 | ipv4Header->dest.IP3 |
Benoit | 2:3d1c0fbd10e6 | 279 | )); |
Benoit | 2:3d1c0fbd10e6 | 280 | useGateway = True; |
Benoit | 2:3d1c0fbd10e6 | 281 | } |
Benoit | 1:f4040665bc61 | 282 | } |
Benoit | 1:f4040665bc61 | 283 | |
Benoit | 1:f4040665bc61 | 284 | /* Still no interface able to send, then return error */ |
Benoit | 1:f4040665bc61 | 285 | if (netIF == NULL) |
Benoit | 1:f4040665bc61 | 286 | { |
Benoit | 1:f4040665bc61 | 287 | DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("No route to host")); |
Benoit | 1:f4040665bc61 | 288 | mbedNet_LastError = mbedNetResult_NoRouteToHost; |
Benoit | 1:f4040665bc61 | 289 | goto Exit; |
Benoit | 1:f4040665bc61 | 290 | } |
Benoit | 1:f4040665bc61 | 291 | |
Benoit | 1:f4040665bc61 | 292 | /* Prepare to send the IPv4 packet */ |
Benoit | 1:f4040665bc61 | 293 | mtu = netIF->driver->mtu; |
Benoit | 1:f4040665bc61 | 294 | |
Benoit | 1:f4040665bc61 | 295 | lengthToSend = (sizeof(Ethernet_Header_t) + ntohs(ipv4Header->totalLength)); |
Benoit | 1:f4040665bc61 | 296 | /* Check that total length doesn't exceed MTU */ |
Benoit | 1:f4040665bc61 | 297 | if (lengthToSend > mtu) |
Benoit | 1:f4040665bc61 | 298 | { |
Benoit | 1:f4040665bc61 | 299 | DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Too much data: %d bytes", lengthToSend)); |
Benoit | 1:f4040665bc61 | 300 | mbedNet_LastError = mbedNetResult_TooMuchData; |
Benoit | 1:f4040665bc61 | 301 | goto Exit; |
Benoit | 1:f4040665bc61 | 302 | } |
Benoit | 1:f4040665bc61 | 303 | |
Benoit | 1:f4040665bc61 | 304 | /* Set source address and compute checksum of IPv4 header */ |
Benoit | 1:f4040665bc61 | 305 | ipv4Header->source.addr = netIF->ipv4Address.addr; |
Benoit | 1:f4040665bc61 | 306 | ipv4Header->crc = 0; |
Benoit | 1:f4040665bc61 | 307 | ipv4Header->crc = IPv4_ComputeCRC(ipv4Header); |
Benoit | 1:f4040665bc61 | 308 | |
Benoit | 1:f4040665bc61 | 309 | /* Prepare packet with ethernet data */ |
Benoit | 1:f4040665bc61 | 310 | txPacket.depth = -1; |
Benoit | 1:f4040665bc61 | 311 | txPacket.length = lengthToSend; |
Benoit | 1:f4040665bc61 | 312 | txPacket.data = netIF->driver->GetTxBuffer(); |
Benoit | 1:f4040665bc61 | 313 | ethernetHeader = (Ethernet_Header_t *)txPacket.data; |
Benoit | 1:f4040665bc61 | 314 | |
Benoit | 1:f4040665bc61 | 315 | /* Copy destination MAC address */ |
Benoit | 1:f4040665bc61 | 316 | if (useGateway) |
Benoit | 1:f4040665bc61 | 317 | { |
Benoit | 1:f4040665bc61 | 318 | while (ARP_ResolveIPv4Address(netIF, netIF->ipv4Gateway, ðernetHeader->destination) == -1) |
Benoit | 1:f4040665bc61 | 319 | { |
Benoit | 1:f4040665bc61 | 320 | DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("%d.%d.%d.%d not in ARP cache", |
Benoit | 1:f4040665bc61 | 321 | netIF->ipv4Gateway.IP0, |
Benoit | 1:f4040665bc61 | 322 | netIF->ipv4Gateway.IP1, |
Benoit | 1:f4040665bc61 | 323 | netIF->ipv4Gateway.IP2, |
Benoit | 1:f4040665bc61 | 324 | netIF->ipv4Gateway.IP3 |
Benoit | 1:f4040665bc61 | 325 | )); |
Benoit | 1:f4040665bc61 | 326 | } |
Benoit | 1:f4040665bc61 | 327 | } |
Benoit | 1:f4040665bc61 | 328 | else |
Benoit | 1:f4040665bc61 | 329 | { |
Benoit | 2:3d1c0fbd10e6 | 330 | while (ARP_ResolveIPv4Address(netIF, ipv4Header->dest, ðernetHeader->destination) == -1) |
Benoit | 1:f4040665bc61 | 331 | { |
Benoit | 1:f4040665bc61 | 332 | DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("%d.%d.%d.%d not in ARP cache", |
Benoit | 1:f4040665bc61 | 333 | ipv4Header->dest.IP0, |
Benoit | 1:f4040665bc61 | 334 | ipv4Header->dest.IP1, |
Benoit | 1:f4040665bc61 | 335 | ipv4Header->dest.IP2, |
Benoit | 1:f4040665bc61 | 336 | ipv4Header->dest.IP3 |
Benoit | 1:f4040665bc61 | 337 | )); |
Benoit | 1:f4040665bc61 | 338 | } |
Benoit | 1:f4040665bc61 | 339 | } |
Benoit | 1:f4040665bc61 | 340 | |
Benoit | 1:f4040665bc61 | 341 | DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("IPv4 sending %d bytes %d.%d.%d.%d --> %d.%d.%d.%d using %s%d", |
Benoit | 1:f4040665bc61 | 342 | ntohs(ipv4Header->totalLength), |
Benoit | 1:f4040665bc61 | 343 | |
Benoit | 1:f4040665bc61 | 344 | ipv4Header->source.IP0, |
Benoit | 1:f4040665bc61 | 345 | ipv4Header->source.IP1, |
Benoit | 1:f4040665bc61 | 346 | ipv4Header->source.IP2, |
Benoit | 1:f4040665bc61 | 347 | ipv4Header->source.IP3, |
Benoit | 1:f4040665bc61 | 348 | |
Benoit | 1:f4040665bc61 | 349 | ipv4Header->dest.IP0, |
Benoit | 1:f4040665bc61 | 350 | ipv4Header->dest.IP1, |
Benoit | 1:f4040665bc61 | 351 | ipv4Header->dest.IP2, |
Benoit | 1:f4040665bc61 | 352 | ipv4Header->dest.IP3, |
Benoit | 1:f4040665bc61 | 353 | |
Benoit | 1:f4040665bc61 | 354 | netIF->name, |
Benoit | 1:f4040665bc61 | 355 | netIF->index |
Benoit | 1:f4040665bc61 | 356 | )); |
Benoit | 1:f4040665bc61 | 357 | |
Benoit | 1:f4040665bc61 | 358 | /* Copy source MAC address */ |
Benoit | 1:f4040665bc61 | 359 | memcpy(ðernetHeader->source, (uint8_t *)netIF->driverParameter, 6); |
Benoit | 1:f4040665bc61 | 360 | ethernetHeader->protocol = htons(ETHERNET_PROTO_IPV4); |
Benoit | 1:f4040665bc61 | 361 | NetIF_ProtoPush(&txPacket, sizeof(Ethernet_Header_t), Protocol_ID_Ethernet); |
Benoit | 1:f4040665bc61 | 362 | |
Benoit | 1:f4040665bc61 | 363 | /* Copy ethernet payload */ |
Benoit | 1:f4040665bc61 | 364 | //ipv4Header = (IPv4_Header_t *)txPacket.data; |
Benoit | 1:f4040665bc61 | 365 | memcpy(txPacket.data, ipv4Header, ntohs(ipv4Header->totalLength)); |
Benoit | 1:f4040665bc61 | 366 | NetIF_ProtoPop(&txPacket); |
Benoit | 1:f4040665bc61 | 367 | |
Benoit | 1:f4040665bc61 | 368 | /* Send packet */ |
Benoit | 1:f4040665bc61 | 369 | result = netIF->driver->Write(txPacket.data, txPacket.length); |
Benoit | 1:f4040665bc61 | 370 | |
Benoit | 1:f4040665bc61 | 371 | Exit: |
Benoit | 1:f4040665bc61 | 372 | RTOS_MUTEX_UNLOCK(netIF_TableMutex); |
Benoit | 1:f4040665bc61 | 373 | return result; |
Benoit | 1:f4040665bc61 | 374 | } |
Benoit | 1:f4040665bc61 | 375 | |
Benoit | 1:f4040665bc61 | 376 | |
Benoit | 1:f4040665bc61 | 377 | int32_t NetIF_Up(NetIF_t *netIF) |
Benoit | 1:f4040665bc61 | 378 | { |
Benoit | 1:f4040665bc61 | 379 | int32_t result = 0; |
Benoit | 1:f4040665bc61 | 380 | |
Benoit | 1:f4040665bc61 | 381 | if (netIF->up) |
Benoit | 1:f4040665bc61 | 382 | { |
Benoit | 1:f4040665bc61 | 383 | result = -1; |
Benoit | 1:f4040665bc61 | 384 | mbedNet_LastError = mbedNetResult_InterfaceAlreadyUp; |
Benoit | 1:f4040665bc61 | 385 | goto Exit; |
Benoit | 1:f4040665bc61 | 386 | } |
Benoit | 1:f4040665bc61 | 387 | |
Benoit | 1:f4040665bc61 | 388 | netIF->driver->Enable(); |
Benoit | 1:f4040665bc61 | 389 | netIF->up = True; |
Benoit | 1:f4040665bc61 | 390 | |
Benoit | 1:f4040665bc61 | 391 | Exit: |
Benoit | 1:f4040665bc61 | 392 | return result; |
Benoit | 1:f4040665bc61 | 393 | } |
Benoit | 1:f4040665bc61 | 394 | |
Benoit | 1:f4040665bc61 | 395 | |
Benoit | 1:f4040665bc61 | 396 | int32_t NetIF_Down(NetIF_t *netIF) |
Benoit | 1:f4040665bc61 | 397 | { |
Benoit | 1:f4040665bc61 | 398 | int32_t result = 0; |
Benoit | 1:f4040665bc61 | 399 | |
Benoit | 1:f4040665bc61 | 400 | if (!netIF->up) |
Benoit | 1:f4040665bc61 | 401 | { |
Benoit | 1:f4040665bc61 | 402 | result = -1; |
Benoit | 1:f4040665bc61 | 403 | mbedNet_LastError = mbedNetResult_InterfaceAlreadyDown; |
Benoit | 1:f4040665bc61 | 404 | goto Exit; |
Benoit | 1:f4040665bc61 | 405 | } |
Benoit | 1:f4040665bc61 | 406 | |
Benoit | 1:f4040665bc61 | 407 | netIF->driver->Disable(); |
Benoit | 1:f4040665bc61 | 408 | netIF->up = False; |
Benoit | 1:f4040665bc61 | 409 | |
Benoit | 1:f4040665bc61 | 410 | Exit: |
Benoit | 1:f4040665bc61 | 411 | return result; |
Benoit | 1:f4040665bc61 | 412 | } |
Benoit | 1:f4040665bc61 | 413 | |
Benoit | 1:f4040665bc61 | 414 | |
Benoit | 5:3cd83fcb1467 | 415 | void NetIF_ProtoPop(NetPacket_t *packet) |
Benoit | 1:f4040665bc61 | 416 | { |
Benoit | 1:f4040665bc61 | 417 | static int32_t depth, headerSize, index; |
Benoit | 1:f4040665bc61 | 418 | |
Benoit | 1:f4040665bc61 | 419 | DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length)); |
Benoit | 1:f4040665bc61 | 420 | if (packet->depth >= 0) |
Benoit | 1:f4040665bc61 | 421 | { |
Benoit | 1:f4040665bc61 | 422 | depth = packet->depth; |
Benoit | 1:f4040665bc61 | 423 | headerSize = packet->headerLenTable[depth]; |
Benoit | 1:f4040665bc61 | 424 | |
Benoit | 1:f4040665bc61 | 425 | packet->data -= headerSize; |
Benoit | 1:f4040665bc61 | 426 | packet->length += headerSize; |
Benoit | 1:f4040665bc61 | 427 | |
Benoit | 1:f4040665bc61 | 428 | packet->depth--; |
Benoit | 1:f4040665bc61 | 429 | } |
Benoit | 1:f4040665bc61 | 430 | |
Benoit | 1:f4040665bc61 | 431 | DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (" > Decapsulate: ")); |
Benoit | 1:f4040665bc61 | 432 | DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE1) |
Benoit | 1:f4040665bc61 | 433 | { |
Benoit | 1:f4040665bc61 | 434 | for (index = 0; index <= packet->depth; index++) |
Benoit | 1:f4040665bc61 | 435 | { |
Benoit | 1:f4040665bc61 | 436 | DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (" > %d %s header:%d bytes", index, protocol_IDNames[packet->protocolTable[index]], packet->headerLenTable[index])); |
Benoit | 1:f4040665bc61 | 437 | } |
Benoit | 1:f4040665bc61 | 438 | } |
Benoit | 1:f4040665bc61 | 439 | DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length)); |
Benoit | 1:f4040665bc61 | 440 | } |
Benoit | 1:f4040665bc61 | 441 | |
Benoit | 1:f4040665bc61 | 442 | |
Benoit | 5:3cd83fcb1467 | 443 | void NetIF_ProtoPush(NetPacket_t *packet, int32_t headerSize, Protocol_ID_t protocol) |
Benoit | 1:f4040665bc61 | 444 | { |
Benoit | 1:f4040665bc61 | 445 | static int32_t depth, index; |
Benoit | 1:f4040665bc61 | 446 | |
Benoit | 1:f4040665bc61 | 447 | DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length)); |
Benoit | 1:f4040665bc61 | 448 | |
Benoit | 1:f4040665bc61 | 449 | packet->depth++; |
Benoit | 1:f4040665bc61 | 450 | depth = packet->depth; |
Benoit | 1:f4040665bc61 | 451 | |
Benoit | 1:f4040665bc61 | 452 | packet->headerPtrTable[depth] = packet->data; |
Benoit | 1:f4040665bc61 | 453 | packet->headerLenTable[depth] = headerSize; |
Benoit | 1:f4040665bc61 | 454 | packet->protocolTable[depth] = protocol; |
Benoit | 1:f4040665bc61 | 455 | packet->data += headerSize; |
Benoit | 1:f4040665bc61 | 456 | packet->length -= headerSize; |
Benoit | 1:f4040665bc61 | 457 | |
Benoit | 1:f4040665bc61 | 458 | DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (" > Encapsulate: ")); |
Benoit | 1:f4040665bc61 | 459 | DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE1) |
Benoit | 1:f4040665bc61 | 460 | { |
Benoit | 1:f4040665bc61 | 461 | for (index = 0; index <= depth; index++) |
Benoit | 1:f4040665bc61 | 462 | { |
Benoit | 1:f4040665bc61 | 463 | DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (" > %d %s header:%d bytes", index, protocol_IDNames[packet->protocolTable[index]], packet->headerLenTable[index])); |
Benoit | 1:f4040665bc61 | 464 | } |
Benoit | 1:f4040665bc61 | 465 | } |
Benoit | 1:f4040665bc61 | 466 | DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length)); |
Benoit | 1:f4040665bc61 | 467 | } |
Benoit | 1:f4040665bc61 | 468 |