1 /*
2 * Copyright (c) 2017-2020, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /*****************************************************************************/
34 /* Include files */
35 /*****************************************************************************/
36
37 #include <stdint.h>
38 #include <stddef.h>
39 #include <stdbool.h>
40 #include <string.h>
41 #include <stdlib.h>
42
43 #include <ti/net/slnetsock.h>
44 #include <ti/net/slnetutils.h>
45 #include <ti/net/slnetif.h>
46 #include <ti/net/slneterr.h>
47
48 /* POSIX Header files */
49 /* Changed include path to match Zephyr posix */
50 #include <posix/semaphore.h>
51
52 /*****************************************************************************/
53 /* Macro declarations */
54 /*****************************************************************************/
55 #define SLNETSOCK_NORMALIZE_NEEDED 0
56 #if SLNETSOCK_NORMALIZE_NEEDED
57 #define SLNETSOCK_NORMALIZE_RET_VAL(retVal,err) ((retVal < 0)?(retVal = err):(retVal))
58 #else
59 #define SLNETSOCK_NORMALIZE_RET_VAL(retVal,err)
60 #endif
61
62 #define SLNETSOCK_IPV4_ADDR_LEN (4)
63 #define SLNETSOCK_IPV6_ADDR_LEN (16)
64
65 #define SLNETSOCK_SIZEOF_ONE_SDSETBITMAP_SLOT_IN_BITS (sizeof(uint32_t)*8)
66
67 #define SLNETSOCK_LOCK() sem_wait(&VirtualSocketSem)
68 #define SLNETSOCK_UNLOCK() sem_post(&VirtualSocketSem)
69
70 #define ENABLE_DEFAULT_QUERY_FLAGS() (SLNETSOCK_CREATE_IF_STATE_ENABLE | SLNETSOCK_CREATE_IF_STATUS_CONNECTED | SLNETSOCK_CREATE_ALLOW_PARTIAL_MATCH)
71 #define GET_QUERY_FLAGS(flags) (flags & (SLNETSOCK_CREATE_IF_STATE_ENABLE | SLNETSOCK_CREATE_IF_STATUS_CONNECTED | SLNETSOCK_CREATE_ALLOW_PARTIAL_MATCH))
72
73 /* Macro which merge the 8bit security flags to the upper bits of the 32 bit
74 input flags */
75 #define MERGE_SEC_INTO_INPUT_FLAGS(inputFlags, secFlags) (inputFlags |= (secFlags << 24))
76
77
78 /*****************************************************************************/
79 /* Structure/Enum declarations */
80 /*****************************************************************************/
81
82
83 /* Socket Endpoint */
84 typedef struct SlNetSock_VirtualSocket_t
85 {
86 int16_t realSd;
87 uint8_t sdFlags;
88 void *sdContext;
89 SlNetIf_t *netIf;
90 } SlNetSock_VirtualSocket_t;
91
92 /* Structure which holds the realSd and the virtualSd indexes */
93 typedef struct SlNetSock_RealToVirtualIndexes_t
94 {
95 int16_t realSd;
96 int16_t virtualSd;
97 struct SlNetSock_RealToVirtualIndexes_t *next;
98 } SlNetSock_RealToVirtualIndexes_t;
99
100 /*****************************************************************************/
101 /* Global declarations */
102 /*****************************************************************************/
103
104 static SlNetSock_VirtualSocket_t *VirtualSockets[SLNETSOCK_MAX_CONCURRENT_SOCKETS];
105 static uint8_t SlNetSock_Initialized = false;
106
107 /* semaphore to protect VirtualSockets[] */
108 static sem_t VirtualSocketSem;
109
110
111 /*****************************************************************************/
112 /* Function prototypes */
113 /*****************************************************************************/
114
115 static int32_t SlNetSock_getVirtualSdConf(int16_t virtualSdIndex, int16_t *realSd, uint8_t *sdFlags, void **sdContext, SlNetIf_t **netIf);
116 static int32_t SlNetSock_AllocVirtualSocket(int16_t *virtualSdIndex, SlNetSock_VirtualSocket_t **newSocketNode);
117 static int32_t SlNetSock_freeVirtualSocket(int16_t virtualSdIndex);
118
119 //*****************************************************************************
120 //
121 // SlNetSock_getVirtualSdConf - This function search and returns the
122 // configuration of virtual socket.
123 //
124 //*****************************************************************************
SlNetSock_getVirtualSdConf(int16_t virtualSdIndex,int16_t * realSd,uint8_t * sdFlags,void ** sdContext,SlNetIf_t ** netIf)125 static int32_t SlNetSock_getVirtualSdConf(int16_t virtualSdIndex, int16_t *realSd, uint8_t *sdFlags, void **sdContext, SlNetIf_t **netIf)
126 {
127 int32_t retVal = SLNETERR_RET_CODE_OK;
128
129 if (false == SlNetSock_Initialized)
130 {
131 return SLNETERR_RET_CODE_MUTEX_CREATION_FAILED;
132 }
133
134 SLNETSOCK_LOCK();
135
136 /* Check if the input is valid and if real socket descriptor exists */
137 if ( (virtualSdIndex >= SLNETSOCK_MAX_CONCURRENT_SOCKETS) || (virtualSdIndex < 0) || (NULL == netIf) )
138 {
139 retVal = SLNETERR_RET_CODE_INVALID_INPUT;
140 }
141 else if (NULL == VirtualSockets[virtualSdIndex])
142 {
143 /* Socket was not found, return error code */
144 retVal = SLNETERR_RET_CODE_COULDNT_FIND_RESOURCE;
145 }
146 else
147 {
148 /* Socket found, copy and return its content */
149 *netIf = VirtualSockets[virtualSdIndex]->netIf;
150 *realSd = VirtualSockets[virtualSdIndex]->realSd;
151
152 /* If sdContext pointer supplied, copy into it the sdContext of the
153 socket */
154 if ( NULL != sdContext )
155 {
156 *sdContext = VirtualSockets[virtualSdIndex]->sdContext;
157 }
158
159 /* If sdFlags pointer supplied, copy into it the sdFlags of the
160 socket */
161 if ( NULL != sdFlags )
162 {
163 *sdFlags = VirtualSockets[virtualSdIndex]->sdFlags;
164 }
165
166 /* Check if the interface of the socket is declared */
167 if ( (NULL == (*netIf)) || (NULL == (*netIf)->ifConf) )
168 {
169 /* Interface was not found or config list is missing,
170 return error code */
171 retVal = SLNETERR_RET_CODE_SOCKET_CREATION_IN_PROGRESS;
172 }
173 }
174
175 SLNETSOCK_UNLOCK();
176
177 return retVal;
178 }
179
180 //*****************************************************************************
181 //
182 // SlNetSock_AllocVirtualSocket - Search for free space in the VirtualSockets
183 // array and allocate a socket in this location
184 //
185 //*****************************************************************************
SlNetSock_AllocVirtualSocket(int16_t * virtualSdIndex,SlNetSock_VirtualSocket_t ** newSocketNode)186 static int32_t SlNetSock_AllocVirtualSocket(int16_t *virtualSdIndex, SlNetSock_VirtualSocket_t **newSocketNode)
187 {
188 uint16_t arrayIndex = 0;
189 int32_t retVal = SLNETERR_RET_CODE_NO_FREE_SPACE;
190
191 if (false == SlNetSock_Initialized)
192 {
193 return SLNETERR_RET_CODE_MUTEX_CREATION_FAILED;
194 }
195
196 SLNETSOCK_LOCK();
197
198 /* Search for free space in the VirtualSockets array */
199 while ( arrayIndex < SLNETSOCK_MAX_CONCURRENT_SOCKETS )
200 {
201 /* Check if the arrayIndex in VirtualSockets is free */
202 if ( NULL == VirtualSockets[arrayIndex] )
203 {
204 /* Allocate memory for new socket node for the socket list */
205 *newSocketNode = (SlNetSock_VirtualSocket_t *)calloc(1, sizeof(SlNetSock_VirtualSocket_t));
206
207 /* Check if the memory allocated successfully */
208 if (NULL == *newSocketNode)
209 {
210 /* Allocation failed, return error code */
211 retVal = SLNETERR_RET_CODE_MALLOC_ERROR;
212 break;
213 }
214 else
215 {
216 /* Location free, return the Index and function success */
217 *virtualSdIndex = arrayIndex;
218
219 VirtualSockets[arrayIndex] = *newSocketNode;
220
221 retVal = SLNETERR_RET_CODE_OK;
222 break;
223 }
224 }
225 else
226 {
227 /* Location isn't free, continue to next location */
228 arrayIndex++;
229 }
230 }
231
232 SLNETSOCK_UNLOCK();
233
234 return retVal;
235 }
236
237 //*****************************************************************************
238 //
239 // SlNetSock_freeVirtualSocket - free allocated socket and initialize the array
240 // in the virtual socket location
241 //
242 //*****************************************************************************
SlNetSock_freeVirtualSocket(int16_t virtualSdIndex)243 static int32_t SlNetSock_freeVirtualSocket(int16_t virtualSdIndex)
244 {
245 int32_t retVal = SLNETERR_RET_CODE_OK;
246
247 if (false == SlNetSock_Initialized)
248 {
249 return SLNETERR_RET_CODE_MUTEX_CREATION_FAILED;
250 }
251
252 SLNETSOCK_LOCK();
253
254 /* Check if the input is valid and if real socket descriptor exists */
255 if ( (virtualSdIndex >= SLNETSOCK_MAX_CONCURRENT_SOCKETS) || (virtualSdIndex < 0) )
256 {
257 retVal = SLNETERR_RET_CODE_INVALID_INPUT;
258 }
259 else if (NULL == VirtualSockets[virtualSdIndex])
260 {
261 /* Socket was not found, return error code */
262 retVal = SLNETERR_RET_CODE_COULDNT_FIND_RESOURCE;
263 }
264 else
265 {
266 /* Free Socket Context allocated memory */
267 if (NULL != VirtualSockets[virtualSdIndex]->sdContext)
268 {
269 free((void *)VirtualSockets[virtualSdIndex]->sdContext);
270 }
271
272 /* Free Socket Node allocated memory and delete it from the
273 VirtualSockets array */
274 free((void *)VirtualSockets[virtualSdIndex]);
275
276 VirtualSockets[virtualSdIndex] = NULL;
277 }
278
279 SLNETSOCK_UNLOCK();
280
281 return retVal;
282 }
283
284 //*****************************************************************************
285 //
286 // SlNetSock_init - init the SlNetSock module
287 //
288 //*****************************************************************************
SlNetSock_init(int32_t flags)289 int32_t SlNetSock_init(int32_t flags)
290 {
291 int16_t Index = SLNETSOCK_MAX_CONCURRENT_SOCKETS;
292 int32_t retVal;
293
294 /* If the SlNetSock layer isn't initialized, initialize it */
295 if (false == SlNetSock_Initialized)
296 {
297 retVal = sem_init(&VirtualSocketSem, 0, 1);
298 if (0 != retVal)
299 {
300 return SLNETERR_RET_CODE_MUTEX_CREATION_FAILED;
301 }
302 else
303 {
304 /* Initialize the VirtualSockets array */
305 while (Index--)
306 {
307 VirtualSockets[Index] = NULL;
308 }
309 SlNetSock_Initialized = true;
310 }
311 }
312 return SLNETERR_RET_CODE_OK;
313 }
314
315
316 //*****************************************************************************
317 //
318 // SlNetSock_create - Create an endpoint for communication
319 //
320 //*****************************************************************************
SlNetSock_create(int16_t domain,int16_t type,int16_t protocol,uint32_t ifBitmap,int16_t flags)321 int16_t SlNetSock_create(int16_t domain, int16_t type, int16_t protocol, uint32_t ifBitmap, int16_t flags)
322 {
323 SlNetIf_t *netIf;
324 SlNetSock_VirtualSocket_t *sdNode;
325 int16_t socketIndex;
326 int16_t createdSd;
327 int16_t queryFlags;
328 int32_t retVal;
329
330
331 /* if flags is zero, enable the default bits */
332 if (0 == flags)
333 {
334 queryFlags = ENABLE_DEFAULT_QUERY_FLAGS();
335 }
336 else
337 {
338 queryFlags = GET_QUERY_FLAGS(flags);
339 }
340
341 /* Search for free place in the array */
342 retVal = SlNetSock_AllocVirtualSocket(&socketIndex, &sdNode);
343
344 /* Before creating a socket, check if there is a free place in the array */
345 if ( retVal < SLNETERR_RET_CODE_OK )
346 {
347 /* There isn't a free space in the array, return error code */
348 return retVal;
349 }
350
351 if (protocol == 0) {
352 switch (type) {
353 case SLNETSOCK_SOCK_STREAM:
354 protocol = SLNETSOCK_PROTO_TCP;
355 break;
356 case SLNETSOCK_SOCK_DGRAM:
357 protocol = SLNETSOCK_PROTO_UDP;
358 break;
359 case SLNETSOCK_SOCK_RAW:
360 default:
361 /* Keep protocol as is for other types */
362 break;
363 }
364 }
365
366 /* When ifBitmap is 0, that means automatic selection of all interfaces
367 is required, enable all bits in ifBitmap */
368 if (0 == ifBitmap)
369 {
370 ifBitmap = ~ifBitmap;
371 }
372
373 /* This loop tries to create a socket on the required interface with the
374 required queryFlags.
375 When multiple interfaces, in addition to the queryFlags it will try
376 to create the socket on the interface with the highest priority */
377 while ( ifBitmap > 0 )
378 {
379 /* Search for the highest priority interface according to the
380 ifBitmap and the queryFlags */
381 netIf = SlNetIf_queryIf(ifBitmap, queryFlags);
382
383 /* Check if the function returned NULL or the requested interface
384 exists */
385 if (NULL == netIf)
386 {
387 /* Free the captured VirtualSockets location */
388 SlNetSock_freeVirtualSocket(socketIndex);
389
390 /* Interface doesn't exists, save error code */
391 return retVal;
392 }
393 else
394 {
395
396 /* Disable the ifID bit from the ifBitmap after finding the
397 netIf */
398 ifBitmap &= ~(netIf->ifID);
399
400 /* Interface exists, try to create new socket */
401 createdSd = (netIf->ifConf)->sockCreate(netIf->ifContext, domain, type, protocol, &(sdNode->sdContext));
402
403 /* Check createdSd for error codes */
404 if (createdSd < 0)
405 {
406 /* sockCreate failed, continue to the next ifID */
407 retVal = createdSd;
408 }
409 else
410 {
411 /* Real socket created, fill the allocated socket node */
412 sdNode->realSd = createdSd;
413 sdNode->netIf = netIf;
414
415 /* Socket created, allocated and connected to the
416 VirtualSockets array, return VirtualSockets index */
417 return socketIndex;
418 }
419 }
420 }
421
422 /* Free the captured VirtualSockets location */
423 SlNetSock_freeVirtualSocket(socketIndex);
424
425 /* There isn't a free space in the array or socket couldn't be opened,
426 return error code */
427 return retVal;
428 }
429
430
431 //*****************************************************************************
432 //
433 // SlNetSock_close - Gracefully close socket
434 //
435 //*****************************************************************************
SlNetSock_close(int16_t sd)436 int32_t SlNetSock_close(int16_t sd)
437 {
438 int32_t retVal = SLNETERR_RET_CODE_OK;
439 int16_t realSd;
440 SlNetIf_t *netIf;
441 void *sdContext;
442
443 /* Check if the sd input exists and return it */
444 retVal = SlNetSock_getVirtualSdConf(sd, &realSd, NULL, &sdContext, &netIf);
445
446 /* Check if sd found */
447 if (SLNETERR_RET_CODE_OK != retVal)
448 {
449 /* Validation failed, return error code */
450 return retVal;
451 }
452
453 /* Function exists in the interface of the socket descriptor, dispatch
454 the Close command */
455 retVal = (netIf->ifConf)->sockClose(realSd, sdContext);
456 SLNETSOCK_NORMALIZE_RET_VAL(retVal,SLNETSOCK_ERR_SOCKCLOSE_FAILED);
457
458 /* When freeing the virtual socket, it will free allocated memory
459 of the sdContext and of the socket node, if other threads will
460 try to use this socket or the retrieved data of the socket the
461 stack needs to return an error.
462
463 The virtual socket resources are freed after a call to close regardless
464 of the return from netIf->sockClose. Recovery of the socket handle is
465 not possible after this function exits. This was one suggestion derived
466 from NS-233. */
467 SlNetSock_freeVirtualSocket(sd);
468 return retVal;
469 }
470
471
472 //*****************************************************************************
473 //
474 // SlNetSock_shutdown - Shutting down parts of a full-duplex connection
475 //
476 //*****************************************************************************
SlNetSock_shutdown(int16_t sd,int16_t how)477 int32_t SlNetSock_shutdown(int16_t sd, int16_t how)
478 {
479 int32_t retVal = SLNETERR_RET_CODE_OK;
480 int16_t realSd;
481 SlNetIf_t *netIf;
482 void *sdContext;
483
484 /* Check if the sd input exists and return it */
485 retVal = SlNetSock_getVirtualSdConf(sd, &realSd, NULL, &sdContext, &netIf);
486
487 /* Check if sd found or if the non mandatory function exists */
488 if (SLNETERR_RET_CODE_OK != retVal)
489 {
490 return retVal;
491 }
492 if (NULL == (netIf->ifConf)->sockShutdown)
493 {
494 /* Non mandatory function doesn't exists, return error code */
495 return SLNETERR_RET_CODE_DOESNT_SUPPORT_NON_MANDATORY_FXN;
496 }
497
498 /* Function exists in the interface of the socket descriptor, dispatch
499 the Shutdown command */
500 retVal = (netIf->ifConf)->sockShutdown(realSd, sdContext, how);
501 SLNETSOCK_NORMALIZE_RET_VAL(retVal,SLNETSOCK_ERR_SOCKSHUTDOWN_FAILED);
502
503 return retVal;
504 }
505
506
507 //*****************************************************************************
508 //
509 // SlNetSock_accept - Accept a connection on a socket
510 //
511 //*****************************************************************************
SlNetSock_accept(int16_t sd,SlNetSock_Addr_t * addr,SlNetSocklen_t * addrlen)512 int16_t SlNetSock_accept(int16_t sd, SlNetSock_Addr_t *addr, SlNetSocklen_t *addrlen)
513 {
514 SlNetSock_VirtualSocket_t *allocSdNode;
515 void *sdContext;
516 int16_t realSd;
517 int16_t socketIndex;
518 int32_t retVal = SLNETERR_RET_CODE_OK;
519
520 /* Search for free place in the array */
521 retVal = SlNetSock_AllocVirtualSocket(&socketIndex, &allocSdNode);
522
523 /* Before creating a socket, check if there is a free place in the array */
524 if ( retVal < SLNETERR_RET_CODE_OK )
525 {
526 /* There isn't a free space in the array, return error code */
527 return retVal;
528 }
529
530 /* Check if the sd input exists and return it */
531 retVal = SlNetSock_getVirtualSdConf(sd, &realSd, &(allocSdNode->sdFlags), &sdContext, &(allocSdNode->netIf));
532
533 /* Check if sd found or if the non mandatory function exists */
534 if (SLNETERR_RET_CODE_OK != retVal)
535 {
536 return retVal;
537 }
538 if (NULL == ((allocSdNode->netIf)->ifConf)->sockAccept)
539 {
540 /* Free the captured VirtualSockets location */
541 SlNetSock_freeVirtualSocket(socketIndex);
542
543 /* Validation failed, return error code */
544 return SLNETERR_RET_CODE_INVALID_INPUT;
545 }
546
547 /* Function exists in the interface of the socket descriptor, dispatch
548 the Accept command */
549 retVal = ((allocSdNode->netIf)->ifConf)->sockAccept(realSd, sdContext, addr, addrlen, allocSdNode->sdFlags, &(allocSdNode->sdContext));
550
551 /* Check retVal for error codes */
552 if (retVal < SLNETERR_RET_CODE_OK)
553 {
554 /* Free the captured VirtualSockets location */
555 SlNetSock_freeVirtualSocket(socketIndex);
556
557 /* sockAccept failed, return error code */
558 return retVal;
559 }
560 else
561 {
562 /* Real socket created, fill the allocated socket node */
563 allocSdNode->realSd = retVal;
564
565 /* Socket created, allocated and connected to the
566 VirtualSockets array, return VirtualSockets index */
567 return socketIndex;
568 }
569
570 }
571
572
573 //*****************************************************************************
574 //
575 // SlNetSock_bind - Assign a name to a socket
576 //
577 //*****************************************************************************
SlNetSock_bind(int16_t sd,const SlNetSock_Addr_t * addr,int16_t addrlen)578 int32_t SlNetSock_bind(int16_t sd, const SlNetSock_Addr_t *addr, int16_t addrlen)
579 {
580 int32_t retVal = SLNETERR_RET_CODE_OK;
581 int16_t realSd;
582 SlNetIf_t *netIf;
583 void *sdContext;
584
585 /* Check if the sd input exists and return it */
586 retVal = SlNetSock_getVirtualSdConf(sd, &realSd, NULL, &sdContext, &netIf);
587
588 /* Check if sd found or if the non mandatory function exists */
589 if (SLNETERR_RET_CODE_OK != retVal)
590 {
591 return retVal;
592 }
593 if (NULL == (netIf->ifConf)->sockBind)
594 {
595 /* Non mandatory function doesn't exists, return error code */
596 return SLNETERR_RET_CODE_DOESNT_SUPPORT_NON_MANDATORY_FXN;
597 }
598
599 /* Function exists in the interface of the socket descriptor, dispatch
600 the Bind command */
601 retVal = (netIf->ifConf)->sockBind(realSd, sdContext, addr, addrlen);
602 SLNETSOCK_NORMALIZE_RET_VAL(retVal,SLNETSOCK_ERR_SOCKBIND_FAILED);
603
604 return retVal;
605 }
606
607
608 //*****************************************************************************
609 //
610 // SlNetSock_listen - Listen for connections on a socket
611 //
612 //*****************************************************************************
SlNetSock_listen(int16_t sd,int16_t backlog)613 int32_t SlNetSock_listen(int16_t sd, int16_t backlog)
614 {
615 int32_t retVal = SLNETERR_RET_CODE_OK;
616 int16_t realSd;
617 SlNetIf_t *netIf;
618 void *sdContext;
619
620 /* Check if the sd input exists and return it */
621 retVal = SlNetSock_getVirtualSdConf(sd, &realSd, NULL, &sdContext, &netIf);
622
623 /* Check if sd found or if the non mandatory function exists */
624 if (SLNETERR_RET_CODE_OK != retVal)
625 {
626 return retVal;
627 }
628 if (NULL == (netIf->ifConf)->sockListen)
629 {
630 /* Non mandatory function doesn't exists, return error code */
631 return SLNETERR_RET_CODE_DOESNT_SUPPORT_NON_MANDATORY_FXN;
632 }
633
634 /* Function exists in the interface of the socket descriptor, dispatch
635 the Listen command */
636 retVal = (netIf->ifConf)->sockListen(realSd, sdContext, backlog);
637 SLNETSOCK_NORMALIZE_RET_VAL(retVal,SLNETSOCK_ERR_SOCKLISTEN_FAILED);
638
639 return retVal;
640 }
641
642
643 //*****************************************************************************
644 //
645 // SlNetSock_connect - Initiate a connection on a socket
646 //
647 //*****************************************************************************
SlNetSock_connect(int16_t sd,const SlNetSock_Addr_t * addr,SlNetSocklen_t addrlen)648 int32_t SlNetSock_connect(int16_t sd, const SlNetSock_Addr_t *addr, SlNetSocklen_t addrlen)
649 {
650 int32_t retVal = SLNETERR_RET_CODE_OK;
651 int16_t realSd;
652 uint8_t sdFlags;
653 SlNetIf_t *netIf;
654 void *sdContext;
655
656 /* Check if the sd input exists and return it */
657 retVal = SlNetSock_getVirtualSdConf(sd, &realSd, &sdFlags, &sdContext, &netIf);
658
659 /* Check if sd found or if the non mandatory function exists */
660 if (SLNETERR_RET_CODE_OK != retVal)
661 {
662 return retVal;
663 }
664 if (NULL == (netIf->ifConf)->sockConnect)
665 {
666 /* Non mandatory function doesn't exists, return error code */
667 return SLNETERR_RET_CODE_DOESNT_SUPPORT_NON_MANDATORY_FXN;
668 }
669
670 /* Function exists in the interface of the socket descriptor, dispatch
671 the Connect command */
672 retVal = (netIf->ifConf)->sockConnect(realSd, sdContext, addr, addrlen, sdFlags);
673 SLNETSOCK_NORMALIZE_RET_VAL(retVal,SLNETSOCK_ERR_SOCKCONNECT_FAILED);
674
675 return retVal;
676 }
677
678
679 //*****************************************************************************
680 //
681 // SlNetSock_connectUrl - Initiate a connection on a socket by URL
682 //
683 //*****************************************************************************
SlNetSock_connectUrl(int16_t sd,const char * url)684 int32_t SlNetSock_connectUrl(int16_t sd, const char *url)
685 {
686 uint32_t addr[4];
687 uint16_t ipAddrLen;
688 SlNetSock_AddrIn_t localAddr; //address of the server to connect to
689 SlNetSocklen_t localAddrSize;
690 int16_t realSd;
691 uint8_t sdFlags;
692 SlNetIf_t *netIf;
693 void *sdContext;
694 int32_t retVal = SLNETERR_RET_CODE_OK;
695
696 /* Check if the sd input exists and return it */
697 retVal = SlNetSock_getVirtualSdConf(sd, &realSd, &sdFlags, &sdContext, &netIf);
698
699 /* Check if sd found or if the non mandatory function exists */
700 if (SLNETERR_RET_CODE_OK != retVal)
701 {
702 return retVal;
703 }
704 if ( (NULL == (netIf->ifConf)->sockConnect) || (NULL == (netIf->ifConf)->utilGetHostByName) )
705 {
706 /* Non mandatory function doesn't exists, return error code */
707 return SLNETERR_RET_CODE_DOESNT_SUPPORT_NON_MANDATORY_FXN;
708 }
709
710 /* Query DNS for IPv4 address. */
711 retVal = (netIf->ifConf)->utilGetHostByName(netIf->ifContext, (char *)url, strlen(url), addr, &ipAddrLen, SLNETSOCK_AF_INET);
712 SLNETSOCK_NORMALIZE_RET_VAL(retVal,SLNETUTIL_ERR_UTILGETHOSTBYNAME_FAILED);
713 if(retVal < 0)
714 {
715 /* If call fails, try again for IPv6. */
716 retVal = (netIf->ifConf)->utilGetHostByName(netIf->ifContext, (char *)url, strlen(url), addr, &ipAddrLen, SLNETSOCK_AF_INET6);
717 SLNETSOCK_NORMALIZE_RET_VAL(retVal,SLNETUTIL_ERR_UTILGETHOSTBYNAME_FAILED);
718 if(retVal < 0)
719 {
720 /* if the request failed twice, return error code. */
721 return retVal;
722 }
723 else
724 {
725 /* fill the answer fields with IPv6 parameters */
726 localAddr.sin_family = SLNETSOCK_AF_INET6;
727 localAddrSize = sizeof(SlNetSock_AddrIn6_t);
728 }
729 }
730 else
731 {
732 /* fill the answer fields with IPv4 parameters */
733 localAddr.sin_family = SLNETSOCK_AF_INET;
734 localAddrSize = sizeof(SlNetSock_AddrIn_t);
735
736 /* convert the IPv4 address from host byte order to network byte
737 order */
738 localAddr.sin_addr.s_addr = SlNetUtil_htonl(addr[0]);
739 }
740
741
742 /* Function exists in the interface of the socket descriptor, dispatch
743 the Connect command */
744 retVal = (netIf->ifConf)->sockConnect(realSd, sdContext, (const SlNetSock_Addr_t *)&localAddr, localAddrSize, sdFlags);
745 SLNETSOCK_NORMALIZE_RET_VAL(retVal,SLNETSOCK_ERR_SOCKCONNECT_FAILED);
746
747 return retVal;
748 }
749
750
751 //*****************************************************************************
752 //
753 // SlNetSock_getPeerName - Return address info about the remote side of the
754 // connection
755 //
756 //*****************************************************************************
SlNetSock_getPeerName(int16_t sd,SlNetSock_Addr_t * addr,SlNetSocklen_t * addrlen)757 int32_t SlNetSock_getPeerName(int16_t sd, SlNetSock_Addr_t *addr, SlNetSocklen_t *addrlen)
758 {
759 int32_t retVal = SLNETERR_RET_CODE_OK;
760 int16_t realSd;
761 SlNetIf_t *netIf;
762 void *sdContext;
763
764 /* Check if the sd input exists and return it */
765 retVal = SlNetSock_getVirtualSdConf(sd, &realSd, NULL, &sdContext, &netIf);
766
767 /* Check if sd found or if the non mandatory function exists */
768 if (SLNETERR_RET_CODE_OK != retVal)
769 {
770 return retVal;
771 }
772 if (NULL == (netIf->ifConf)->sockGetPeerName)
773 {
774 /* Non mandatory function doesn't exists, return error code */
775 return SLNETERR_RET_CODE_DOESNT_SUPPORT_NON_MANDATORY_FXN;
776 }
777
778 /* Function exists in the interface of the socket descriptor, dispatch
779 the GetPeerName command */
780 retVal = (netIf->ifConf)->sockGetPeerName(realSd, sdContext, addr, addrlen);
781 SLNETSOCK_NORMALIZE_RET_VAL(retVal,SLNETSOCK_ERR_SOCKGETPEERNAME_FAILED);
782
783 return retVal;
784 }
785
786
787 //*****************************************************************************
788 //
789 // SlNetSock_getSockName - Returns the local address info of the socket
790 // descriptor
791 //
792 //*****************************************************************************
SlNetSock_getSockName(int16_t sd,SlNetSock_Addr_t * addr,SlNetSocklen_t * addrlen)793 int32_t SlNetSock_getSockName(int16_t sd, SlNetSock_Addr_t *addr, SlNetSocklen_t *addrlen)
794 {
795 int32_t retVal = SLNETERR_RET_CODE_OK;
796 int16_t realSd;
797 SlNetIf_t *netIf;
798 void *sdContext;
799
800 /* Check if the sd input exists and return it */
801 retVal = SlNetSock_getVirtualSdConf(sd, &realSd, NULL, &sdContext, &netIf);
802
803 /* Check if sd found or if the non mandatory function exists */
804 if (SLNETERR_RET_CODE_OK != retVal)
805 {
806 return retVal;
807 }
808 if (NULL == (netIf->ifConf)->sockGetLocalName)
809 {
810 /* Non mandatory function doesn't exists, return error code */
811 return SLNETERR_RET_CODE_DOESNT_SUPPORT_NON_MANDATORY_FXN;
812 }
813
814 /* Function exists in the interface of the socket descriptor, dispatch
815 the GetLocalName command */
816 retVal = (netIf->ifConf)->sockGetLocalName(realSd, sdContext, addr, addrlen);
817 SLNETSOCK_NORMALIZE_RET_VAL(retVal,SLNETSOCK_ERR_SOCKGETLOCALNAME_FAILED);
818
819 return retVal;
820 }
821
822
823 //*****************************************************************************
824 //
825 // SlNetSock_select - Monitor socket activity
826 //
827 //*****************************************************************************
SlNetSock_select(int16_t nsds,SlNetSock_SdSet_t * readsds,SlNetSock_SdSet_t * writesds,SlNetSock_SdSet_t * exceptsds,SlNetSock_Timeval_t * timeout)828 int32_t SlNetSock_select(int16_t nsds, SlNetSock_SdSet_t *readsds, SlNetSock_SdSet_t *writesds, SlNetSock_SdSet_t *exceptsds, SlNetSock_Timeval_t *timeout)
829 {
830 int32_t retVal = SLNETERR_RET_CODE_OK;
831 int32_t sdIndex = 0;
832 int16_t realSd;
833 int16_t ifNsds = 0;
834 bool skipToNext = true;
835 SlNetIf_t *firstIfID = NULL;
836 SlNetIf_t *netIf;
837 void *sdContext;
838 SlNetSock_SdSet_t ifReadsds;
839 SlNetSock_SdSet_t ifWritesds;
840 SlNetSock_SdSet_t ifExceptsds;
841 SlNetSock_RealToVirtualIndexes_t *tempNode = NULL;
842 SlNetSock_RealToVirtualIndexes_t *realSdToVirtual = NULL;
843
844 /* Initialize sds parameters */
845 SlNetSock_sdsClrAll(&ifReadsds);
846 SlNetSock_sdsClrAll(&ifWritesds);
847 SlNetSock_sdsClrAll(&ifExceptsds);
848
849 /* Run over all possible sd indexes */
850 while ( sdIndex < nsds )
851 {
852 /* get interface ID from the socket identifier */
853 retVal = SlNetSock_getVirtualSdConf(sdIndex, &realSd, NULL, &sdContext, &netIf);
854
855 /* Check if sd found */
856 if (SLNETERR_RET_CODE_OK == retVal)
857 {
858 /* Check if sdIndex is set in read/write/except virtual sd sets,
859 if so, set the real sd set and set skipToNext to false
860 for further use */
861 if (SlNetSock_sdsIsSet(sdIndex, readsds) == 1)
862 {
863 SlNetSock_sdsSet(realSd, &ifReadsds);
864 skipToNext = false;
865 }
866 if (SlNetSock_sdsIsSet(sdIndex, writesds) == 1)
867 {
868 SlNetSock_sdsSet(realSd, &ifWritesds);
869 skipToNext = false;
870 }
871 if (SlNetSock_sdsIsSet(sdIndex, exceptsds) == 1)
872 {
873 SlNetSock_sdsSet(realSd, &ifExceptsds);
874 skipToNext = false;
875 }
876
877 if (false == skipToNext)
878 {
879
880 /* Create a node which stores the relation between the virtual
881 sd index and the real sd index and connect it to the list */
882 tempNode = (SlNetSock_RealToVirtualIndexes_t *)malloc(sizeof(SlNetSock_RealToVirtualIndexes_t));
883
884 /* Check if the malloc function failed */
885 if (NULL == tempNode)
886 {
887 firstIfID = NULL;
888 retVal = SLNETERR_RET_CODE_MALLOC_ERROR;
889 break;
890 }
891
892 tempNode->realSd = realSd;
893 tempNode->virtualSd = sdIndex;
894 tempNode->next = realSdToVirtual;
895 realSdToVirtual = tempNode;
896
897 /* Check if the stored interface ID is different from the
898 interface ID of the socket */
899 if (netIf != firstIfID)
900 {
901 /* Check if the stored interface ID is still initialized */
902 if (NULL == firstIfID)
903 {
904 /* Store the interface ID */
905 firstIfID = netIf;
906 }
907 else
908 {
909 /* Different interface ID from the stored interface
910 ID, that means more than one interface supplied
911 in the read sd set */
912 firstIfID = NULL;
913 break;
914 }
915 }
916 if (ifNsds <= realSd)
917 {
918 ifNsds = realSd + 1;
919 }
920 skipToNext = true;
921 }
922 }
923
924 /* Continue to next sd index */
925 sdIndex++;
926 }
927
928 /* Check if non mandatory function exists */
929 if ( (NULL != firstIfID) && (NULL != (firstIfID->ifConf)->sockSelect) )
930 {
931 /* Function exists in the interface of the socket descriptor,
932 dispatch the Select command */
933 retVal = (firstIfID->ifConf)->sockSelect(firstIfID->ifContext, ifNsds, &ifReadsds, &ifWritesds, &ifExceptsds, timeout);
934 SLNETSOCK_NORMALIZE_RET_VAL(retVal,SLNETSOCK_ERR_SOCKSELECT_FAILED);
935
936 /* Clear all virtual sd sets before setting the sockets that are set */
937 SlNetSock_sdsClrAll(readsds);
938 SlNetSock_sdsClrAll(writesds);
939 SlNetSock_sdsClrAll(exceptsds);
940
941 /* check if the sockselect returned positive value, this value
942 represents how many socket descriptors are set */
943 if (retVal > 0)
944 {
945 /* Run over all the socket descriptors in the list and check if
946 the sockSelect function set them, if so, set the virtual
947 socket descriptors sets */
948 tempNode = realSdToVirtual;
949 while ( NULL != tempNode )
950 {
951 if (SlNetSock_sdsIsSet(tempNode->realSd, &ifReadsds) == 1)
952 {
953 SlNetSock_sdsSet(tempNode->virtualSd, readsds);
954 }
955 if (SlNetSock_sdsIsSet(tempNode->realSd, &ifWritesds) == 1)
956 {
957 SlNetSock_sdsSet(tempNode->virtualSd, writesds);
958 }
959 if (SlNetSock_sdsIsSet(tempNode->realSd, &ifExceptsds) == 1)
960 {
961 SlNetSock_sdsSet(tempNode->virtualSd, exceptsds);
962 }
963 tempNode = tempNode->next;
964 }
965 }
966 }
967 else
968 {
969 if ( SLNETERR_RET_CODE_MALLOC_ERROR != retVal )
970 {
971 /* Validation failed, return error code */
972 retVal = SLNETERR_RET_CODE_INVALID_INPUT;
973 }
974 }
975
976 /* List isn't needed anymore, free it from the head of the list */
977 while (NULL != realSdToVirtual)
978 {
979 tempNode = realSdToVirtual->next;
980 free(realSdToVirtual);
981 realSdToVirtual = tempNode;
982 }
983
984 return retVal;
985 }
986
987
988 //*****************************************************************************
989 //
990 // SlNetSock_sdsSet - SlNetSock_select's SlNetSock_SdSet_t SET function
991 //
992 //*****************************************************************************
SlNetSock_sdsSet(int16_t sd,SlNetSock_SdSet_t * sdset)993 int32_t SlNetSock_sdsSet(int16_t sd, SlNetSock_SdSet_t *sdset)
994 {
995 int sdArrayIndex;
996
997 /* Validation check */
998 if ( (NULL == sdset) || (sd >= SLNETSOCK_MAX_CONCURRENT_SOCKETS) )
999 {
1000 /* Validation failed, return error code */
1001 return SLNETERR_RET_CODE_INVALID_INPUT;
1002 }
1003
1004 /* Check in which sdset index the input socket exists */
1005 sdArrayIndex = (sd / SLNETSOCK_SIZEOF_ONE_SDSETBITMAP_SLOT_IN_BITS);
1006
1007 /* Set the socket in the sd set */
1008 sdset->sdSetBitmap[sdArrayIndex] |= ( 1 << (sd % SLNETSOCK_SIZEOF_ONE_SDSETBITMAP_SLOT_IN_BITS) );
1009
1010 return SLNETERR_RET_CODE_OK;
1011
1012 }
1013
1014
1015 //*****************************************************************************
1016 //
1017 // SlNetSock_sdsClr - SlNetSock_select's SlNetSock_SdSet_t CLR function
1018 //
1019 //*****************************************************************************
SlNetSock_sdsClr(int16_t sd,SlNetSock_SdSet_t * sdset)1020 int32_t SlNetSock_sdsClr(int16_t sd, SlNetSock_SdSet_t *sdset)
1021 {
1022 int sdArrayIndex;
1023
1024 /* Validation check */
1025 if ( (NULL == sdset) || (sd >= SLNETSOCK_MAX_CONCURRENT_SOCKETS) )
1026 {
1027 /* Validation failed, return error code */
1028 return SLNETERR_RET_CODE_INVALID_INPUT;
1029 }
1030 /* Check in which sdset index the input socket exists */
1031 sdArrayIndex = (sd / SLNETSOCK_SIZEOF_ONE_SDSETBITMAP_SLOT_IN_BITS);
1032
1033 /* Set the socket in the sd set */
1034 sdset->sdSetBitmap[sdArrayIndex] &= ~( 1 << (sd % SLNETSOCK_SIZEOF_ONE_SDSETBITMAP_SLOT_IN_BITS) );
1035
1036 return SLNETERR_RET_CODE_OK;
1037 }
1038
1039
1040 //*****************************************************************************
1041 //
1042 // SlNetSock_sdsClrAll - SlNetSock_select's SlNetSock_SdSet_t ZERO function
1043 //
1044 //*****************************************************************************
SlNetSock_sdsClrAll(SlNetSock_SdSet_t * sdset)1045 int32_t SlNetSock_sdsClrAll(SlNetSock_SdSet_t *sdset)
1046 {
1047 int sdArrayIndex;
1048
1049 /* Validation check */
1050 if (NULL == sdset)
1051 {
1052 /* Validation failed, return error code */
1053 return SLNETERR_RET_CODE_INVALID_INPUT;
1054 }
1055
1056 /* Check the size of the sdArrayIndex */
1057 sdArrayIndex = (((sizeof(sdset)*8)-1) / SLNETSOCK_SIZEOF_ONE_SDSETBITMAP_SLOT_IN_BITS);
1058
1059 while (sdArrayIndex >= 0)
1060 {
1061 /* Set to 0 the sd set */
1062 sdset->sdSetBitmap[sdArrayIndex] = 0;
1063 sdArrayIndex --;
1064 }
1065
1066 return SLNETERR_RET_CODE_OK;
1067 }
1068
1069
1070
1071 //*****************************************************************************
1072 //
1073 // SlNetSock_sdsIsSet - SlNetSock_select's SlNetSock_SdSet_t ISSET function
1074 //
1075 //*****************************************************************************
SlNetSock_sdsIsSet(int16_t sd,SlNetSock_SdSet_t * sdset)1076 int32_t SlNetSock_sdsIsSet(int16_t sd, SlNetSock_SdSet_t *sdset)
1077 {
1078 int sdArrayIndex;
1079
1080 /* Validation check */
1081 if ( (NULL == sdset) || (sd >= SLNETSOCK_MAX_CONCURRENT_SOCKETS) )
1082 {
1083 /* Validation failed, return error code */
1084 return SLNETERR_RET_CODE_INVALID_INPUT;
1085 }
1086
1087 /* Check in which sdset index the input socket exists */
1088 sdArrayIndex = (sd / SLNETSOCK_SIZEOF_ONE_SDSETBITMAP_SLOT_IN_BITS);
1089
1090 /* Check if the sd is set in the sdSetBitmap */
1091 if ( (sdset->sdSetBitmap[sdArrayIndex]) & (1 << (sd % SLNETSOCK_SIZEOF_ONE_SDSETBITMAP_SLOT_IN_BITS)) )
1092 {
1093 /* Bit is set, return 1 */
1094 return 1;
1095 }
1096 else
1097 {
1098 /* Bit is not set, return 0 */
1099 return 0;
1100 }
1101 }
1102
1103
1104 //*****************************************************************************
1105 //
1106 // SlNetSock_setOpt - Set socket options
1107 //
1108 //*****************************************************************************
SlNetSock_setOpt(int16_t sd,int16_t level,int16_t optname,void * optval,SlNetSocklen_t optlen)1109 int32_t SlNetSock_setOpt(int16_t sd, int16_t level, int16_t optname, void *optval, SlNetSocklen_t optlen)
1110 {
1111 int32_t retVal = SLNETERR_RET_CODE_OK;
1112 int16_t realSd;
1113 SlNetIf_t *netIf;
1114 void *sdContext;
1115
1116 /* Check if the sd input exists and return it */
1117 retVal = SlNetSock_getVirtualSdConf(sd, &realSd, NULL, &sdContext, &netIf);
1118
1119 /* Check if sd found or if the non mandatory function exists */
1120 if (SLNETERR_RET_CODE_OK != retVal)
1121 {
1122 return retVal;
1123 }
1124 if (NULL == (netIf->ifConf)->sockSetOpt)
1125 {
1126 /* Non mandatory function doesn't exists, return error code */
1127 return SLNETERR_RET_CODE_DOESNT_SUPPORT_NON_MANDATORY_FXN;
1128 }
1129
1130 /* Function exists in the interface of the socket descriptor, dispatch
1131 the SetOpt command */
1132 retVal = (netIf->ifConf)->sockSetOpt(realSd, sdContext, level, optname, optval, optlen);
1133 SLNETSOCK_NORMALIZE_RET_VAL(retVal,SLNETSOCK_ERR_SOCKSETOPT_FAILED);
1134
1135 return retVal;
1136 }
1137
1138
1139 //*****************************************************************************
1140 //
1141 // SlNetSock_getOpt - Get socket options
1142 //
1143 //*****************************************************************************
SlNetSock_getOpt(int16_t sd,int16_t level,int16_t optname,void * optval,SlNetSocklen_t * optlen)1144 int32_t SlNetSock_getOpt(int16_t sd, int16_t level, int16_t optname, void *optval, SlNetSocklen_t *optlen)
1145 {
1146 int32_t retVal = SLNETERR_RET_CODE_OK;
1147 int16_t realSd;
1148 SlNetIf_t *netIf;
1149 void *sdContext;
1150
1151 /* Check if the sd input exists and return it */
1152 retVal = SlNetSock_getVirtualSdConf(sd, &realSd, NULL, &sdContext, &netIf);
1153
1154 /* Check if sd found or if the non mandatory function exists */
1155 if (SLNETERR_RET_CODE_OK != retVal)
1156 {
1157 return retVal;
1158 }
1159 if (NULL == (netIf->ifConf)->sockGetOpt)
1160 {
1161 /* Non mandatory function doesn't exists, return error code */
1162 return SLNETERR_RET_CODE_DOESNT_SUPPORT_NON_MANDATORY_FXN;
1163 }
1164
1165 /* Function exists in the interface of the socket descriptor, dispatch
1166 the GetOpt command */
1167 retVal = (netIf->ifConf)->sockGetOpt(realSd, sdContext, level, optname, optval, optlen);
1168 SLNETSOCK_NORMALIZE_RET_VAL(retVal,SLNETSOCK_ERR_SOCKGETOPT_FAILED);
1169
1170 return retVal;
1171 }
1172
1173
1174 //*****************************************************************************
1175 //
1176 // SlNetSock_recv - Read data from TCP socket
1177 //
1178 //*****************************************************************************
SlNetSock_recv(int16_t sd,void * buf,uint32_t len,uint32_t flags)1179 int32_t SlNetSock_recv(int16_t sd, void *buf, uint32_t len, uint32_t flags)
1180 {
1181 int32_t retVal = SLNETERR_RET_CODE_OK;
1182 int16_t realSd;
1183 uint8_t sdFlags;
1184 SlNetIf_t *netIf;
1185 void *sdContext;
1186
1187 /* Check if the sd input exists and return it */
1188 retVal = SlNetSock_getVirtualSdConf(sd, &realSd, &sdFlags, &sdContext, &netIf);
1189
1190 /* Check if sd found or if the non mandatory function exists */
1191 if (SLNETERR_RET_CODE_OK != retVal)
1192 {
1193 return retVal;
1194 }
1195 if (NULL == (netIf->ifConf)->sockRecv)
1196 {
1197 /* Non mandatory function doesn't exists, return error code */
1198 return SLNETERR_RET_CODE_DOESNT_SUPPORT_NON_MANDATORY_FXN;
1199 }
1200 if ((flags & 0xff000000) != 0)
1201 {
1202 /* invalid user flags */
1203 return SLNETERR_BSD_EOPNOTSUPP;
1204 }
1205
1206 /* Macro which merge the 8bit security flags to the upper bits of the
1207 32bit input flags */
1208 MERGE_SEC_INTO_INPUT_FLAGS(flags, sdFlags);
1209
1210 /* Function exists in the interface of the socket descriptor, dispatch
1211 the Recv command */
1212 retVal = (netIf->ifConf)->sockRecv(realSd, sdContext, buf, len, flags);
1213 SLNETSOCK_NORMALIZE_RET_VAL(retVal,SLNETSOCK_ERR_SOCKRECV_FAILED);
1214
1215 return retVal;
1216 }
1217
1218
1219 //*****************************************************************************
1220 //
1221 // SlNetSock_recvFrom - Read data from socket
1222 //
1223 //*****************************************************************************
SlNetSock_recvFrom(int16_t sd,void * buf,uint32_t len,uint32_t flags,SlNetSock_Addr_t * from,SlNetSocklen_t * fromlen)1224 int32_t SlNetSock_recvFrom(int16_t sd, void *buf, uint32_t len, uint32_t flags, SlNetSock_Addr_t *from, SlNetSocklen_t *fromlen)
1225 {
1226 int32_t retVal = SLNETERR_RET_CODE_OK;
1227 int16_t realSd;
1228 uint8_t sdFlags;
1229 SlNetIf_t *netIf;
1230 void *sdContext;
1231
1232 /* Check if the sd input exists and return it */
1233 retVal = SlNetSock_getVirtualSdConf(sd, &realSd, &sdFlags, &sdContext, &netIf);
1234
1235 /* Check if sd found */
1236 if (SLNETERR_RET_CODE_OK != retVal)
1237 {
1238 /* Validation failed, return error code */
1239 return SLNETERR_RET_CODE_INVALID_INPUT;
1240 }
1241 if ((flags & 0xff000000) != 0)
1242 {
1243 /* invalid user flags */
1244 return SLNETERR_BSD_EOPNOTSUPP;
1245 }
1246
1247 /* Macro which merge the 8bit security flags to the upper bits of the
1248 32bit input flags */
1249 MERGE_SEC_INTO_INPUT_FLAGS(flags, sdFlags);
1250
1251 /* Function exists in the interface of the socket descriptor, dispatch
1252 the RecvFrom command */
1253 retVal = (netIf->ifConf)->sockRecvFrom(realSd, sdContext, buf, len, flags, from, fromlen);
1254 SLNETSOCK_NORMALIZE_RET_VAL(retVal,SLNETSOCK_ERR_SOCKRECVFROM_FAILED);
1255
1256 return retVal;
1257 }
1258
1259
1260 //*****************************************************************************
1261 //
1262 // SlNetSock_send - Write data to TCP socket
1263 //
1264 //*****************************************************************************
SlNetSock_send(int16_t sd,const void * buf,uint32_t len,uint32_t flags)1265 int32_t SlNetSock_send(int16_t sd, const void *buf, uint32_t len, uint32_t flags)
1266 {
1267 int32_t retVal = SLNETERR_RET_CODE_OK;
1268 int16_t realSd;
1269 uint8_t sdFlags;
1270 SlNetIf_t *netIf;
1271 void *sdContext;
1272
1273 /* Check if the sd input exists and return it */
1274 retVal = SlNetSock_getVirtualSdConf(sd, &realSd, &sdFlags, &sdContext, &netIf);
1275
1276 /* Check if sd found or if the non mandatory function exists */
1277 if (SLNETERR_RET_CODE_OK != retVal)
1278 {
1279 return retVal;
1280 }
1281 if (NULL == (netIf->ifConf)->sockSend)
1282 {
1283 /* Non mandatory function doesn't exists, return error code */
1284 return SLNETERR_RET_CODE_DOESNT_SUPPORT_NON_MANDATORY_FXN;
1285 }
1286 if ((flags & 0xff000000) != 0)
1287 {
1288 /* invalid user flags */
1289 return SLNETERR_BSD_EOPNOTSUPP;
1290 }
1291
1292 /* Macro which merge the 8bit security flags to the upper bits of the
1293 32bit input flags */
1294 MERGE_SEC_INTO_INPUT_FLAGS(flags, sdFlags);
1295
1296 /* Function exists in the interface of the socket descriptor, dispatch
1297 the Send command */
1298 retVal = (netIf->ifConf)->sockSend(realSd, sdContext, buf, len, flags);
1299 SLNETSOCK_NORMALIZE_RET_VAL(retVal,SLNETSOCK_ERR_SOCKSEND_FAILED);
1300
1301 return retVal;
1302 }
1303
1304
1305 //*****************************************************************************
1306 //
1307 // SlNetSock_sendTo - Write data to socket
1308 //
1309 //*****************************************************************************
SlNetSock_sendTo(int16_t sd,const void * buf,uint32_t len,uint32_t flags,const SlNetSock_Addr_t * to,SlNetSocklen_t tolen)1310 int32_t SlNetSock_sendTo(int16_t sd, const void *buf, uint32_t len, uint32_t flags, const SlNetSock_Addr_t *to, SlNetSocklen_t tolen)
1311 {
1312 int32_t retVal = SLNETERR_RET_CODE_OK;
1313 int16_t realSd;
1314 uint8_t sdFlags;
1315 SlNetIf_t *netIf;
1316 void *sdContext;
1317
1318 /* Check if the sd input exists and return it */
1319 retVal = SlNetSock_getVirtualSdConf(sd, &realSd, &sdFlags, &sdContext, &netIf);
1320
1321 /* Check if sd found */
1322 if (SLNETERR_RET_CODE_OK != retVal)
1323 {
1324 /* Validation failed, return error code */
1325 return SLNETERR_RET_CODE_INVALID_INPUT;
1326 }
1327 if ((flags & 0xff000000) != 0)
1328 {
1329 /* invalid user flags */
1330 return SLNETERR_BSD_EOPNOTSUPP;
1331 }
1332
1333 /* Macro which merge the 8bit security flags to the upper bits of the
1334 32bit input flags */
1335 MERGE_SEC_INTO_INPUT_FLAGS(flags, sdFlags);
1336
1337 /* Function exists in the interface of the socket descriptor, dispatch
1338 the SendTo command */
1339 retVal = (netIf->ifConf)->sockSendTo(realSd, sdContext, buf, len, flags, to, tolen);
1340 SLNETSOCK_NORMALIZE_RET_VAL(retVal,SLNETSOCK_ERR_SOCKSENDTO_FAILED);
1341
1342 return retVal;
1343 }
1344
1345
1346 //*****************************************************************************
1347 //
1348 // SlNetSock_getIfID - Get interface ID from socket descriptor (sd)
1349 //
1350 //*****************************************************************************
SlNetSock_getIfID(uint16_t sd)1351 int32_t SlNetSock_getIfID(uint16_t sd)
1352 {
1353 int32_t retVal = SLNETERR_RET_CODE_OK;
1354 int16_t realSd;
1355 SlNetIf_t *netIf;
1356
1357 /* Check if the sd input exists and return it */
1358 retVal = SlNetSock_getVirtualSdConf(sd, &realSd, NULL, NULL, &netIf);
1359
1360 /* Check if sd found */
1361 if (SLNETERR_RET_CODE_OK != retVal)
1362 {
1363 /* Validation failed, return error code */
1364 return SLNETERR_RET_CODE_INVALID_INPUT;
1365 }
1366
1367 /* Return interface identifier */
1368 return netIf->ifID;
1369 }
1370
1371
1372 //*****************************************************************************
1373 //
1374 // SlNetSock_secAttribCreate - Creates a security attributes object
1375 //
1376 //*****************************************************************************
SlNetSock_secAttribCreate(void)1377 SlNetSockSecAttrib_t *SlNetSock_secAttribCreate(void)
1378 {
1379 SlNetSockSecAttrib_t *secAttribHandler;
1380
1381 /* Allocate and initialize dynamic memory for security attribute handler */
1382 secAttribHandler = (SlNetSockSecAttrib_t *)calloc(1, sizeof(SlNetSockSecAttrib_t));
1383
1384 /* Check if the calloc function failed */
1385 if (NULL == secAttribHandler)
1386 {
1387 /* Function failed, return error code */
1388 return NULL;
1389 }
1390
1391 return (secAttribHandler);
1392 }
1393
1394
1395 //*****************************************************************************
1396 //
1397 // SlNetSock_secAttribDelete - Deletes a security attributes object
1398 //
1399 //*****************************************************************************
SlNetSock_secAttribDelete(SlNetSockSecAttrib_t * secAttrib)1400 int32_t SlNetSock_secAttribDelete(SlNetSockSecAttrib_t *secAttrib)
1401 {
1402 SlNetSock_SecAttribNode_t *nextSecAttrib;
1403 SlNetSock_SecAttribNode_t *tempSecAttrib;
1404
1405 /* Check if the input doesn't exist */
1406 if (NULL == secAttrib)
1407 {
1408 /* Function failed, return error code */
1409 return SLNETERR_RET_CODE_INVALID_INPUT;
1410 }
1411 else
1412 {
1413 nextSecAttrib = (SlNetSock_SecAttribNode_t *)*secAttrib;
1414 tempSecAttrib = (SlNetSock_SecAttribNode_t *)*secAttrib;
1415 }
1416
1417 /* Free all SecAttrib list nodes */
1418 while (NULL != nextSecAttrib)
1419 {
1420 nextSecAttrib = tempSecAttrib->next;
1421 free((void *)tempSecAttrib);
1422 tempSecAttrib = nextSecAttrib;
1423 }
1424
1425 free(secAttrib);
1426
1427 return SLNETERR_RET_CODE_OK;
1428 }
1429
1430
1431 //*****************************************************************************
1432 //
1433 // SlNetSock_secAttribSet - used to set a security attribute of a security
1434 // attributes object
1435 //
1436 //*****************************************************************************
SlNetSock_secAttribSet(SlNetSockSecAttrib_t * secAttrib,SlNetSockSecAttrib_e attribName,void * val,uint16_t len)1437 int32_t SlNetSock_secAttribSet(SlNetSockSecAttrib_t *secAttrib, SlNetSockSecAttrib_e attribName, void *val, uint16_t len)
1438 {
1439 SlNetSock_SecAttribNode_t *secAttribObj;
1440
1441 /* Check if the inputs doesn't exists or not valid */
1442 if ( (NULL == secAttrib) || (0 == len) || (NULL == val) )
1443 {
1444 /* Function failed, return error code */
1445 return SLNETERR_RET_CODE_INVALID_INPUT;
1446 }
1447
1448 /* Ensure the len was set correctly for the given attribName */
1449 switch (attribName)
1450 {
1451 case SLNETSOCK_SEC_ATTRIB_PRIVATE_KEY:
1452 case SLNETSOCK_SEC_ATTRIB_LOCAL_CERT:
1453 case SLNETSOCK_SEC_ATTRIB_PEER_ROOT_CA:
1454 case SLNETSOCK_SEC_ATTRIB_DH_KEY:
1455 case SLNETSOCK_SEC_ATTRIB_DOMAIN_NAME:
1456 if((strlen((char *)val) + 1) != len)
1457 {
1458 return SLNETERR_RET_CODE_INVALID_INPUT;
1459 }
1460 break;
1461 case SLNETSOCK_SEC_ATTRIB_CIPHERS:
1462 case SLNETSOCK_SEC_ATTRIB_ALPN:
1463 case SLNETSOCK_SEC_ATTRIB_DISABLE_CERT_STORE:
1464 if(sizeof(uint32_t) != len)
1465 {
1466 return SLNETERR_RET_CODE_INVALID_INPUT;
1467 }
1468 break;
1469 case SLNETSOCK_SEC_ATTRIB_METHOD:
1470 if(sizeof(uint8_t) != len)
1471 {
1472 return SLNETERR_RET_CODE_INVALID_INPUT;
1473 }
1474 break;
1475 case SLNETSOCK_SEC_ATTRIB_EXT_CLIENT_CHLNG_RESP:
1476 /* Format for this attrib is TBD */
1477 break;
1478 default:
1479 /* Reject attribNames we don't recognize */
1480 return SLNETERR_RET_CODE_INVALID_INPUT;
1481 }
1482
1483 /* Allocate dynamic memory for security attribute handler */
1484 secAttribObj = (SlNetSock_SecAttribNode_t *)malloc(sizeof(SlNetSock_SecAttribNode_t));
1485
1486 /* Check if the malloc function failed */
1487 if (NULL == secAttribObj)
1488 {
1489 /* Function failed, return error code */
1490 return SLNETERR_RET_CODE_MALLOC_ERROR;
1491 }
1492
1493 /* Set the inputs in the allocated security attribute handler */
1494 secAttribObj->attribName = attribName;
1495 secAttribObj->attribBuff = val;
1496 secAttribObj->attribBuffLen = len;
1497 secAttribObj->next = *secAttrib;
1498
1499 /* Connect the security attribute to the secAttrib list */
1500 *secAttrib = secAttribObj;
1501
1502
1503
1504 return SLNETERR_RET_CODE_OK;
1505 }
1506
1507
1508 //*****************************************************************************
1509 //
1510 // SlNetSock_startSec - Start a security session on an opened socket
1511 //
1512 //*****************************************************************************
SlNetSock_startSec(int16_t sd,SlNetSockSecAttrib_t * secAttrib,uint8_t flags)1513 int32_t SlNetSock_startSec(int16_t sd, SlNetSockSecAttrib_t *secAttrib, uint8_t flags)
1514 {
1515 int32_t retVal = SLNETERR_RET_CODE_OK;
1516 int16_t realSd;
1517 uint8_t sdFlags;
1518 SlNetIf_t *netIf;
1519 void *sdContext;
1520
1521 /* Check if the sd input exists and return it */
1522 retVal = SlNetSock_getVirtualSdConf(sd, &realSd, &sdFlags, &sdContext, &netIf);
1523
1524 /* Check if sd found or if the non mandatory function exists */
1525 if (SLNETERR_RET_CODE_OK != retVal)
1526 {
1527 return retVal;
1528 }
1529 if (NULL == (netIf->ifConf)->sockstartSec)
1530 {
1531 /* Non mandatory function doesn't exists, return error code */
1532 return SLNETERR_RET_CODE_DOESNT_SUPPORT_NON_MANDATORY_FXN;
1533 }
1534 /* StartSec function called, set bit */
1535 sdFlags |= flags;
1536 /* Function exists in the interface of the socket descriptor, dispatch
1537 the startSec command */
1538 retVal = (netIf->ifConf)->sockstartSec(realSd, sdContext, secAttrib, flags);
1539 SLNETSOCK_NORMALIZE_RET_VAL(retVal,SLNETSOCK_ERR_SOCKSTARTSEC_FAILED);
1540
1541 return retVal;
1542 }
1543