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.

Committer:
Benoit
Date:
Mon Jun 13 13:13:59 2011 +0000
Revision:
5:3cd83fcb1467
Parent:
1:f4040665bc61
Child:
6:7f7f29fde21c
Renamed some types to avoid conflicts with other objects

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Benoit 1:f4040665bc61 1 /*
Benoit 1:f4040665bc61 2 * $Id: Sockets.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 "Sockets.h"
Benoit 1:f4040665bc61 15 #include "IPv4.h"
Benoit 1:f4040665bc61 16 #include "UDPv4.h"
Benoit 1:f4040665bc61 17 #include "Debug.h"
Benoit 5:3cd83fcb1467 18 #include "CQueue.h"
Benoit 1:f4040665bc61 19 #include <string.h>
Benoit 1:f4040665bc61 20 #include <stdlib.h>
Benoit 1:f4040665bc61 21
Benoit 1:f4040665bc61 22
Benoit 1:f4040665bc61 23 #define DEBUG_CURRENT_MODULE_NAME "sockets"
Benoit 1:f4040665bc61 24 #define DEBUG_CURRENT_MODULE_ID DEBUG_MODULE_SOCKETS
Benoit 1:f4040665bc61 25
Benoit 1:f4040665bc61 26
Benoit 1:f4040665bc61 27 #define UDPV4_DATA_OFFSET 8
Benoit 1:f4040665bc61 28
Benoit 1:f4040665bc61 29
Benoit 1:f4040665bc61 30 struct DataBlock
Benoit 1:f4040665bc61 31 {
Benoit 1:f4040665bc61 32 uint8_t *dataPtr,
Benoit 1:f4040665bc61 33 *readPtr;
Benoit 1:f4040665bc61 34 int16_t totalSize,
Benoit 1:f4040665bc61 35 remainingSize;
Benoit 1:f4040665bc61 36 };
Benoit 1:f4040665bc61 37 typedef struct DataBlock DataBlock_t;
Benoit 1:f4040665bc61 38
Benoit 1:f4040665bc61 39
Benoit 1:f4040665bc61 40 enum State
Benoit 1:f4040665bc61 41 {
Benoit 1:f4040665bc61 42 State_Close = 0,
Benoit 1:f4040665bc61 43 State_Open,
Benoit 1:f4040665bc61 44 State_Bound,
Benoit 1:f4040665bc61 45 };
Benoit 1:f4040665bc61 46 typedef enum State State_t;
Benoit 1:f4040665bc61 47
Benoit 1:f4040665bc61 48
Benoit 1:f4040665bc61 49 struct Socket_Entry
Benoit 1:f4040665bc61 50 {
Benoit 1:f4040665bc61 51 //Bool_t inUse;
Benoit 1:f4040665bc61 52 Socket_Family_t family;
Benoit 1:f4040665bc61 53 Socket_Protocol_t protocol;
Benoit 1:f4040665bc61 54 int32_t options;
Benoit 1:f4040665bc61 55 State_t state;
Benoit 1:f4040665bc61 56 Socket_Addr_t *localAddr,
Benoit 1:f4040665bc61 57 *remoteAddr;
Benoit 5:3cd83fcb1467 58 CQueue_t *dataQueue;
Benoit 1:f4040665bc61 59 int32_t index;
Benoit 1:f4040665bc61 60 };
Benoit 1:f4040665bc61 61 typedef struct Socket_Entry Socket_Entry_t;
Benoit 1:f4040665bc61 62
Benoit 1:f4040665bc61 63
Benoit 1:f4040665bc61 64 static Socket_Entry_t socketEntryTable[SOCKET_MAX_COUNT];
Benoit 1:f4040665bc61 65 static Bool_t socketAPIInitialized = False;
Benoit 1:f4040665bc61 66
Benoit 1:f4040665bc61 67
Benoit 1:f4040665bc61 68 static void Init(void);
Benoit 5:3cd83fcb1467 69 static int32_t Hook(NetIF_t *netIF, Protocol_ID_t protocolID, NetPacket_t *packet);
Benoit 5:3cd83fcb1467 70 static void Hook_UDPv4(NetIF_t *netIF, NetPacket_t *packet, Socket_Entry_t *entry);
Benoit 1:f4040665bc61 71 static Socket_Entry_t *GetSocketEntry(Socket_t socket);
Benoit 1:f4040665bc61 72 static int32_t BindUDPv4(Socket_Entry_t *entry, Socket_AddrIn_t *addrIn);
Benoit 1:f4040665bc61 73 static int32_t Recv_Data(Socket_Entry_t *entry, uint8_t *data, int32_t length);
Benoit 1:f4040665bc61 74 static int32_t SendToUDPv4(Socket_Entry_t *entry, uint8_t *data, int32_t length, Socket_AddrIn_t *remoteAddr);
Benoit 1:f4040665bc61 75
Benoit 1:f4040665bc61 76
Benoit 1:f4040665bc61 77 Net_API_t sockets =
Benoit 1:f4040665bc61 78 {
Benoit 1:f4040665bc61 79 API_ID_Sockets,
Benoit 1:f4040665bc61 80 Init,
Benoit 1:f4040665bc61 81 Hook
Benoit 1:f4040665bc61 82 };
Benoit 1:f4040665bc61 83
Benoit 1:f4040665bc61 84
Benoit 1:f4040665bc61 85 static void Init(void)
Benoit 1:f4040665bc61 86 {
Benoit 1:f4040665bc61 87 if (socketAPIInitialized) goto Exit;
Benoit 1:f4040665bc61 88
Benoit 1:f4040665bc61 89 DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing"));
Benoit 1:f4040665bc61 90 memset(socketEntryTable, 0, sizeof(socketEntryTable));
Benoit 1:f4040665bc61 91 socketAPIInitialized = True;
Benoit 1:f4040665bc61 92
Benoit 1:f4040665bc61 93 Exit:
Benoit 1:f4040665bc61 94 return;
Benoit 1:f4040665bc61 95 }
Benoit 1:f4040665bc61 96
Benoit 1:f4040665bc61 97
Benoit 5:3cd83fcb1467 98 static int32_t Hook(NetIF_t *netIF, Protocol_ID_t protocolID, NetPacket_t *packet)
Benoit 1:f4040665bc61 99 {
Benoit 1:f4040665bc61 100 int32_t index = 0;
Benoit 1:f4040665bc61 101 Socket_Entry_t *entry = NULL;
Benoit 1:f4040665bc61 102
Benoit 1:f4040665bc61 103 DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("Hook(%s%d, %s, %d bytes)",
Benoit 1:f4040665bc61 104 netIF->name,
Benoit 1:f4040665bc61 105 netIF->index,
Benoit 1:f4040665bc61 106 protocol_IDNames[protocolID],
Benoit 1:f4040665bc61 107 packet->length
Benoit 1:f4040665bc61 108 ));
Benoit 1:f4040665bc61 109
Benoit 1:f4040665bc61 110 for (index = 0; index < SOCKET_MAX_COUNT; index++)
Benoit 1:f4040665bc61 111 {
Benoit 1:f4040665bc61 112 entry = socketEntryTable + index;
Benoit 1:f4040665bc61 113 if (entry->state != State_Bound) continue;
Benoit 1:f4040665bc61 114 switch(protocolID)
Benoit 1:f4040665bc61 115 {
Benoit 1:f4040665bc61 116 case Protocol_ID_UDPv4:
Benoit 1:f4040665bc61 117 if (entry->protocol == SOCK_DGRAM) Hook_UDPv4(netIF, packet, entry);
Benoit 1:f4040665bc61 118 break;
Benoit 1:f4040665bc61 119
Benoit 1:f4040665bc61 120 default:
Benoit 1:f4040665bc61 121 continue;
Benoit 1:f4040665bc61 122 }
Benoit 1:f4040665bc61 123 }
Benoit 1:f4040665bc61 124
Benoit 1:f4040665bc61 125 return 0;
Benoit 1:f4040665bc61 126 }
Benoit 1:f4040665bc61 127
Benoit 5:3cd83fcb1467 128 static void Hook_UDPv4(NetIF_t *netIF, NetPacket_t *packet, Socket_Entry_t *entry)
Benoit 1:f4040665bc61 129 {
Benoit 1:f4040665bc61 130 IPv4_Header_t *ipv4Header;
Benoit 1:f4040665bc61 131 UDPv4_Header_t *udpv4Header;
Benoit 1:f4040665bc61 132 Socket_AddrIn_t *localAddrIn, *remoteAddrIn;
Benoit 1:f4040665bc61 133 int32_t depth;
Benoit 1:f4040665bc61 134 DataBlock_t *dataBlock;
Benoit 1:f4040665bc61 135
Benoit 1:f4040665bc61 136
Benoit 1:f4040665bc61 137 depth = packet->depth;
Benoit 1:f4040665bc61 138 ipv4Header = (IPv4_Header_t *)packet->headerPtrTable[depth];
Benoit 1:f4040665bc61 139 udpv4Header = (UDPv4_Header_t *)(ipv4Header + 1);
Benoit 1:f4040665bc61 140 localAddrIn = (Socket_AddrIn_t *)entry->localAddr;
Benoit 1:f4040665bc61 141 remoteAddrIn = (Socket_AddrIn_t *)entry->remoteAddr;
Benoit 1:f4040665bc61 142 DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("ports: %d.%d.%d.%d:%d to %d.%d.%d.%d:%d size:%d",
Benoit 1:f4040665bc61 143 ipv4Header->source.IP0,
Benoit 1:f4040665bc61 144 ipv4Header->source.IP1,
Benoit 1:f4040665bc61 145 ipv4Header->source.IP2,
Benoit 1:f4040665bc61 146 ipv4Header->source.IP3,
Benoit 1:f4040665bc61 147 ntohs(udpv4Header->destPort),
Benoit 1:f4040665bc61 148 localAddrIn->address.IP0,
Benoit 1:f4040665bc61 149 localAddrIn->address.IP1,
Benoit 1:f4040665bc61 150 localAddrIn->address.IP2,
Benoit 1:f4040665bc61 151 localAddrIn->address.IP3,
Benoit 1:f4040665bc61 152 ntohs(localAddrIn->port),
Benoit 1:f4040665bc61 153 ntohs(udpv4Header->length)
Benoit 1:f4040665bc61 154 ));
Benoit 1:f4040665bc61 155 if ((localAddrIn->port == udpv4Header->destPort) && ( (localAddrIn->address.addr == IPADDR_ANY) || (ipv4Header->dest.addr == localAddrIn->address.addr) ) )
Benoit 1:f4040665bc61 156 {
Benoit 5:3cd83fcb1467 157 if (!CQueue_IsFull(entry->dataQueue))
Benoit 1:f4040665bc61 158 {
Benoit 1:f4040665bc61 159 remoteAddrIn->address = ipv4Header->source;
Benoit 1:f4040665bc61 160 remoteAddrIn->port = udpv4Header->sourcePort;
Benoit 1:f4040665bc61 161 dataBlock = (DataBlock_t *)malloc(sizeof(DataBlock_t));
Benoit 1:f4040665bc61 162 if (dataBlock == NULL)
Benoit 1:f4040665bc61 163 {
Benoit 1:f4040665bc61 164 mbedNet_LastError = mbedNetResult_NotEnoughMemory;
Benoit 1:f4040665bc61 165 goto Exit;
Benoit 1:f4040665bc61 166 }
Benoit 1:f4040665bc61 167 dataBlock->totalSize = ntohs(udpv4Header->length) - sizeof(UDPv4_Header_t);
Benoit 1:f4040665bc61 168 dataBlock->remainingSize = dataBlock->totalSize;
Benoit 1:f4040665bc61 169 dataBlock->dataPtr = (uint8_t *)malloc(dataBlock->totalSize);
Benoit 1:f4040665bc61 170 if (dataBlock->dataPtr == NULL)
Benoit 1:f4040665bc61 171 {
Benoit 1:f4040665bc61 172 free(dataBlock);
Benoit 1:f4040665bc61 173 mbedNet_LastError = mbedNetResult_NotEnoughMemory;
Benoit 1:f4040665bc61 174 goto Exit;
Benoit 1:f4040665bc61 175 }
Benoit 1:f4040665bc61 176 dataBlock->readPtr = dataBlock->dataPtr;
Benoit 1:f4040665bc61 177 memcpy(dataBlock->dataPtr, packet->data + sizeof(UDPv4_Header_t), dataBlock->totalSize);
Benoit 5:3cd83fcb1467 178 CQueue_Push(entry->dataQueue, (void *)dataBlock);
Benoit 1:f4040665bc61 179 DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("Added block of %d bytes to socket %d", dataBlock->totalSize, entry->index));
Benoit 1:f4040665bc61 180 }
Benoit 1:f4040665bc61 181 }
Benoit 1:f4040665bc61 182
Benoit 1:f4040665bc61 183 Exit:
Benoit 1:f4040665bc61 184 return;
Benoit 1:f4040665bc61 185 }
Benoit 1:f4040665bc61 186
Benoit 1:f4040665bc61 187 static int32_t BindUDPv4(Socket_Entry_t *entry, Socket_AddrIn_t *addrIn)
Benoit 1:f4040665bc61 188 {
Benoit 1:f4040665bc61 189 int32_t result = -1;
Benoit 1:f4040665bc61 190 Socket_AddrIn_t *localAddrIn,
Benoit 1:f4040665bc61 191 *remoteAddrIn;
Benoit 1:f4040665bc61 192
Benoit 1:f4040665bc61 193 entry->localAddr = (Socket_Addr_t *)malloc(sizeof(Socket_AddrIn_t));
Benoit 1:f4040665bc61 194 if (entry->localAddr == NULL)
Benoit 1:f4040665bc61 195 {
Benoit 1:f4040665bc61 196 mbedNet_LastError = mbedNetResult_NotEnoughMemory;
Benoit 1:f4040665bc61 197 goto Exit;
Benoit 1:f4040665bc61 198 }
Benoit 1:f4040665bc61 199 entry->remoteAddr = (Socket_Addr_t *)malloc(sizeof(Socket_AddrIn_t));
Benoit 1:f4040665bc61 200 if (entry->remoteAddr == NULL)
Benoit 1:f4040665bc61 201 {
Benoit 1:f4040665bc61 202 free(entry->localAddr);
Benoit 1:f4040665bc61 203 mbedNet_LastError = mbedNetResult_NotEnoughMemory;
Benoit 1:f4040665bc61 204 goto Exit;
Benoit 1:f4040665bc61 205 }
Benoit 1:f4040665bc61 206 localAddrIn = (Socket_AddrIn_t *)entry->localAddr;
Benoit 1:f4040665bc61 207 remoteAddrIn = (Socket_AddrIn_t *)entry->remoteAddr;
Benoit 1:f4040665bc61 208 memcpy(localAddrIn, addrIn, sizeof(Socket_AddrIn_t));
Benoit 1:f4040665bc61 209 memset(remoteAddrIn, 0, sizeof(Socket_AddrIn_t));
Benoit 1:f4040665bc61 210 remoteAddrIn->family = addrIn->family;
Benoit 1:f4040665bc61 211 remoteAddrIn->len = addrIn->len;
Benoit 1:f4040665bc61 212 localAddrIn->port = addrIn->port;
Benoit 1:f4040665bc61 213
Benoit 1:f4040665bc61 214 DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Binding socket %d to %d.%d.%d.%d:%d",
Benoit 1:f4040665bc61 215 entry->index,
Benoit 1:f4040665bc61 216 addrIn->address.IP0,
Benoit 1:f4040665bc61 217 addrIn->address.IP1,
Benoit 1:f4040665bc61 218 addrIn->address.IP2,
Benoit 1:f4040665bc61 219 addrIn->address.IP3,
Benoit 1:f4040665bc61 220 ntohs(addrIn->port)
Benoit 1:f4040665bc61 221 ));
Benoit 1:f4040665bc61 222
Benoit 1:f4040665bc61 223 Exit:
Benoit 1:f4040665bc61 224 return result;
Benoit 1:f4040665bc61 225 }
Benoit 1:f4040665bc61 226
Benoit 1:f4040665bc61 227
Benoit 1:f4040665bc61 228 static int32_t Recv_Data(Socket_Entry_t *entry, uint8_t *data, int32_t length)
Benoit 1:f4040665bc61 229 {
Benoit 1:f4040665bc61 230 int32_t count = 0;
Benoit 1:f4040665bc61 231 DataBlock_t *dataBlock = NULL;
Benoit 1:f4040665bc61 232
Benoit 5:3cd83fcb1467 233 CQueue_Peek(entry->dataQueue, (void **)&dataBlock);
Benoit 1:f4040665bc61 234 if (dataBlock->remainingSize <= length)
Benoit 1:f4040665bc61 235 {
Benoit 1:f4040665bc61 236 count = dataBlock->remainingSize;
Benoit 5:3cd83fcb1467 237 CQueue_Pop(entry->dataQueue, (void **)&dataBlock);
Benoit 1:f4040665bc61 238 memcpy(data, dataBlock->readPtr, count);
Benoit 1:f4040665bc61 239 free(dataBlock->dataPtr);
Benoit 1:f4040665bc61 240 free(dataBlock);
Benoit 1:f4040665bc61 241 }
Benoit 1:f4040665bc61 242 else
Benoit 1:f4040665bc61 243 {
Benoit 1:f4040665bc61 244 count = length;
Benoit 1:f4040665bc61 245 memcpy(data, dataBlock->readPtr, count);
Benoit 1:f4040665bc61 246 dataBlock->readPtr += count;
Benoit 1:f4040665bc61 247 dataBlock->remainingSize -= count;
Benoit 1:f4040665bc61 248 }
Benoit 1:f4040665bc61 249 return count;
Benoit 1:f4040665bc61 250 }
Benoit 1:f4040665bc61 251
Benoit 1:f4040665bc61 252
Benoit 1:f4040665bc61 253 static int32_t SendToUDPv4(Socket_Entry_t *entry, uint8_t *data, int32_t length, Socket_AddrIn_t *remoteAddr)
Benoit 1:f4040665bc61 254 {
Benoit 1:f4040665bc61 255 int32_t count = -1,
Benoit 1:f4040665bc61 256 totalLength;
Benoit 1:f4040665bc61 257 IPv4_Header_t *ipv4Header;
Benoit 1:f4040665bc61 258 UDPv4_Header_t *udpv4Header;
Benoit 1:f4040665bc61 259 Socket_AddrIn_t *localAddrIn,
Benoit 1:f4040665bc61 260 *remoteAddrIn;
Benoit 1:f4040665bc61 261
Benoit 1:f4040665bc61 262 localAddrIn = (Socket_AddrIn_t *)entry->localAddr;
Benoit 1:f4040665bc61 263 remoteAddrIn = (Socket_AddrIn_t *)entry->remoteAddr;
Benoit 1:f4040665bc61 264 totalLength = length + sizeof(UDPv4_Header_t) + sizeof(IPv4_Header_t);
Benoit 1:f4040665bc61 265 ipv4Header = (IPv4_Header_t *)malloc(totalLength);
Benoit 1:f4040665bc61 266 if (ipv4Header == NULL)
Benoit 1:f4040665bc61 267 {
Benoit 1:f4040665bc61 268 DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Not enough memory (needed %d bytes)", totalLength));
Benoit 1:f4040665bc61 269 mbedNet_LastError = mbedNetResult_NotEnoughMemory;
Benoit 1:f4040665bc61 270 goto Exit;
Benoit 1:f4040665bc61 271 }
Benoit 1:f4040665bc61 272
Benoit 1:f4040665bc61 273 memset(ipv4Header, 0, totalLength);
Benoit 1:f4040665bc61 274
Benoit 1:f4040665bc61 275 DEBUG_SOURCE(DEBUG_LEVEL_VERBOSE0, ("UDPv4 sending %d bytes to %d.%d.%d.%d:%d",
Benoit 1:f4040665bc61 276 length,
Benoit 1:f4040665bc61 277 remoteAddr->address.IP0,
Benoit 1:f4040665bc61 278 remoteAddr->address.IP1,
Benoit 1:f4040665bc61 279 remoteAddr->address.IP2,
Benoit 1:f4040665bc61 280 remoteAddr->address.IP3,
Benoit 1:f4040665bc61 281 ntohs(remoteAddr->port)
Benoit 1:f4040665bc61 282
Benoit 1:f4040665bc61 283 ));
Benoit 1:f4040665bc61 284
Benoit 1:f4040665bc61 285 udpv4Header = (UDPv4_Header_t *)(ipv4Header + 1);
Benoit 1:f4040665bc61 286
Benoit 1:f4040665bc61 287 ipv4Header->ihl = 5;
Benoit 1:f4040665bc61 288 ipv4Header->version = IPV4_VERSION;
Benoit 1:f4040665bc61 289 ipv4Header->tos = 0;
Benoit 1:f4040665bc61 290 ipv4Header->totalLength = htons(5 * 4 + totalLength);
Benoit 1:f4040665bc61 291 ipv4Header->id = 0;
Benoit 1:f4040665bc61 292 ipv4Header->fragmentFlags = 0;
Benoit 1:f4040665bc61 293 ipv4Header->ttl = NET_DEFAULT_TTL;
Benoit 1:f4040665bc61 294 ipv4Header->protocol = IPV4_PROTO_UDPV4;
Benoit 1:f4040665bc61 295 ipv4Header->dest = remoteAddr->address;
Benoit 1:f4040665bc61 296
Benoit 1:f4040665bc61 297 udpv4Header->sourcePort = localAddrIn->port;
Benoit 1:f4040665bc61 298 udpv4Header->destPort = remoteAddrIn->port;
Benoit 1:f4040665bc61 299 udpv4Header->length = htons(length + sizeof(UDPv4_Header_t));
Benoit 1:f4040665bc61 300
Benoit 1:f4040665bc61 301 memcpy(udpv4Header + 1, data, length);
Benoit 1:f4040665bc61 302
Benoit 1:f4040665bc61 303 DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE0)
Benoit 1:f4040665bc61 304 {
Benoit 1:f4040665bc61 305 IPv4_DumpIPv4Header("Sockets:", ipv4Header);
Benoit 1:f4040665bc61 306 }
Benoit 1:f4040665bc61 307
Benoit 1:f4040665bc61 308 count = NetIF_SendIPv4Packet(ipv4Header);
Benoit 1:f4040665bc61 309 free(ipv4Header);
Benoit 1:f4040665bc61 310
Benoit 1:f4040665bc61 311 Exit:
Benoit 1:f4040665bc61 312 return count;
Benoit 1:f4040665bc61 313 }
Benoit 1:f4040665bc61 314
Benoit 1:f4040665bc61 315
Benoit 1:f4040665bc61 316 Socket_t Sockets_Open(Socket_Family_t family, Socket_Protocol_t protocol, int32_t options)
Benoit 1:f4040665bc61 317 {
Benoit 1:f4040665bc61 318 int32_t result = 0,
Benoit 1:f4040665bc61 319 index = 0;
Benoit 1:f4040665bc61 320 Socket_Entry_t *entry = NULL;
Benoit 1:f4040665bc61 321
Benoit 1:f4040665bc61 322 if (family != AF_INET)
Benoit 1:f4040665bc61 323 {
Benoit 1:f4040665bc61 324 DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Protocol family not supported"));
Benoit 1:f4040665bc61 325 mbedNet_LastError = mbedNetResult_NotIplemented;
Benoit 1:f4040665bc61 326 result = -1;
Benoit 1:f4040665bc61 327 goto Exit;
Benoit 1:f4040665bc61 328 }
Benoit 1:f4040665bc61 329
Benoit 1:f4040665bc61 330 for (index = 0; index < SOCKET_MAX_COUNT; index++)
Benoit 1:f4040665bc61 331 {
Benoit 1:f4040665bc61 332 if (socketEntryTable[index].state != State_Close) continue;
Benoit 1:f4040665bc61 333 entry = socketEntryTable + index;
Benoit 1:f4040665bc61 334 break;
Benoit 1:f4040665bc61 335 }
Benoit 1:f4040665bc61 336
Benoit 1:f4040665bc61 337 if (entry == NULL)
Benoit 1:f4040665bc61 338 {
Benoit 1:f4040665bc61 339 DEBUG_MODULE(DEBUG_LEVEL_WARNING, ("Too many open sockets"));
Benoit 1:f4040665bc61 340 mbedNet_LastError = mbedNetResult_TooManyOpenSockets;
Benoit 1:f4040665bc61 341 result = -1;
Benoit 1:f4040665bc61 342 goto Exit;
Benoit 1:f4040665bc61 343 }
Benoit 1:f4040665bc61 344
Benoit 1:f4040665bc61 345 entry->family = family;
Benoit 1:f4040665bc61 346 entry->protocol = protocol;
Benoit 1:f4040665bc61 347 entry->options = options;
Benoit 1:f4040665bc61 348 entry->state = State_Open;
Benoit 1:f4040665bc61 349 entry->dataQueue = NULL;
Benoit 1:f4040665bc61 350 entry->index = index;
Benoit 1:f4040665bc61 351 result = index;
Benoit 1:f4040665bc61 352
Benoit 1:f4040665bc61 353 Exit:
Benoit 1:f4040665bc61 354 DEBUG_MODULE(DEBUG_LEVEL_INFO, ("opened socket %d", index));
Benoit 1:f4040665bc61 355 return result;
Benoit 1:f4040665bc61 356 }
Benoit 1:f4040665bc61 357
Benoit 1:f4040665bc61 358
Benoit 1:f4040665bc61 359 int32_t Sockets_Bind(Socket_t socket, Socket_Addr_t *addr, int32_t addrLen)
Benoit 1:f4040665bc61 360 {
Benoit 1:f4040665bc61 361 int32_t result = -1;
Benoit 1:f4040665bc61 362 Socket_Entry_t *entry;
Benoit 1:f4040665bc61 363
Benoit 1:f4040665bc61 364 if ((entry = GetSocketEntry(socket)) == NULL) goto Exit;
Benoit 1:f4040665bc61 365
Benoit 1:f4040665bc61 366 if (entry == NULL)
Benoit 1:f4040665bc61 367 {
Benoit 1:f4040665bc61 368 DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Socket %d not found", socket));
Benoit 1:f4040665bc61 369 mbedNet_LastError = mbedNetResult_NotEnoughMemory;
Benoit 1:f4040665bc61 370 result = -1;
Benoit 1:f4040665bc61 371 goto Exit;
Benoit 1:f4040665bc61 372 }
Benoit 1:f4040665bc61 373
Benoit 1:f4040665bc61 374 /* Allocate address entry */
Benoit 1:f4040665bc61 375 switch(entry->family)
Benoit 1:f4040665bc61 376 {
Benoit 1:f4040665bc61 377 case AF_INET:
Benoit 1:f4040665bc61 378 switch(entry->protocol)
Benoit 1:f4040665bc61 379 {
Benoit 1:f4040665bc61 380 case SOCK_DGRAM:
Benoit 1:f4040665bc61 381 if (addrLen != sizeof(Socket_AddrIn_t))
Benoit 1:f4040665bc61 382 {
Benoit 1:f4040665bc61 383 mbedNet_LastError = mbedNetResult_InvalidParameter;
Benoit 1:f4040665bc61 384 result = -1;
Benoit 1:f4040665bc61 385 goto Exit;
Benoit 1:f4040665bc61 386 }
Benoit 1:f4040665bc61 387 result = BindUDPv4(entry, (Socket_AddrIn_t *)addr);
Benoit 1:f4040665bc61 388 break;
Benoit 1:f4040665bc61 389
Benoit 1:f4040665bc61 390 case SOCK_STREAM:
Benoit 1:f4040665bc61 391 DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Protocol not supported"));
Benoit 1:f4040665bc61 392 mbedNet_LastError = mbedNetResult_NotIplemented;
Benoit 1:f4040665bc61 393 result = -1;
Benoit 1:f4040665bc61 394 goto Exit;
Benoit 1:f4040665bc61 395
Benoit 1:f4040665bc61 396 case SOCK_RAW:
Benoit 1:f4040665bc61 397 DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Protocol not supported"));
Benoit 1:f4040665bc61 398 mbedNet_LastError = mbedNetResult_NotIplemented;
Benoit 1:f4040665bc61 399 result = -1;
Benoit 1:f4040665bc61 400 goto Exit;
Benoit 1:f4040665bc61 401
Benoit 1:f4040665bc61 402 default:
Benoit 1:f4040665bc61 403 DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Unknown socket protocol"));
Benoit 1:f4040665bc61 404 mbedNet_LastError = mbedNetResult_InvalidParameter;
Benoit 1:f4040665bc61 405 result = -1;
Benoit 1:f4040665bc61 406 goto Exit;
Benoit 1:f4040665bc61 407 }
Benoit 1:f4040665bc61 408 break;
Benoit 1:f4040665bc61 409
Benoit 1:f4040665bc61 410 default:
Benoit 1:f4040665bc61 411 DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Protocol family not supported"));
Benoit 1:f4040665bc61 412 mbedNet_LastError = mbedNetResult_NotIplemented;
Benoit 1:f4040665bc61 413 result = -1;
Benoit 1:f4040665bc61 414 goto Exit;
Benoit 1:f4040665bc61 415 }
Benoit 1:f4040665bc61 416
Benoit 5:3cd83fcb1467 417 entry->dataQueue = CQueue_Alloc(SOCKET_DATAQUEUE_ENTRY_COUNT);
Benoit 1:f4040665bc61 418
Benoit 1:f4040665bc61 419 if (entry == NULL)
Benoit 1:f4040665bc61 420 {
Benoit 1:f4040665bc61 421 free(entry->localAddr);
Benoit 1:f4040665bc61 422 free(entry->remoteAddr);
Benoit 1:f4040665bc61 423 DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Not enough memory to allocate data queue"));
Benoit 1:f4040665bc61 424 mbedNet_LastError = mbedNetResult_NotEnoughMemory;
Benoit 1:f4040665bc61 425 result = -1;
Benoit 1:f4040665bc61 426 goto Exit;
Benoit 1:f4040665bc61 427 }
Benoit 1:f4040665bc61 428
Benoit 1:f4040665bc61 429 entry->state = State_Bound;
Benoit 1:f4040665bc61 430
Benoit 1:f4040665bc61 431 result = 0;
Benoit 1:f4040665bc61 432
Benoit 1:f4040665bc61 433 Exit:
Benoit 1:f4040665bc61 434 return result;
Benoit 1:f4040665bc61 435 }
Benoit 1:f4040665bc61 436
Benoit 1:f4040665bc61 437
Benoit 1:f4040665bc61 438 int32_t Sockets_Send(Socket_t socket, uint8_t *data, int32_t length, int32_t flags)
Benoit 1:f4040665bc61 439 {
Benoit 1:f4040665bc61 440 int32_t count = -1;
Benoit 1:f4040665bc61 441 Socket_Entry_t *entry;
Benoit 1:f4040665bc61 442
Benoit 1:f4040665bc61 443 entry = GetSocketEntry(socket);
Benoit 1:f4040665bc61 444 if (entry == NULL) goto Exit;
Benoit 1:f4040665bc61 445
Benoit 1:f4040665bc61 446 if (entry->protocol == SOCK_DGRAM)
Benoit 1:f4040665bc61 447 {
Benoit 1:f4040665bc61 448 mbedNet_LastError = mbedNetResult_DestinationAddressRequired;
Benoit 1:f4040665bc61 449 goto Exit;
Benoit 1:f4040665bc61 450 }
Benoit 1:f4040665bc61 451
Benoit 1:f4040665bc61 452 mbedNet_LastError = mbedNetResult_NotIplemented;
Benoit 1:f4040665bc61 453
Benoit 1:f4040665bc61 454 Exit:
Benoit 1:f4040665bc61 455 return count;
Benoit 1:f4040665bc61 456 }
Benoit 1:f4040665bc61 457
Benoit 1:f4040665bc61 458
Benoit 1:f4040665bc61 459 int32_t Sockets_SendTo(Socket_t socket, uint8_t *data, int32_t length, int32_t flags, const Socket_Addr_t *remoteAddr, int32_t addrLen)
Benoit 1:f4040665bc61 460 {
Benoit 1:f4040665bc61 461 int32_t count = -1;
Benoit 1:f4040665bc61 462 Socket_Entry_t *entry;
Benoit 1:f4040665bc61 463
Benoit 1:f4040665bc61 464
Benoit 1:f4040665bc61 465 entry = GetSocketEntry(socket);
Benoit 1:f4040665bc61 466 if (entry == NULL)
Benoit 1:f4040665bc61 467 {
Benoit 1:f4040665bc61 468 DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("socket not found!"));
Benoit 1:f4040665bc61 469 goto Exit;
Benoit 1:f4040665bc61 470 }
Benoit 1:f4040665bc61 471
Benoit 1:f4040665bc61 472 switch(entry->family)
Benoit 1:f4040665bc61 473 {
Benoit 1:f4040665bc61 474 case AF_INET:
Benoit 1:f4040665bc61 475 switch(entry->protocol)
Benoit 1:f4040665bc61 476 {
Benoit 1:f4040665bc61 477 case SOCK_DGRAM:
Benoit 1:f4040665bc61 478 if (addrLen != sizeof(Socket_AddrIn_t))
Benoit 1:f4040665bc61 479 {
Benoit 1:f4040665bc61 480 DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Invalid socket address length"));
Benoit 1:f4040665bc61 481 mbedNet_LastError = mbedNetResult_InvalidParameter;
Benoit 1:f4040665bc61 482 goto Exit;
Benoit 1:f4040665bc61 483 }
Benoit 1:f4040665bc61 484 count = SendToUDPv4(entry, data, length, (Socket_AddrIn_t *)remoteAddr);
Benoit 1:f4040665bc61 485 break;
Benoit 1:f4040665bc61 486
Benoit 1:f4040665bc61 487 default:
Benoit 1:f4040665bc61 488 DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Protocol not implemented"));
Benoit 1:f4040665bc61 489 mbedNet_LastError = mbedNetResult_NotIplemented;
Benoit 1:f4040665bc61 490 goto Exit;
Benoit 1:f4040665bc61 491 }
Benoit 1:f4040665bc61 492 break;
Benoit 1:f4040665bc61 493
Benoit 1:f4040665bc61 494 default:
Benoit 1:f4040665bc61 495 DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Protocol family not implemented"));
Benoit 1:f4040665bc61 496 mbedNet_LastError = mbedNetResult_NotIplemented;
Benoit 1:f4040665bc61 497 goto Exit;
Benoit 1:f4040665bc61 498 }
Benoit 1:f4040665bc61 499
Benoit 1:f4040665bc61 500 Exit:
Benoit 1:f4040665bc61 501 return count;
Benoit 1:f4040665bc61 502 }
Benoit 1:f4040665bc61 503
Benoit 1:f4040665bc61 504
Benoit 1:f4040665bc61 505 int32_t Sockets_Recv(Socket_t socket, uint8_t *data, int32_t length, int32_t flags)
Benoit 1:f4040665bc61 506 {
Benoit 1:f4040665bc61 507 int32_t count = -1;
Benoit 1:f4040665bc61 508 Socket_Entry_t *entry;
Benoit 1:f4040665bc61 509
Benoit 1:f4040665bc61 510 entry = GetSocketEntry(socket);
Benoit 1:f4040665bc61 511 if (entry == NULL) goto Exit;
Benoit 1:f4040665bc61 512
Benoit 5:3cd83fcb1467 513 if (CQueue_IsEmpty(entry->dataQueue))
Benoit 1:f4040665bc61 514 {
Benoit 1:f4040665bc61 515 mbedNet_LastError = mbedNetResult_WouldBlock;
Benoit 1:f4040665bc61 516 goto Exit;
Benoit 1:f4040665bc61 517 }
Benoit 1:f4040665bc61 518
Benoit 1:f4040665bc61 519 count = Recv_Data(entry, data, length);
Benoit 1:f4040665bc61 520
Benoit 1:f4040665bc61 521 Exit:
Benoit 1:f4040665bc61 522 return count;
Benoit 1:f4040665bc61 523 }
Benoit 1:f4040665bc61 524
Benoit 1:f4040665bc61 525
Benoit 1:f4040665bc61 526 int32_t Sockets_RecvFrom(Socket_t socket, uint8_t *data, int32_t length, int32_t flags, Socket_Addr_t *remoteAddr, int32_t *addrLen)
Benoit 1:f4040665bc61 527 {
Benoit 1:f4040665bc61 528 int32_t count = -1;
Benoit 1:f4040665bc61 529 Socket_Entry_t *entry;
Benoit 1:f4040665bc61 530
Benoit 1:f4040665bc61 531 entry = GetSocketEntry(socket);
Benoit 1:f4040665bc61 532 if (entry == NULL) goto Exit;
Benoit 1:f4040665bc61 533
Benoit 5:3cd83fcb1467 534 if (CQueue_IsEmpty(entry->dataQueue))
Benoit 1:f4040665bc61 535 {
Benoit 1:f4040665bc61 536 mbedNet_LastError = mbedNetResult_WouldBlock;
Benoit 1:f4040665bc61 537 goto Exit;
Benoit 1:f4040665bc61 538 }
Benoit 1:f4040665bc61 539
Benoit 1:f4040665bc61 540 if (remoteAddr != NULL)
Benoit 1:f4040665bc61 541 {
Benoit 1:f4040665bc61 542 if (entry->localAddr->len > *addrLen)
Benoit 1:f4040665bc61 543 {
Benoit 1:f4040665bc61 544 mbedNet_LastError = mbedNetResult_BufferTooSmall;
Benoit 1:f4040665bc61 545 goto Exit;
Benoit 1:f4040665bc61 546 }
Benoit 1:f4040665bc61 547 memcpy(remoteAddr, entry->remoteAddr, entry->remoteAddr->len);
Benoit 1:f4040665bc61 548 }
Benoit 1:f4040665bc61 549
Benoit 1:f4040665bc61 550 count = Recv_Data(entry, data, length);
Benoit 1:f4040665bc61 551
Benoit 1:f4040665bc61 552 Exit:
Benoit 1:f4040665bc61 553 return count;
Benoit 1:f4040665bc61 554 }
Benoit 1:f4040665bc61 555
Benoit 1:f4040665bc61 556
Benoit 1:f4040665bc61 557 int32_t Sockets_Close(Socket_t socket)
Benoit 1:f4040665bc61 558 {
Benoit 1:f4040665bc61 559 int32_t result = -1;
Benoit 1:f4040665bc61 560 Socket_Entry_t *entry;
Benoit 1:f4040665bc61 561 void *ptr;
Benoit 1:f4040665bc61 562
Benoit 1:f4040665bc61 563 if ((entry = GetSocketEntry(socket)) == NULL) goto Exit;
Benoit 1:f4040665bc61 564
Benoit 1:f4040665bc61 565 entry->state = State_Close;
Benoit 1:f4040665bc61 566 free(entry->localAddr);
Benoit 1:f4040665bc61 567 entry->localAddr = NULL;
Benoit 1:f4040665bc61 568 free(entry->remoteAddr);
Benoit 1:f4040665bc61 569 entry->remoteAddr = NULL;
Benoit 1:f4040665bc61 570 /* Free pending data blocks */
Benoit 5:3cd83fcb1467 571 while(CQueue_Peek(entry->dataQueue, &ptr) != -1)
Benoit 1:f4040665bc61 572 {
Benoit 1:f4040665bc61 573 free(ptr);
Benoit 1:f4040665bc61 574 }
Benoit 5:3cd83fcb1467 575 CQueue_Free(entry->dataQueue);
Benoit 1:f4040665bc61 576 entry->dataQueue = NULL;
Benoit 1:f4040665bc61 577 result = 0;
Benoit 1:f4040665bc61 578
Benoit 1:f4040665bc61 579 Exit:
Benoit 1:f4040665bc61 580 DEBUG_MODULE(DEBUG_LEVEL_INFO, ("closed socket %d", socket));
Benoit 1:f4040665bc61 581 return result;
Benoit 1:f4040665bc61 582 }
Benoit 1:f4040665bc61 583
Benoit 1:f4040665bc61 584
Benoit 1:f4040665bc61 585
Benoit 1:f4040665bc61 586 static Socket_Entry_t *GetSocketEntry(Socket_t socket)
Benoit 1:f4040665bc61 587 {
Benoit 1:f4040665bc61 588 Socket_Entry_t *entry = NULL;
Benoit 1:f4040665bc61 589
Benoit 1:f4040665bc61 590 if ((socket < 0) || (socket >= SOCKET_MAX_COUNT))
Benoit 1:f4040665bc61 591 {
Benoit 1:f4040665bc61 592 DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Invalid socket handle"));
Benoit 1:f4040665bc61 593 mbedNet_LastError = mbedNetResult_InvalidSocketHandle;
Benoit 1:f4040665bc61 594 goto Exit;
Benoit 1:f4040665bc61 595 }
Benoit 1:f4040665bc61 596 entry = socketEntryTable + socket;
Benoit 1:f4040665bc61 597
Benoit 1:f4040665bc61 598 if (entry->state == State_Close)
Benoit 1:f4040665bc61 599 {
Benoit 1:f4040665bc61 600 DEBUG_MODULE(DEBUG_LEVEL_WARNING, ("Socket already closed"));
Benoit 1:f4040665bc61 601 mbedNet_LastError = mbedNetResult_SocketAlreadyClosed;
Benoit 1:f4040665bc61 602 entry = NULL;
Benoit 1:f4040665bc61 603 goto Exit;
Benoit 1:f4040665bc61 604 }
Benoit 1:f4040665bc61 605 Exit:
Benoit 1:f4040665bc61 606 return entry;
Benoit 1:f4040665bc61 607 }