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@1:f4040665bc61, 2011-06-12 (annotated)
- Committer:
- Benoit
- Date:
- Sun Jun 12 19:17:11 2011 +0000
- Revision:
- 1:f4040665bc61
- Child:
- 2:3d1c0fbd10e6
Frames are now received using an interrupt handler
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 | 1:f4040665bc61 | 43 | static Packet_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 | 1:f4040665bc61 | 151 | int32_t NetIF_ProcessFrames(void) |
Benoit | 1:f4040665bc61 | 152 | { |
Benoit | 1:f4040665bc61 | 153 | NetIF_Index_t netIFIndex; |
Benoit | 1:f4040665bc61 | 154 | NetIF_t *netIF; |
Benoit | 1:f4040665bc61 | 155 | int32_t result = 0, |
Benoit | 1:f4040665bc61 | 156 | readResult; |
Benoit | 1:f4040665bc61 | 157 | |
Benoit | 1:f4040665bc61 | 158 | DEBUG_SOURCE(DEBUG_LEVEL_VERBOSE2, ("enter")); |
Benoit | 1:f4040665bc61 | 159 | RTOS_MUTEX_LOCK(netIF_TableMutex); |
Benoit | 1:f4040665bc61 | 160 | for (netIFIndex = 0; netIFIndex < netIF_Count; netIFIndex++) |
Benoit | 1:f4040665bc61 | 161 | { |
Benoit | 1:f4040665bc61 | 162 | netIF = netIF_Table + netIFIndex; |
Benoit | 1:f4040665bc61 | 163 | readResult = netIF->driver->Read(&rxPacket.data, &rxPacket.length); |
Benoit | 1:f4040665bc61 | 164 | if (readResult == 0) |
Benoit | 1:f4040665bc61 | 165 | { |
Benoit | 1:f4040665bc61 | 166 | rxPacket.depth = -1; |
Benoit | 1:f4040665bc61 | 167 | netIF->driver->protocolHandler->HandlePacket(netIF, &rxPacket); |
Benoit | 1:f4040665bc61 | 168 | } |
Benoit | 1:f4040665bc61 | 169 | } |
Benoit | 1:f4040665bc61 | 170 | RTOS_MUTEX_UNLOCK(netIF_TableMutex); |
Benoit | 1:f4040665bc61 | 171 | |
Benoit | 1:f4040665bc61 | 172 | DEBUG_SOURCE(DEBUG_LEVEL_VERBOSE2, ("leave")); |
Benoit | 1:f4040665bc61 | 173 | return result; |
Benoit | 1:f4040665bc61 | 174 | } |
Benoit | 1:f4040665bc61 | 175 | |
Benoit | 1:f4040665bc61 | 176 | |
Benoit | 1:f4040665bc61 | 177 | int32_t NetIF_RegisterPeriodicFunction(char *name, PeriodicFunction_t function, FunctionPeriod_t period) |
Benoit | 1:f4040665bc61 | 178 | { |
Benoit | 1:f4040665bc61 | 179 | int32_t result = 0; |
Benoit | 1:f4040665bc61 | 180 | PeriodicFunctionTimer_t *timerEntry; |
Benoit | 1:f4040665bc61 | 181 | |
Benoit | 1:f4040665bc61 | 182 | if (netIF_PeriodicFunctionCount >= NET_PERIODIC_FUNCTION_MAX_COUNT) |
Benoit | 1:f4040665bc61 | 183 | { |
Benoit | 1:f4040665bc61 | 184 | DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Too many periodic functions registered")); |
Benoit | 1:f4040665bc61 | 185 | mbedNet_LastError = mbedNetResult_TooManyPeriodicFunctions; |
Benoit | 1:f4040665bc61 | 186 | goto Exit; |
Benoit | 1:f4040665bc61 | 187 | } |
Benoit | 1:f4040665bc61 | 188 | |
Benoit | 1:f4040665bc61 | 189 | RTOS_MUTEX_LOCK(netIF_PeriodicFunctionTableMutex); |
Benoit | 1:f4040665bc61 | 190 | timerEntry = netIF_PeriodicFunctionTable + netIF_PeriodicFunctionCount; |
Benoit | 1:f4040665bc61 | 191 | timerEntry->name = name; |
Benoit | 1:f4040665bc61 | 192 | timerEntry->function = function; |
Benoit | 1:f4040665bc61 | 193 | timerEntry->period = period; |
Benoit | 1:f4040665bc61 | 194 | timerEntry->age = 0; |
Benoit | 1:f4040665bc61 | 195 | |
Benoit | 1:f4040665bc61 | 196 | DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Registered periodic function '%s' with period %d seconds", |
Benoit | 1:f4040665bc61 | 197 | name, |
Benoit | 1:f4040665bc61 | 198 | period |
Benoit | 1:f4040665bc61 | 199 | )); |
Benoit | 1:f4040665bc61 | 200 | |
Benoit | 1:f4040665bc61 | 201 | netIF_PeriodicFunctionCount++; |
Benoit | 1:f4040665bc61 | 202 | RTOS_MUTEX_UNLOCK(netIF_PeriodicFunctionTableMutex); |
Benoit | 1:f4040665bc61 | 203 | |
Benoit | 1:f4040665bc61 | 204 | Exit: |
Benoit | 1:f4040665bc61 | 205 | return result; |
Benoit | 1:f4040665bc61 | 206 | } |
Benoit | 1:f4040665bc61 | 207 | |
Benoit | 1:f4040665bc61 | 208 | |
Benoit | 1:f4040665bc61 | 209 | int32_t NetIF_ProcessTimers(int32_t elapsedTime) |
Benoit | 1:f4040665bc61 | 210 | { |
Benoit | 1:f4040665bc61 | 211 | int32_t result = 0, |
Benoit | 1:f4040665bc61 | 212 | timerIndex; |
Benoit | 1:f4040665bc61 | 213 | PeriodicFunctionTimer_t *timerEntry; |
Benoit | 1:f4040665bc61 | 214 | static int64_t seconds = 0; |
Benoit | 1:f4040665bc61 | 215 | |
Benoit | 1:f4040665bc61 | 216 | seconds++; |
Benoit | 1:f4040665bc61 | 217 | |
Benoit | 1:f4040665bc61 | 218 | RTOS_MUTEX_LOCK(netIF_PeriodicFunctionTableMutex); |
Benoit | 1:f4040665bc61 | 219 | for (timerIndex = 0; timerIndex < netIF_PeriodicFunctionCount; timerIndex++) |
Benoit | 1:f4040665bc61 | 220 | { |
Benoit | 1:f4040665bc61 | 221 | timerEntry = netIF_PeriodicFunctionTable + timerIndex; |
Benoit | 1:f4040665bc61 | 222 | if (elapsedTime == 0) |
Benoit | 1:f4040665bc61 | 223 | { |
Benoit | 1:f4040665bc61 | 224 | timerEntry->age = 0; |
Benoit | 1:f4040665bc61 | 225 | continue; |
Benoit | 1:f4040665bc61 | 226 | } |
Benoit | 1:f4040665bc61 | 227 | |
Benoit | 1:f4040665bc61 | 228 | timerEntry->age += elapsedTime; |
Benoit | 1:f4040665bc61 | 229 | if (timerEntry->age >= timerEntry->period) |
Benoit | 1:f4040665bc61 | 230 | { |
Benoit | 1:f4040665bc61 | 231 | timerEntry->age = 0; |
Benoit | 1:f4040665bc61 | 232 | timerEntry->function(); |
Benoit | 1:f4040665bc61 | 233 | } |
Benoit | 1:f4040665bc61 | 234 | } |
Benoit | 1:f4040665bc61 | 235 | RTOS_MUTEX_UNLOCK(netIF_PeriodicFunctionTableMutex); |
Benoit | 1:f4040665bc61 | 236 | |
Benoit | 1:f4040665bc61 | 237 | return result; |
Benoit | 1:f4040665bc61 | 238 | } |
Benoit | 1:f4040665bc61 | 239 | |
Benoit | 1:f4040665bc61 | 240 | |
Benoit | 1:f4040665bc61 | 241 | int32_t NetIF_SendIPv4Packet(IPv4_Header_t *ipv4Header) |
Benoit | 1:f4040665bc61 | 242 | { |
Benoit | 1:f4040665bc61 | 243 | int32_t result = -1, |
Benoit | 1:f4040665bc61 | 244 | mtu, |
Benoit | 1:f4040665bc61 | 245 | lengthToSend; |
Benoit | 1:f4040665bc61 | 246 | NetIF_Index_t netIFIndex; |
Benoit | 1:f4040665bc61 | 247 | NetIF_t *netIF = NULL; |
Benoit | 1:f4040665bc61 | 248 | Ethernet_Header_t *ethernetHeader; |
Benoit | 1:f4040665bc61 | 249 | Bool_t useGateway = False; |
Benoit | 1:f4040665bc61 | 250 | |
Benoit | 1:f4040665bc61 | 251 | RTOS_MUTEX_LOCK(netIF_TableMutex); |
Benoit | 1:f4040665bc61 | 252 | |
Benoit | 1:f4040665bc61 | 253 | /* Look for netif having same network */ |
Benoit | 1:f4040665bc61 | 254 | for (netIFIndex = 0; netIFIndex < netIF_Count; netIFIndex++) |
Benoit | 1:f4040665bc61 | 255 | { |
Benoit | 1:f4040665bc61 | 256 | netIF = netIF_Table + netIFIndex; |
Benoit | 1:f4040665bc61 | 257 | if ( (netIF->up) && ((netIF->ipv4Netmask.addr & ipv4Header->dest.addr) == netIF->ipv4Network.addr)) break; |
Benoit | 1:f4040665bc61 | 258 | netIF = NULL; |
Benoit | 1:f4040665bc61 | 259 | } |
Benoit | 1:f4040665bc61 | 260 | |
Benoit | 1:f4040665bc61 | 261 | /* if not found, use gateway netif */ |
Benoit | 1:f4040665bc61 | 262 | if ((netIF == NULL) && (gatewayNetIFIndex >= 0)) |
Benoit | 1:f4040665bc61 | 263 | { |
Benoit | 1:f4040665bc61 | 264 | netIF = netIF_Table + gatewayNetIFIndex; |
Benoit | 1:f4040665bc61 | 265 | DEBUG_MODULE(DEBUG_LEVEL_INFO, ("using gateway %d.%d.%d.%d to talk to %d.%d.%d.%d", |
Benoit | 1:f4040665bc61 | 266 | netIF->ipv4Gateway.IP0, |
Benoit | 1:f4040665bc61 | 267 | netIF->ipv4Gateway.IP1, |
Benoit | 1:f4040665bc61 | 268 | netIF->ipv4Gateway.IP2, |
Benoit | 1:f4040665bc61 | 269 | netIF->ipv4Gateway.IP3, |
Benoit | 1:f4040665bc61 | 270 | |
Benoit | 1:f4040665bc61 | 271 | ipv4Header->dest.IP0, |
Benoit | 1:f4040665bc61 | 272 | ipv4Header->dest.IP1, |
Benoit | 1:f4040665bc61 | 273 | ipv4Header->dest.IP2, |
Benoit | 1:f4040665bc61 | 274 | ipv4Header->dest.IP3 |
Benoit | 1:f4040665bc61 | 275 | )); |
Benoit | 1:f4040665bc61 | 276 | useGateway = True; |
Benoit | 1:f4040665bc61 | 277 | } |
Benoit | 1:f4040665bc61 | 278 | |
Benoit | 1:f4040665bc61 | 279 | /* Still no interface able to send, then return error */ |
Benoit | 1:f4040665bc61 | 280 | if (netIF == NULL) |
Benoit | 1:f4040665bc61 | 281 | { |
Benoit | 1:f4040665bc61 | 282 | DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("No route to host")); |
Benoit | 1:f4040665bc61 | 283 | mbedNet_LastError = mbedNetResult_NoRouteToHost; |
Benoit | 1:f4040665bc61 | 284 | goto Exit; |
Benoit | 1:f4040665bc61 | 285 | } |
Benoit | 1:f4040665bc61 | 286 | |
Benoit | 1:f4040665bc61 | 287 | /* Prepare to send the IPv4 packet */ |
Benoit | 1:f4040665bc61 | 288 | mtu = netIF->driver->mtu; |
Benoit | 1:f4040665bc61 | 289 | |
Benoit | 1:f4040665bc61 | 290 | lengthToSend = (sizeof(Ethernet_Header_t) + ntohs(ipv4Header->totalLength)); |
Benoit | 1:f4040665bc61 | 291 | /* Check that total length doesn't exceed MTU */ |
Benoit | 1:f4040665bc61 | 292 | if (lengthToSend > mtu) |
Benoit | 1:f4040665bc61 | 293 | { |
Benoit | 1:f4040665bc61 | 294 | DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Too much data: %d bytes", lengthToSend)); |
Benoit | 1:f4040665bc61 | 295 | mbedNet_LastError = mbedNetResult_TooMuchData; |
Benoit | 1:f4040665bc61 | 296 | goto Exit; |
Benoit | 1:f4040665bc61 | 297 | } |
Benoit | 1:f4040665bc61 | 298 | |
Benoit | 1:f4040665bc61 | 299 | /* Set source address and compute checksum of IPv4 header */ |
Benoit | 1:f4040665bc61 | 300 | ipv4Header->source.addr = netIF->ipv4Address.addr; |
Benoit | 1:f4040665bc61 | 301 | ipv4Header->crc = 0; |
Benoit | 1:f4040665bc61 | 302 | ipv4Header->crc = IPv4_ComputeCRC(ipv4Header); |
Benoit | 1:f4040665bc61 | 303 | |
Benoit | 1:f4040665bc61 | 304 | /* Prepare packet with ethernet data */ |
Benoit | 1:f4040665bc61 | 305 | txPacket.depth = -1; |
Benoit | 1:f4040665bc61 | 306 | txPacket.length = lengthToSend; |
Benoit | 1:f4040665bc61 | 307 | txPacket.data = netIF->driver->GetTxBuffer(); |
Benoit | 1:f4040665bc61 | 308 | ethernetHeader = (Ethernet_Header_t *)txPacket.data; |
Benoit | 1:f4040665bc61 | 309 | |
Benoit | 1:f4040665bc61 | 310 | /* Copy destination MAC address */ |
Benoit | 1:f4040665bc61 | 311 | if (useGateway) |
Benoit | 1:f4040665bc61 | 312 | { |
Benoit | 1:f4040665bc61 | 313 | while (ARP_ResolveIPv4Address(netIF, netIF->ipv4Gateway, ðernetHeader->destination) == -1) |
Benoit | 1:f4040665bc61 | 314 | { |
Benoit | 1:f4040665bc61 | 315 | DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("%d.%d.%d.%d not in ARP cache", |
Benoit | 1:f4040665bc61 | 316 | netIF->ipv4Gateway.IP0, |
Benoit | 1:f4040665bc61 | 317 | netIF->ipv4Gateway.IP1, |
Benoit | 1:f4040665bc61 | 318 | netIF->ipv4Gateway.IP2, |
Benoit | 1:f4040665bc61 | 319 | netIF->ipv4Gateway.IP3 |
Benoit | 1:f4040665bc61 | 320 | )); |
Benoit | 1:f4040665bc61 | 321 | NetIF_ProcessFrames(); |
Benoit | 1:f4040665bc61 | 322 | } |
Benoit | 1:f4040665bc61 | 323 | } |
Benoit | 1:f4040665bc61 | 324 | else |
Benoit | 1:f4040665bc61 | 325 | { |
Benoit | 1:f4040665bc61 | 326 | while (ARP_ResolveIPv4Address(netIF, ipv4Header->dest, ðernetHeader->destination)) |
Benoit | 1:f4040665bc61 | 327 | { |
Benoit | 1:f4040665bc61 | 328 | DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("%d.%d.%d.%d not in ARP cache", |
Benoit | 1:f4040665bc61 | 329 | ipv4Header->dest.IP0, |
Benoit | 1:f4040665bc61 | 330 | ipv4Header->dest.IP1, |
Benoit | 1:f4040665bc61 | 331 | ipv4Header->dest.IP2, |
Benoit | 1:f4040665bc61 | 332 | ipv4Header->dest.IP3 |
Benoit | 1:f4040665bc61 | 333 | )); |
Benoit | 1:f4040665bc61 | 334 | NetIF_ProcessFrames(); |
Benoit | 1:f4040665bc61 | 335 | } |
Benoit | 1:f4040665bc61 | 336 | } |
Benoit | 1:f4040665bc61 | 337 | |
Benoit | 1:f4040665bc61 | 338 | DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("IPv4 sending %d bytes %d.%d.%d.%d --> %d.%d.%d.%d using %s%d", |
Benoit | 1:f4040665bc61 | 339 | ntohs(ipv4Header->totalLength), |
Benoit | 1:f4040665bc61 | 340 | |
Benoit | 1:f4040665bc61 | 341 | ipv4Header->source.IP0, |
Benoit | 1:f4040665bc61 | 342 | ipv4Header->source.IP1, |
Benoit | 1:f4040665bc61 | 343 | ipv4Header->source.IP2, |
Benoit | 1:f4040665bc61 | 344 | ipv4Header->source.IP3, |
Benoit | 1:f4040665bc61 | 345 | |
Benoit | 1:f4040665bc61 | 346 | ipv4Header->dest.IP0, |
Benoit | 1:f4040665bc61 | 347 | ipv4Header->dest.IP1, |
Benoit | 1:f4040665bc61 | 348 | ipv4Header->dest.IP2, |
Benoit | 1:f4040665bc61 | 349 | ipv4Header->dest.IP3, |
Benoit | 1:f4040665bc61 | 350 | |
Benoit | 1:f4040665bc61 | 351 | netIF->name, |
Benoit | 1:f4040665bc61 | 352 | netIF->index |
Benoit | 1:f4040665bc61 | 353 | |
Benoit | 1:f4040665bc61 | 354 | )); |
Benoit | 1:f4040665bc61 | 355 | |
Benoit | 1:f4040665bc61 | 356 | /* Copy source MAC address */ |
Benoit | 1:f4040665bc61 | 357 | memcpy(ðernetHeader->source, (uint8_t *)netIF->driverParameter, 6); |
Benoit | 1:f4040665bc61 | 358 | ethernetHeader->protocol = htons(ETHERNET_PROTO_IPV4); |
Benoit | 1:f4040665bc61 | 359 | NetIF_ProtoPush(&txPacket, sizeof(Ethernet_Header_t), Protocol_ID_Ethernet); |
Benoit | 1:f4040665bc61 | 360 | |
Benoit | 1:f4040665bc61 | 361 | /* Copy ethernet payload */ |
Benoit | 1:f4040665bc61 | 362 | //ipv4Header = (IPv4_Header_t *)txPacket.data; |
Benoit | 1:f4040665bc61 | 363 | memcpy(txPacket.data, ipv4Header, ntohs(ipv4Header->totalLength)); |
Benoit | 1:f4040665bc61 | 364 | NetIF_ProtoPop(&txPacket); |
Benoit | 1:f4040665bc61 | 365 | |
Benoit | 1:f4040665bc61 | 366 | /* Send packet */ |
Benoit | 1:f4040665bc61 | 367 | result = netIF->driver->Write(txPacket.data, txPacket.length); |
Benoit | 1:f4040665bc61 | 368 | |
Benoit | 1:f4040665bc61 | 369 | Exit: |
Benoit | 1:f4040665bc61 | 370 | RTOS_MUTEX_UNLOCK(netIF_TableMutex); |
Benoit | 1:f4040665bc61 | 371 | return result; |
Benoit | 1:f4040665bc61 | 372 | } |
Benoit | 1:f4040665bc61 | 373 | |
Benoit | 1:f4040665bc61 | 374 | |
Benoit | 1:f4040665bc61 | 375 | int32_t NetIF_Up(NetIF_t *netIF) |
Benoit | 1:f4040665bc61 | 376 | { |
Benoit | 1:f4040665bc61 | 377 | int32_t result = 0; |
Benoit | 1:f4040665bc61 | 378 | |
Benoit | 1:f4040665bc61 | 379 | if (netIF->up) |
Benoit | 1:f4040665bc61 | 380 | { |
Benoit | 1:f4040665bc61 | 381 | result = -1; |
Benoit | 1:f4040665bc61 | 382 | mbedNet_LastError = mbedNetResult_InterfaceAlreadyUp; |
Benoit | 1:f4040665bc61 | 383 | goto Exit; |
Benoit | 1:f4040665bc61 | 384 | } |
Benoit | 1:f4040665bc61 | 385 | |
Benoit | 1:f4040665bc61 | 386 | netIF->driver->Enable(); |
Benoit | 1:f4040665bc61 | 387 | netIF->up = True; |
Benoit | 1:f4040665bc61 | 388 | |
Benoit | 1:f4040665bc61 | 389 | Exit: |
Benoit | 1:f4040665bc61 | 390 | return result; |
Benoit | 1:f4040665bc61 | 391 | } |
Benoit | 1:f4040665bc61 | 392 | |
Benoit | 1:f4040665bc61 | 393 | |
Benoit | 1:f4040665bc61 | 394 | int32_t NetIF_Down(NetIF_t *netIF) |
Benoit | 1:f4040665bc61 | 395 | { |
Benoit | 1:f4040665bc61 | 396 | int32_t result = 0; |
Benoit | 1:f4040665bc61 | 397 | |
Benoit | 1:f4040665bc61 | 398 | if (!netIF->up) |
Benoit | 1:f4040665bc61 | 399 | { |
Benoit | 1:f4040665bc61 | 400 | result = -1; |
Benoit | 1:f4040665bc61 | 401 | mbedNet_LastError = mbedNetResult_InterfaceAlreadyDown; |
Benoit | 1:f4040665bc61 | 402 | goto Exit; |
Benoit | 1:f4040665bc61 | 403 | } |
Benoit | 1:f4040665bc61 | 404 | |
Benoit | 1:f4040665bc61 | 405 | netIF->driver->Disable(); |
Benoit | 1:f4040665bc61 | 406 | netIF->up = False; |
Benoit | 1:f4040665bc61 | 407 | |
Benoit | 1:f4040665bc61 | 408 | Exit: |
Benoit | 1:f4040665bc61 | 409 | return result; |
Benoit | 1:f4040665bc61 | 410 | } |
Benoit | 1:f4040665bc61 | 411 | |
Benoit | 1:f4040665bc61 | 412 | |
Benoit | 1:f4040665bc61 | 413 | void NetIF_ProtoPop(Packet_t *packet) |
Benoit | 1:f4040665bc61 | 414 | { |
Benoit | 1:f4040665bc61 | 415 | static int32_t depth, headerSize, index; |
Benoit | 1:f4040665bc61 | 416 | |
Benoit | 1:f4040665bc61 | 417 | DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length)); |
Benoit | 1:f4040665bc61 | 418 | if (packet->depth >= 0) |
Benoit | 1:f4040665bc61 | 419 | { |
Benoit | 1:f4040665bc61 | 420 | depth = packet->depth; |
Benoit | 1:f4040665bc61 | 421 | headerSize = packet->headerLenTable[depth]; |
Benoit | 1:f4040665bc61 | 422 | |
Benoit | 1:f4040665bc61 | 423 | packet->data -= headerSize; |
Benoit | 1:f4040665bc61 | 424 | packet->length += headerSize; |
Benoit | 1:f4040665bc61 | 425 | |
Benoit | 1:f4040665bc61 | 426 | packet->depth--; |
Benoit | 1:f4040665bc61 | 427 | } |
Benoit | 1:f4040665bc61 | 428 | |
Benoit | 1:f4040665bc61 | 429 | DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (" > Decapsulate: ")); |
Benoit | 1:f4040665bc61 | 430 | DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE1) |
Benoit | 1:f4040665bc61 | 431 | { |
Benoit | 1:f4040665bc61 | 432 | for (index = 0; index <= packet->depth; index++) |
Benoit | 1:f4040665bc61 | 433 | { |
Benoit | 1:f4040665bc61 | 434 | DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (" > %d %s header:%d bytes", index, protocol_IDNames[packet->protocolTable[index]], packet->headerLenTable[index])); |
Benoit | 1:f4040665bc61 | 435 | } |
Benoit | 1:f4040665bc61 | 436 | } |
Benoit | 1:f4040665bc61 | 437 | DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length)); |
Benoit | 1:f4040665bc61 | 438 | } |
Benoit | 1:f4040665bc61 | 439 | |
Benoit | 1:f4040665bc61 | 440 | |
Benoit | 1:f4040665bc61 | 441 | void NetIF_ProtoPush(Packet_t *packet, int32_t headerSize, Protocol_ID_t protocol) |
Benoit | 1:f4040665bc61 | 442 | { |
Benoit | 1:f4040665bc61 | 443 | static int32_t depth, index; |
Benoit | 1:f4040665bc61 | 444 | |
Benoit | 1:f4040665bc61 | 445 | DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length)); |
Benoit | 1:f4040665bc61 | 446 | |
Benoit | 1:f4040665bc61 | 447 | packet->depth++; |
Benoit | 1:f4040665bc61 | 448 | depth = packet->depth; |
Benoit | 1:f4040665bc61 | 449 | |
Benoit | 1:f4040665bc61 | 450 | packet->headerPtrTable[depth] = packet->data; |
Benoit | 1:f4040665bc61 | 451 | packet->headerLenTable[depth] = headerSize; |
Benoit | 1:f4040665bc61 | 452 | packet->protocolTable[depth] = protocol; |
Benoit | 1:f4040665bc61 | 453 | packet->data += headerSize; |
Benoit | 1:f4040665bc61 | 454 | packet->length -= headerSize; |
Benoit | 1:f4040665bc61 | 455 | |
Benoit | 1:f4040665bc61 | 456 | DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (" > Encapsulate: ")); |
Benoit | 1:f4040665bc61 | 457 | DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE1) |
Benoit | 1:f4040665bc61 | 458 | { |
Benoit | 1:f4040665bc61 | 459 | for (index = 0; index <= depth; index++) |
Benoit | 1:f4040665bc61 | 460 | { |
Benoit | 1:f4040665bc61 | 461 | DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (" > %d %s header:%d bytes", index, protocol_IDNames[packet->protocolTable[index]], packet->headerLenTable[index])); |
Benoit | 1:f4040665bc61 | 462 | } |
Benoit | 1:f4040665bc61 | 463 | } |
Benoit | 1:f4040665bc61 | 464 | DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length)); |
Benoit | 1:f4040665bc61 | 465 | } |
Benoit | 1:f4040665bc61 | 466 |