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 <zephyr/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