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:
Sun Jun 26 09:56:31 2011 +0000
Revision:
7:8e12f7357b9f
Parent:
6:7f7f29fde21c
Added IPv4 global broadcast address to processed frames inside IPv4 layer.

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