1 /*
2  * socket.c - CC31xx/CC32xx Host Driver Implementation
3  *
4  * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
5  *
6  *
7  *  Redistribution and use in source and binary forms, with or without
8  *  modification, are permitted provided that the following conditions
9  *  are met:
10  *
11  *    Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *
14  *    Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the
17  *    distribution.
18  *
19  *    Neither the name of Texas Instruments Incorporated nor the names of
20  *    its contributors may be used to endorse or promote products derived
21  *    from this software without specific prior written permission.
22  *
23  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  *
35 */
36 
37 
38 
39 
40 /*****************************************************************************/
41 /* Include files                                                             */
42 /*****************************************************************************/
43 #include "simplelink.h"
44 #include "protocol.h"
45 #include "driver.h"
46 
47 
48 void   _sl_BuildAddress(const SlSockAddr_t *addr, _SocketAddrCommand_u    *pCmd);
49 void   _sl_HandleAsync_Connect(void *pVoidBuf);
50 
51 #ifndef SL_TINY_EXT
52 void   _sl_ParseAddress(_SocketAddrResponse_u *pRsp, SlSockAddr_t *addr, SlSocklen_t *addrlen);
53 void   _sl_HandleAsync_Accept(void *pVoidBuf);
54 void   _sl_HandleAsync_Select(void *pVoidBuf);
55 #endif
56 _u16   _sl_TruncatePayloadByProtocol(const _i16 pSd, const _u16 length);
57 
58 /*******************************************************************************/
59 /* Functions                                                                   */
60 /*******************************************************************************/
61 
62 
63     /*  Note: parsing of family and port in the generic way for all IPV4, IPV6 and EUI48 */
64     /*  is possible as _i32 as these parameters are in the same offset and size for these */
65     /*  three families. */
66 #define SL_SOCKET_PAYLOAD_BASE (1350)
67 
68 const _u8 _SlPayloadByProtocolLUT[16] =
69 {
70     (1472 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_UDP_IPV4 */
71     (1460 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_TCP_IPV4 */
72     (1452 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_UDP_IPV6 */
73     (1440 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_TCP_IPV6 */
74     (1386 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_TCP_IPV4_SECURE */
75     (1386 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_UDP_IPV4_SECURE */
76     (1396 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_UDP_IPV6_SECURE */
77     (1396 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_TCP_IPV6_SECURE */
78     (1476 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_RAW_TRANCEIVER */
79     (1514 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_RAW_PACKET */
80     (1480 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_RAW_IP4 */
81     (1480 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_RAW_IP6 */
82     (1440 - SL_SOCKET_PAYLOAD_BASE), /* Default */
83     (1440 - SL_SOCKET_PAYLOAD_BASE), /* Default */
84     (1440 - SL_SOCKET_PAYLOAD_BASE), /* Default */
85     (1440 - SL_SOCKET_PAYLOAD_BASE)  /* Default */
86 };
87 
88 
89 
90 /* ******************************************************************************/
91 /*  _sl_BuildAddress */
92 /* ******************************************************************************/
_sl_BuildAddress(const SlSockAddr_t * addr,_SocketAddrCommand_u * pCmd)93 void _sl_BuildAddress(const SlSockAddr_t *addr, _SocketAddrCommand_u    *pCmd)
94 {
95 
96     /* Note: parsing of family and port in the generic way for all IPV4, IPV6 and EUI48
97            is possible as long as these parameters are in the same offset and size for these
98            three families. */
99     pCmd->IpV4.FamilyAndFlags = (addr->sa_family << 4) & 0xF0;
100     pCmd->IpV4.port = ((SlSockAddrIn_t *)addr)->sin_port;
101 
102     if(SL_AF_INET == addr->sa_family)
103     {
104         pCmd->IpV4.address  = ((SlSockAddrIn_t *)addr)->sin_addr.s_addr;
105     }
106     else if (SL_AF_INET6_EUI_48 == addr->sa_family )
107     {
108         sl_Memcpy( pCmd->IpV6EUI48.address,((SlSockAddrIn6_t *)addr)->sin6_addr._S6_un._S6_u8, 6);
109     }
110 #ifdef SL_SUPPORT_IPV6
111     else
112     {
113         sl_Memcpy(pCmd->IpV6.address, ((sockaddr_in6 *)addr)->sin6_addr._S6_un._S6_u32, 16 );
114     }
115 #endif
116 }
117 
118 
119 /*****************************************************************************
120  _sl_TruncatePayloadByProtocol
121 *****************************************************************************/
_sl_TruncatePayloadByProtocol(const _i16 sd,const _u16 length)122 _u16 _sl_TruncatePayloadByProtocol(const _i16 sd, const _u16 length)
123 {
124    unsigned int maxLength;
125 
126 
127    maxLength = SL_SOCKET_PAYLOAD_BASE + _SlPayloadByProtocolLUT[((sd & SL_SOCKET_PAYLOAD_TYPE_MASK) >> 4)];
128 
129 
130 
131    if( length > maxLength )
132    {
133       return maxLength;
134    }
135    else
136    {
137       return length;
138    }
139 }
140 
141 /*******************************************************************************/
142 /*  _sl_ParseAddress */
143 /*******************************************************************************/
144 
145 #ifndef SL_TINY_EXT
_sl_ParseAddress(_SocketAddrResponse_u * pRsp,SlSockAddr_t * addr,SlSocklen_t * addrlen)146 void _sl_ParseAddress(_SocketAddrResponse_u    *pRsp, SlSockAddr_t *addr, SlSocklen_t *addrlen)
147 {
148     /*  Note: parsing of family and port in the generic way for all IPV4, IPV6 and EUI48 */
149     /*  is possible as long as these parameters are in the same offset and size for these */
150     /*  three families. */
151     addr->sa_family                 = pRsp->IpV4.family;
152     ((SlSockAddrIn_t *)addr)->sin_port = pRsp->IpV4.port;
153 
154     *addrlen = (SL_AF_INET == addr->sa_family) ? sizeof(SlSockAddrIn_t) : sizeof(SlSockAddrIn6_t);
155 
156     if(SL_AF_INET == addr->sa_family)
157     {
158         ((SlSockAddrIn_t *)addr)->sin_addr.s_addr  = pRsp->IpV4.address;
159     }
160     else if (SL_AF_INET6_EUI_48 == addr->sa_family )
161     {
162         sl_Memcpy(((SlSockAddrIn6_t *)addr)->sin6_addr._S6_un._S6_u8, pRsp->IpV6EUI48.address, 6);
163     }
164 #ifdef SL_SUPPORT_IPV6
165     else
166     {
167         sl_Memcpy(((sockaddr_in6 *)addr)->sin6_addr._S6_un._S6_u32, pRsp->IpV6.address, 16);
168     }
169 #endif
170 }
171 
172 #endif
173 
174 /*******************************************************************************/
175 /* sl_Socket */
176 /*******************************************************************************/
177 typedef union
178 {
179     _u32                Dummy;
180 	_SocketCommand_t 	Cmd;
181 	_SocketResponse_t	Rsp;
182 }_SlSockSocketMsg_u;
183 
184 
185 
186 #if _SL_INCLUDE_FUNC(sl_Socket)
187 
188 const _SlCmdCtrl_t _SlSockSocketCmdCtrl =
189 {
190     SL_OPCODE_SOCKET_SOCKET,
191     sizeof(_SocketCommand_t),
192     sizeof(_SocketResponse_t)
193 };
194 
sl_Socket(_i16 Domain,_i16 Type,_i16 Protocol)195 _i16 sl_Socket(_i16 Domain, _i16 Type, _i16 Protocol)
196 {
197     _SlSockSocketMsg_u  Msg;
198 
199     Msg.Cmd.Domain	    = (_u8)Domain;
200     Msg.Cmd.Type     	= (_u8)Type;
201     Msg.Cmd.Protocol 	= (_u8)Protocol;
202 
203     VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSockSocketCmdCtrl, &Msg, NULL));
204 
205     if( Msg.Rsp.statusOrLen < 0 )
206 	{
207 		return( Msg.Rsp.statusOrLen );
208 	}
209 	else
210 	{
211     return (_i16)((_u8)Msg.Rsp.sd);
212 }
213 }
214 #endif
215 
216 /*******************************************************************************/
217 /*  sl_Close  */
218 /*******************************************************************************/
219 typedef union
220 {
221 	_CloseCommand_t	    Cmd;
222 	_SocketResponse_t	Rsp;
223 }_SlSockCloseMsg_u;
224 
225 
226 #if _SL_INCLUDE_FUNC(sl_Close)
227 
228 const _SlCmdCtrl_t _SlSockCloseCmdCtrl =
229 {
230 	SL_OPCODE_SOCKET_CLOSE,
231     sizeof(_CloseCommand_t),
232     sizeof(_SocketResponse_t)
233 };
234 
sl_Close(_i16 sd)235 _i16 sl_Close(_i16 sd)
236 {
237 	_SlSockCloseMsg_u   Msg;
238 
239     Msg.Cmd.sd = (_u8)sd;
240 
241     VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSockCloseCmdCtrl, &Msg, NULL));
242 
243     return Msg.Rsp.statusOrLen;
244 }
245 #endif
246 
247 /*******************************************************************************/
248 /*  sl_Bind */
249 /*******************************************************************************/
250 typedef union
251 {
252 	_SocketAddrCommand_u    Cmd;
253 	_SocketResponse_t	    Rsp;
254 }_SlSockBindMsg_u;
255 
256 #if _SL_INCLUDE_FUNC(sl_Bind)
sl_Bind(_i16 sd,const SlSockAddr_t * addr,_i16 addrlen)257 _i16 sl_Bind(_i16 sd, const SlSockAddr_t *addr, _i16 addrlen)
258 {
259 	_SlSockBindMsg_u    Msg;
260     _SlCmdCtrl_t         CmdCtrl = {0, 0, sizeof(_SocketResponse_t)};
261 
262     switch(addr->sa_family)
263     {
264         case SL_AF_INET :
265             CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND;
266             CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv4Command_t);
267             break;
268 #ifndef SL_TINY_EXT
269         case SL_AF_INET6_EUI_48:
270             CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND_V6;
271             CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6EUI48Command_t);
272         	break;
273 
274 #ifdef SL_SUPPORT_IPV6
275         case AF_INET6:
276             CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND_V6;
277             CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6Command_t);
278             break;
279 #endif
280 #endif
281 
282 
283         case SL_AF_RF   :
284         default:
285             return SL_RET_CODE_INVALID_INPUT;
286     }
287 
288     Msg.Cmd.IpV4.lenOrPadding = 0;
289     Msg.Cmd.IpV4.sd = (_u8)sd;
290 
291     _sl_BuildAddress(addr, &Msg.Cmd);
292 
293     VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, &Msg, NULL));
294 
295     return Msg.Rsp.statusOrLen;
296 }
297 #endif
298 
299 /*******************************************************************************/
300 /*  sl_Sendto */
301 /*******************************************************************************/
302 typedef union
303 {
304     _SocketAddrCommand_u    Cmd;
305     /*  no response for 'sendto' commands*/
306 }_SlSendtoMsg_u;
307 
308 #if _SL_INCLUDE_FUNC(sl_SendTo)
sl_SendTo(_i16 sd,const void * pBuf,_i16 Len,_i16 flags,const SlSockAddr_t * to,SlSocklen_t tolen)309 _i16 sl_SendTo(_i16 sd, const void *pBuf, _i16 Len, _i16 flags, const SlSockAddr_t *to, SlSocklen_t tolen)
310 {
311     _SlSendtoMsg_u   Msg;
312     _SlCmdCtrl_t     CmdCtrl = {0, 0, 0};
313     _SlCmdExt_t      CmdExt;
314     _u16           ChunkLen;
315     _i16              RetVal;
316 
317     _SlDrvResetCmdExt(&CmdExt);
318     CmdExt.TxPayloadLen = (_u16)Len;
319     CmdExt.pTxPayload = (_u8 *)pBuf;
320 
321     switch(to->sa_family)
322     {
323         case SL_AF_INET:
324             CmdCtrl.Opcode = SL_OPCODE_SOCKET_SENDTO;
325             CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv4Command_t);
326             break;
327 #ifndef SL_TINY_EXT
328         case SL_AF_INET6_EUI_48:
329             CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND_V6;
330             CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6EUI48Command_t);
331         	break;
332 #ifdef SL_SUPPORT_IPV6
333         case AF_INET6:
334             CmdCtrl.Opcode = SL_OPCODE_SOCKET_SENDTO_V6;
335             CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6Command_t);
336             break;
337 #endif
338 #endif
339         case SL_AF_RF:
340         default:
341             return SL_RET_CODE_INVALID_INPUT;
342     }
343 
344     ChunkLen = _sl_TruncatePayloadByProtocol(sd,Len);
345     Msg.Cmd.IpV4.lenOrPadding = ChunkLen;
346     CmdExt.TxPayloadLen = ChunkLen;
347 
348     Msg.Cmd.IpV4.sd = (_u8)sd;
349 
350     _sl_BuildAddress(to, &Msg.Cmd);
351 
352     Msg.Cmd.IpV4.FamilyAndFlags |= flags & 0x0F;
353 
354     do
355     {
356         RetVal = _SlDrvDataWriteOp((_SlSd_t)sd, &CmdCtrl, &Msg, &CmdExt);
357 
358         if(SL_OS_RET_CODE_OK == RetVal)
359         {
360             CmdExt.pTxPayload += ChunkLen;
361             ChunkLen = (_u16)((_u8 *)pBuf + Len - CmdExt.pTxPayload);
362             ChunkLen = _sl_TruncatePayloadByProtocol(sd,ChunkLen);
363             CmdExt.TxPayloadLen = ChunkLen;
364             Msg.Cmd.IpV4.lenOrPadding = ChunkLen;
365         }
366         else
367         {
368             return RetVal;
369         }
370     }while(ChunkLen > 0);
371 
372     return (_i16)Len;
373 }
374 #endif
375 
376 /*******************************************************************************/
377 /*  sl_Recvfrom */
378 /*******************************************************************************/
379 typedef union
380 {
381     _sendRecvCommand_t	    Cmd;
382     _SocketAddrResponse_u	Rsp;
383 }_SlRecvfromMsg_u;
384 
385 const _SlCmdCtrl_t _SlRecvfomCmdCtrl =
386 {
387 	SL_OPCODE_SOCKET_RECVFROM,
388     sizeof(_sendRecvCommand_t),
389     sizeof(_SocketAddrResponse_u)
390 };
391 
392 
393 
394 #if _SL_INCLUDE_FUNC(sl_RecvFrom)
sl_RecvFrom(_i16 sd,void * buf,_i16 Len,_i16 flags,SlSockAddr_t * from,SlSocklen_t * fromlen)395 _i16 sl_RecvFrom(_i16 sd, void *buf, _i16 Len, _i16 flags, SlSockAddr_t *from, SlSocklen_t *fromlen)
396 {
397     _SlRecvfromMsg_u    Msg;
398     _SlCmdExt_t         CmdExt;
399     _i16                 RetVal;
400 
401 
402     _SlDrvResetCmdExt(&CmdExt);
403     CmdExt.RxPayloadLen = Len;
404     CmdExt.pRxPayload = (_u8 *)buf;
405 
406     Msg.Cmd.sd = (_u8)sd;
407     Msg.Cmd.StatusOrLen = Len;
408     /*  no size truncation in recv path */
409     CmdExt.RxPayloadLen = Msg.Cmd.StatusOrLen;
410 
411 
412     Msg.Cmd.FamilyAndFlags = flags & 0x0F;
413 
414 
415     if(sizeof(SlSockAddrIn_t) == *fromlen)
416     {
417         Msg.Cmd.FamilyAndFlags |= (SL_AF_INET << 4);
418     }
419     else if (sizeof(SlSockAddrIn6_t) == *fromlen)
420     {
421         Msg.Cmd.FamilyAndFlags |= (SL_AF_INET6 << 4);
422     }
423     else
424     {
425         return SL_RET_CODE_INVALID_INPUT;
426     }
427 
428     RetVal = _SlDrvDataReadOp((_SlSd_t)sd, (_SlCmdCtrl_t *)&_SlRecvfomCmdCtrl, &Msg, &CmdExt);
429     if( RetVal != SL_OS_RET_CODE_OK )
430     {
431 	return RetVal;
432     }
433 
434     RetVal = Msg.Rsp.IpV4.statusOrLen;
435 
436     if(RetVal >= 0)
437     {
438         VERIFY_PROTOCOL(sd == Msg.Rsp.IpV4.sd);
439 #if 0
440         _sl_ParseAddress(&Msg.Rsp, from, fromlen);
441 #else
442         from->sa_family = Msg.Rsp.IpV4.family;
443         if(SL_AF_INET == from->sa_family)
444         {
445             ((SlSockAddrIn_t *)from)->sin_port = Msg.Rsp.IpV4.port;
446             ((SlSockAddrIn_t *)from)->sin_addr.s_addr = Msg.Rsp.IpV4.address;
447             *fromlen = sizeof(SlSockAddrIn_t);
448         }
449         else if (SL_AF_INET6_EUI_48 == from->sa_family )
450          {
451             ((SlSockAddrIn6_t *)from)->sin6_port  = Msg.Rsp.IpV6EUI48.port;
452             sl_Memcpy(((SlSockAddrIn6_t *)from)->sin6_addr._S6_un._S6_u8, Msg.Rsp.IpV6EUI48.address, 6);
453          }
454 #ifdef SL_SUPPORT_IPV6
455         else if(AF_INET6 == from->sa_family)
456         {
457             VERIFY_PROTOCOL(*fromlen >= sizeof(sockaddr_in6));
458 
459             ((sockaddr_in6 *)from)->sin6_port = Msg.Rsp.IpV6.port;
460             sl_Memcpy(((sockaddr_in6 *)from)->sin6_addr._S6_un._S6_u32, Msg.Rsp.IpV6.address, 16);
461             *fromlen = sizeof(sockaddr_in6);
462         }
463 #endif
464 #endif
465     }
466 
467     return (_i16)RetVal;
468 }
469 #endif
470 
471 /*******************************************************************************/
472 /*  sl_Connect */
473 /*******************************************************************************/
474 typedef union
475 {
476 	_SocketAddrCommand_u    Cmd;
477 	_SocketResponse_t	    Rsp;
478 }_SlSockConnectMsg_u;
479 
480 #if _SL_INCLUDE_FUNC(sl_Connect)
sl_Connect(_i16 sd,const SlSockAddr_t * addr,_i16 addrlen)481 _i16 sl_Connect(_i16 sd, const SlSockAddr_t *addr, _i16 addrlen)
482 {
483       _SlSockConnectMsg_u  Msg;
484       _SlReturnVal_t       RetVal;
485       _SlCmdCtrl_t         CmdCtrl = {0, 0, sizeof(_SocketResponse_t)};
486       _SocketResponse_t    AsyncRsp;
487       _u8 ObjIdx = MAX_CONCURRENT_ACTIONS;
488 
489 
490     switch(addr->sa_family)
491     {
492         case SL_AF_INET :
493             CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT;
494             CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv4Command_t);
495             /* Do nothing - cmd already initialized to this type */
496             break;
497         case  SL_AF_INET6_EUI_48:
498             CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT_V6;
499             CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6EUI48Command_t);
500         	break;
501 #ifdef SL_SUPPORT_IPV6
502         case AF_INET6:
503             CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT_V6;
504             CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6Command_t);
505             break;
506 #endif
507         case SL_AF_RF:
508         default:
509             return SL_RET_CODE_INVALID_INPUT;
510     }
511 
512     Msg.Cmd.IpV4.lenOrPadding = 0;
513     Msg.Cmd.IpV4.sd = (_u8)sd;
514 
515     _sl_BuildAddress(addr, &Msg.Cmd);
516 
517 
518     ObjIdx = _SlDrvProtectAsyncRespSetting((_u8*)&AsyncRsp, CONNECT_ID, sd  & BSD_SOCKET_ID_MASK);
519 
520     if (MAX_CONCURRENT_ACTIONS == ObjIdx)
521     {
522         return SL_POOL_IS_EMPTY;
523     }
524 
525     /* send the command */
526     VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, &Msg, NULL));
527     VERIFY_PROTOCOL(Msg.Rsp.sd == sd)
528 
529 	RetVal = Msg.Rsp.statusOrLen;
530 
531     if(SL_RET_CODE_OK == RetVal)
532     {
533 		/* wait for async and get Data Read parameters */
534         _SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj);
535 
536         VERIFY_PROTOCOL(AsyncRsp.sd == sd);
537 
538         RetVal = AsyncRsp.statusOrLen;
539     }
540 
541 
542 
543     _SlDrvReleasePoolObj(ObjIdx);
544     return RetVal;
545 }
546 
547 #endif
548 
549 
550 /*******************************************************************************/
551 /*   _sl_HandleAsync_Connect */
552 /*******************************************************************************/
_sl_HandleAsync_Connect(void * pVoidBuf)553 void _sl_HandleAsync_Connect(void *pVoidBuf)
554 {
555     _SocketResponse_t          *pMsgArgs   = (_SocketResponse_t *)_SL_RESP_ARGS_START(pVoidBuf);
556 
557     _SlDrvProtectionObjLockWaitForever();
558 
559     VERIFY_PROTOCOL((pMsgArgs->sd & BSD_SOCKET_ID_MASK) <= SL_MAX_SOCKETS);
560     VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs);
561 
562 
563     ((_SocketResponse_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->sd = pMsgArgs->sd;
564     ((_SocketResponse_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->statusOrLen = pMsgArgs->statusOrLen;
565 
566 
567     _SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
568     _SlDrvProtectionObjUnLock();
569     return;
570 }
571 
572 /*******************************************************************************/
573 /*  sl_Send */
574 /*******************************************************************************/
575 typedef union
576 {
577 	_sendRecvCommand_t    Cmd;
578     /*  no response for 'sendto' commands*/
579 }_SlSendMsg_u;
580 
581 const _SlCmdCtrl_t _SlSendCmdCtrl =
582 {
583     SL_OPCODE_SOCKET_SEND,
584     sizeof(_sendRecvCommand_t),
585     0
586 };
587 
588 #if _SL_INCLUDE_FUNC(sl_Send)
sl_Send(_i16 sd,const void * pBuf,_i16 Len,_i16 flags)589 _i16 sl_Send(_i16 sd, const void *pBuf, _i16 Len, _i16 flags)
590 {
591     _SlSendMsg_u   Msg;
592     _SlCmdExt_t    CmdExt;
593     _u16         ChunkLen;
594     _i16            RetVal;
595 	_u32         tempVal;
596 	_u8  runSingleChunk = FALSE;
597 
598     _SlDrvResetCmdExt(&CmdExt);
599     CmdExt.TxPayloadLen = Len;
600     CmdExt.pTxPayload = (_u8 *)pBuf;
601 
602     /* Only for RAW transceiver type socket, relay the flags parameter in the 2 bytes (4 byte aligned) before the actual payload */
603     if ((sd & SL_SOCKET_PAYLOAD_TYPE_MASK) == SL_SOCKET_PAYLOAD_TYPE_RAW_TRANCEIVER)
604     {
605 		tempVal = flags;
606         CmdExt.pRxPayload = (_u8 *)&tempVal;
607 		CmdExt.RxPayloadLen = -4; /* mark as Rx data to send */
608 		runSingleChunk = TRUE;
609     }
610     else
611     {
612         CmdExt.pRxPayload = NULL;
613     }
614 
615     ChunkLen = _sl_TruncatePayloadByProtocol(sd,Len);
616     CmdExt.TxPayloadLen = ChunkLen;
617     Msg.Cmd.StatusOrLen = ChunkLen;
618     Msg.Cmd.sd = (_u8)sd;
619     Msg.Cmd.FamilyAndFlags |= flags & 0x0F;
620 
621     do
622     {
623         RetVal = _SlDrvDataWriteOp((_u8)sd, (_SlCmdCtrl_t *)&_SlSendCmdCtrl, &Msg, &CmdExt);
624         if(SL_OS_RET_CODE_OK == RetVal)
625         {
626             CmdExt.pTxPayload += ChunkLen;
627             ChunkLen = (_u8 *)pBuf + Len - CmdExt.pTxPayload;
628             ChunkLen = _sl_TruncatePayloadByProtocol(sd,ChunkLen);
629             CmdExt.TxPayloadLen = ChunkLen;
630             Msg.Cmd.StatusOrLen = ChunkLen;
631         }
632         else
633         {
634             return RetVal;
635         }
636     }while((ChunkLen > 0) && (runSingleChunk==FALSE));
637 
638     return (_i16)Len;
639 }
640 #endif
641 
642 /*******************************************************************************/
643 /*  sl_Listen */
644 /*******************************************************************************/
645 typedef union
646 {
647 	_ListenCommand_t    Cmd;
648     _BasicResponse_t    Rsp;
649 }_SlListenMsg_u;
650 
651 
652 
653 #if _SL_INCLUDE_FUNC(sl_Listen)
654 
655 const _SlCmdCtrl_t _SlListenCmdCtrl =
656 {
657     SL_OPCODE_SOCKET_LISTEN,
658     sizeof(_ListenCommand_t),
659     sizeof(_BasicResponse_t),
660 };
661 
sl_Listen(_i16 sd,_i16 backlog)662 _i16 sl_Listen(_i16 sd, _i16 backlog)
663 {
664     _SlListenMsg_u  Msg;
665 
666     Msg.Cmd.sd = (_u8)sd;
667     Msg.Cmd.backlog = (_u8)backlog;
668 
669     VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlListenCmdCtrl, &Msg, NULL));
670 
671     return (_i16)Msg.Rsp.status;
672 }
673 #endif
674 
675 /*******************************************************************************/
676 /*  sl_Accept */
677 /*******************************************************************************/
678 typedef union
679 {
680 	_AcceptCommand_t    Cmd;
681 	_SocketResponse_t   Rsp;
682 }_SlSockAcceptMsg_u;
683 
684 
685 
686 #if _SL_INCLUDE_FUNC(sl_Accept)
687 
688 const _SlCmdCtrl_t _SlAcceptCmdCtrl =
689 {
690     SL_OPCODE_SOCKET_ACCEPT,
691     sizeof(_AcceptCommand_t),
692     sizeof(_BasicResponse_t),
693 };
694 
sl_Accept(_i16 sd,SlSockAddr_t * addr,SlSocklen_t * addrlen)695 _i16 sl_Accept(_i16 sd, SlSockAddr_t *addr, SlSocklen_t *addrlen)
696 {
697 	_SlSockAcceptMsg_u      Msg;
698     _SlReturnVal_t          RetVal;
699     _SocketAddrResponse_u   AsyncRsp;
700 
701 	_u8 ObjIdx = MAX_CONCURRENT_ACTIONS;
702 
703 
704     Msg.Cmd.sd = (_u8)sd;
705     Msg.Cmd.family = (sizeof(SlSockAddrIn_t) == *addrlen) ? SL_AF_INET : SL_AF_INET6;
706 
707 
708     ObjIdx = _SlDrvProtectAsyncRespSetting((_u8*)&AsyncRsp, ACCEPT_ID, sd  & BSD_SOCKET_ID_MASK );
709 
710     if (MAX_CONCURRENT_ACTIONS == ObjIdx)
711     {
712         return SL_POOL_IS_EMPTY;
713     }
714 
715 	/* send the command */
716     VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlAcceptCmdCtrl, &Msg, NULL));
717     VERIFY_PROTOCOL(Msg.Rsp.sd == sd);
718 
719     RetVal = Msg.Rsp.statusOrLen;
720 
721     if(SL_OS_RET_CODE_OK == RetVal)
722     {
723         /* wait for async and get Data Read parameters */
724         _SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj);
725 
726         VERIFY_PROTOCOL(AsyncRsp.IpV4.sd == sd);
727 
728         RetVal = AsyncRsp.IpV4.statusOrLen;
729         if( (NULL != addr) && (NULL != addrlen) )
730         {
731 #if 0 /*  Kept for backup */
732             _sl_ParseAddress(&AsyncRsp, addr, addrlen);
733 #else
734     	   addr->sa_family = AsyncRsp.IpV4.family;
735 
736     	    if(SL_AF_INET == addr->sa_family)
737     	    {
738               if( *addrlen == sizeof( SlSockAddrIn_t ) )
739               {
740                 ((SlSockAddrIn_t *)addr)->sin_port         = AsyncRsp.IpV4.port;
741                 ((SlSockAddrIn_t *)addr)->sin_addr.s_addr  = AsyncRsp.IpV4.address;
742               }
743               else
744               {
745                 *addrlen = 0;
746               }
747     	    }
748     	    else if (SL_AF_INET6_EUI_48 == addr->sa_family )
749     	    {
750                 if( *addrlen == sizeof( SlSockAddrIn6_t ) )
751               {
752                 ((SlSockAddrIn6_t *)addr)->sin6_port                   = AsyncRsp.IpV6EUI48.port    ;
753                 /*  will be called from here and from _sl_BuildAddress*/
754                 sl_Memcpy(((SlSockAddrIn6_t *)addr)->sin6_addr._S6_un._S6_u8, AsyncRsp.IpV6EUI48.address, 6);
755               }
756               else
757               {
758                 *addrlen = 0;
759               }
760     	    }
761 #ifdef SL_SUPPORT_IPV6
762     	    else
763     	    {
764               if( *addrlen == sizeof( sockaddr_in6 ) )
765               {
766     	        ((sockaddr_in6 *)addr)->sin6_port                   = AsyncRsp.IpV6.port    ;
767     	        sl_Memcpy(((sockaddr_in6 *)addr)->sin6_addr._S6_un._S6_u32, AsyncRsp.IpV6.address, 16);
768               }
769               else
770               {
771                 *addrlen = 0;
772               }
773     	    }
774 #endif
775 #endif
776         }
777     }
778 
779     _SlDrvReleasePoolObj(ObjIdx);
780     return (_i16)RetVal;
781 }
782 #endif
783 
784 
785 /*******************************************************************************/
786 /*  sl_Htonl */
787 /*******************************************************************************/
sl_Htonl(_u32 val)788 _u32 sl_Htonl( _u32 val )
789 {
790   _u32 i = 1;
791   _i8 *p = (_i8 *)&i;
792   if (p[0] == 1) /* little endian */
793   {
794     p[0] = ((_i8* )&val)[3];
795     p[1] = ((_i8* )&val)[2];
796     p[2] = ((_i8* )&val)[1];
797     p[3] = ((_i8* )&val)[0];
798     return i;
799   }
800   else /* big endian */
801   {
802     return val;
803   }
804 }
805 
806 /*******************************************************************************/
807 /*  sl_Htonl */
808 /*******************************************************************************/
sl_Htons(_u16 val)809 _u16 sl_Htons( _u16 val )
810 {
811   _i16 i = 1;
812   _i8 *p = (_i8 *)&i;
813   if (p[0] == 1) /* little endian */
814   {
815     p[0] = ((_i8* )&val)[1];
816     p[1] = ((_i8* )&val)[0];
817     return i;
818   }
819   else /* big endian */
820   {
821     return val;
822   }
823 }
824 
825 /*******************************************************************************/
826 /*   _sl_HandleAsync_Accept */
827 /*******************************************************************************/
828 #ifndef SL_TINY_EXT
_sl_HandleAsync_Accept(void * pVoidBuf)829 void _sl_HandleAsync_Accept(void *pVoidBuf)
830 {
831     _SocketAddrResponse_u      *pMsgArgs   = (_SocketAddrResponse_u *)_SL_RESP_ARGS_START(pVoidBuf);
832 
833     _SlDrvProtectionObjLockWaitForever();
834 
835     VERIFY_PROTOCOL(( pMsgArgs->IpV4.sd & BSD_SOCKET_ID_MASK) <= SL_MAX_SOCKETS);
836     VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs);
837 
838 	sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs,sizeof(_SocketAddrResponse_u));
839 	_SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
840 
841     _SlDrvProtectionObjUnLock();
842     return;
843 }
844 
845 /*******************************************************************************/
846 /*   _sl_HandleAsync_Select */
847 /*******************************************************************************/
_sl_HandleAsync_Select(void * pVoidBuf)848 void _sl_HandleAsync_Select(void *pVoidBuf)
849 {
850     _SelectAsyncResponse_t     *pMsgArgs   = (_SelectAsyncResponse_t *)_SL_RESP_ARGS_START(pVoidBuf);
851 
852     _SlDrvProtectionObjLockWaitForever();
853 
854     VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs);
855 
856     sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_SelectAsyncResponse_t));
857 
858     _SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
859     _SlDrvProtectionObjUnLock();
860 
861     return;
862 }
863 
864 #endif
865 
866 /*******************************************************************************/
867 /*  sl_Recv */
868 /*******************************************************************************/
869 typedef union
870 {
871 	_sendRecvCommand_t  Cmd;
872 	_SocketResponse_t   Rsp;
873 }_SlRecvMsg_u;
874 
875 
876 #if _SL_INCLUDE_FUNC(sl_Recv)
877 
878 const _SlCmdCtrl_t _SlRecvCmdCtrl =
879 {
880     SL_OPCODE_SOCKET_RECV,
881     sizeof(_sendRecvCommand_t),
882     sizeof(_SocketResponse_t)
883 };
884 
885 
sl_Recv(_i16 sd,void * pBuf,_i16 Len,_i16 flags)886 _i16 sl_Recv(_i16 sd, void *pBuf, _i16 Len, _i16 flags)
887 {
888     _SlRecvMsg_u    Msg;
889     _SlCmdExt_t     CmdExt;
890     _SlReturnVal_t status;
891 
892     _SlDrvResetCmdExt(&CmdExt);
893     CmdExt.RxPayloadLen = Len;
894     CmdExt.pRxPayload = (_u8 *)pBuf;
895 
896     Msg.Cmd.sd = (_u8)sd;
897     Msg.Cmd.StatusOrLen = Len;
898 
899     /*  no size truncation in recv path */
900     CmdExt.RxPayloadLen = Msg.Cmd.StatusOrLen;
901 
902     Msg.Cmd.FamilyAndFlags = flags & 0x0F;
903 
904     status = _SlDrvDataReadOp((_SlSd_t)sd, (_SlCmdCtrl_t *)&_SlRecvCmdCtrl, &Msg, &CmdExt);
905     if( status != SL_OS_RET_CODE_OK )
906     {
907 	return status;
908     }
909 
910     /*  if the Device side sends less than expected it is not the Driver's role */
911     /*  the returned value could be smaller than the requested size */
912     return (_i16)Msg.Rsp.statusOrLen;
913 }
914 #endif
915 
916 /*******************************************************************************/
917 /*  sl_SetSockOpt */
918 /*******************************************************************************/
919 typedef union
920 {
921 	_setSockOptCommand_t    Cmd;
922 	_SocketResponse_t       Rsp;
923 }_SlSetSockOptMsg_u;
924 
925 const _SlCmdCtrl_t _SlSetSockOptCmdCtrl =
926 {
927     SL_OPCODE_SOCKET_SETSOCKOPT,
928     sizeof(_setSockOptCommand_t),
929     sizeof(_SocketResponse_t)
930 };
931 
932 #if _SL_INCLUDE_FUNC(sl_SetSockOpt)
sl_SetSockOpt(_i16 sd,_i16 level,_i16 optname,const void * optval,SlSocklen_t optlen)933 _i16 sl_SetSockOpt(_i16 sd, _i16 level, _i16 optname, const void *optval, SlSocklen_t optlen)
934 {
935     _SlSetSockOptMsg_u    Msg;
936     _SlCmdExt_t           CmdExt;
937 
938 
939     _SlDrvResetCmdExt(&CmdExt);
940     CmdExt.TxPayloadLen = optlen;
941     CmdExt.pTxPayload = (_u8 *)optval;
942 
943     Msg.Cmd.sd = (_u8)sd;
944     Msg.Cmd.level = (_u8)level;
945     Msg.Cmd.optionLen = (_u8)optlen;
946     Msg.Cmd.optionName = (_u8)optname;
947 
948     VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSetSockOptCmdCtrl, &Msg, &CmdExt));
949 
950     return (_i16)Msg.Rsp.statusOrLen;
951 }
952 #endif
953 
954 /*******************************************************************************/
955 /*  sl_GetSockOpt */
956 /*******************************************************************************/
957 typedef union
958 {
959 	_getSockOptCommand_t    Cmd;
960 	_getSockOptResponse_t   Rsp;
961 }_SlGetSockOptMsg_u;
962 
963 
964 #if _SL_INCLUDE_FUNC(sl_GetSockOpt)
965 
966 const _SlCmdCtrl_t _SlGetSockOptCmdCtrl =
967 {
968     SL_OPCODE_SOCKET_GETSOCKOPT,
969     sizeof(_getSockOptCommand_t),
970     sizeof(_getSockOptResponse_t)
971 };
972 
sl_GetSockOpt(_i16 sd,_i16 level,_i16 optname,void * optval,SlSocklen_t * optlen)973 _i16 sl_GetSockOpt(_i16 sd, _i16 level, _i16 optname, void *optval, SlSocklen_t *optlen)
974 {
975     _SlGetSockOptMsg_u    Msg;
976     _SlCmdExt_t           CmdExt;
977 
978 	if (*optlen == 0)
979 	{
980 		return SL_EZEROLEN;
981 	}
982 
983     _SlDrvResetCmdExt(&CmdExt);
984     CmdExt.RxPayloadLen = *optlen;
985     CmdExt.pRxPayload = optval;
986 
987     Msg.Cmd.sd = (_u8)sd;
988     Msg.Cmd.level = (_u8)level;
989     Msg.Cmd.optionLen = (_u8)(*optlen);
990     Msg.Cmd.optionName = (_u8)optname;
991 
992     VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlGetSockOptCmdCtrl, &Msg, &CmdExt));
993 
994 	if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen)
995 	{
996 	    *optlen = Msg.Rsp.optionLen;
997 	   return SL_ESMALLBUF;
998 	}
999 	else
1000 	{
1001 		*optlen = (_u8)CmdExt.ActualRxPayloadLen;
1002 	}
1003     return (_i16)Msg.Rsp.status;
1004 }
1005 #endif
1006 
1007 /*******************************************************************************/
1008 /*  sl_Select */
1009 /* ******************************************************************************/
1010 typedef union
1011 {
1012 	_SelectCommand_t   Cmd;
1013 	_BasicResponse_t   Rsp;
1014 }_SlSelectMsg_u;
1015 
1016 
1017 
1018 #ifndef SL_TINY_EXT
1019 #if _SL_INCLUDE_FUNC(sl_Select)
1020 
1021 const _SlCmdCtrl_t _SlSelectCmdCtrl =
1022 {
1023     SL_OPCODE_SOCKET_SELECT,
1024     sizeof(_SelectCommand_t),
1025     sizeof(_BasicResponse_t)
1026 };
1027 
1028 
sl_Select(_i16 nfds,SlFdSet_t * readsds,SlFdSet_t * writesds,SlFdSet_t * exceptsds,struct SlTimeval_t * timeout)1029 _i16 sl_Select(_i16 nfds, SlFdSet_t *readsds, SlFdSet_t *writesds, SlFdSet_t *exceptsds, struct SlTimeval_t *timeout)
1030 {
1031     _SlSelectMsg_u          Msg;
1032     _SelectAsyncResponse_t  AsyncRsp;
1033 	_u8 ObjIdx = MAX_CONCURRENT_ACTIONS;
1034 
1035     Msg.Cmd.nfds          = (_u8)nfds;
1036     Msg.Cmd.readFdsCount  = 0;
1037     Msg.Cmd.writeFdsCount = 0;
1038 
1039     Msg.Cmd.readFds = 0;
1040     Msg.Cmd.writeFds = 0;
1041 
1042 
1043     if( readsds )
1044     {
1045        Msg.Cmd.readFds       = (_u16)readsds->fd_array[0];
1046     }
1047     if( writesds )
1048     {
1049        Msg.Cmd.writeFds      = (_u16)writesds->fd_array[0];
1050     }
1051 	if( NULL == timeout )
1052 	{
1053 		Msg.Cmd.tv_sec = 0xffff;
1054 		Msg.Cmd.tv_usec = 0xffff;
1055 	}
1056 	else
1057 	{
1058 		if( 0xffff <= timeout->tv_sec )
1059 		{
1060 			Msg.Cmd.tv_sec = 0xffff;
1061 		}
1062 		else
1063 		{
1064 			Msg.Cmd.tv_sec = (_u16)timeout->tv_sec;
1065 		}
1066 		timeout->tv_usec = timeout->tv_usec >> 10;  /*  convert to milliseconds */
1067 		if( 0xffff <= timeout->tv_usec )
1068 		{
1069 			Msg.Cmd.tv_usec = 0xffff;
1070 		}
1071 		else
1072 		{
1073 			Msg.Cmd.tv_usec = (_u16)timeout->tv_usec;
1074 		}
1075 	}
1076 
1077 	/* Use Obj to issue the command, if not available try later */
1078     ObjIdx = _SlDrvProtectAsyncRespSetting((_u8*)&AsyncRsp, SELECT_ID, SL_MAX_SOCKETS);
1079 
1080     if (MAX_CONCURRENT_ACTIONS == ObjIdx)
1081     {
1082         return SL_POOL_IS_EMPTY;
1083     }
1084 
1085 
1086 	/* send the command */
1087     VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSelectCmdCtrl, &Msg, NULL));
1088 
1089     if(SL_OS_RET_CODE_OK == (_i16)Msg.Rsp.status)
1090     {
1091         _SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj);
1092 
1093         Msg.Rsp.status = AsyncRsp.status;
1094 
1095         if(  ((_i16)Msg.Rsp.status) >= 0 )
1096         {
1097             if( readsds )
1098             {
1099                readsds->fd_array[0]  = AsyncRsp.readFds;
1100             }
1101             if( writesds )
1102             {
1103                writesds->fd_array[0] = AsyncRsp.writeFds;
1104             }
1105         }
1106     }
1107 
1108     _SlDrvReleasePoolObj(ObjIdx);
1109     return (_i16)Msg.Rsp.status;
1110 }
1111 
1112 /*  Select helper functions */
1113 /*******************************************************************************/
1114 /*  SL_FD_SET */
1115 /* ******************************************************************************/
SL_FD_SET(_i16 fd,SlFdSet_t * fdset)1116 void SL_FD_SET(_i16 fd, SlFdSet_t *fdset)
1117 {
1118    fdset->fd_array[0] |=  (1<< (fd & BSD_SOCKET_ID_MASK));
1119 }
1120 /*******************************************************************************/
1121 /*  SL_FD_CLR */
1122 /*******************************************************************************/
SL_FD_CLR(_i16 fd,SlFdSet_t * fdset)1123 void SL_FD_CLR(_i16 fd, SlFdSet_t *fdset)
1124 {
1125   fdset->fd_array[0] &=  ~(1<< (fd & BSD_SOCKET_ID_MASK));
1126 }
1127 /*******************************************************************************/
1128 /*  SL_FD_ISSET */
1129 /*******************************************************************************/
SL_FD_ISSET(_i16 fd,SlFdSet_t * fdset)1130 _i16  SL_FD_ISSET(_i16 fd, SlFdSet_t *fdset)
1131 {
1132   if( fdset->fd_array[0] & (1<< (fd & BSD_SOCKET_ID_MASK)) )
1133   {
1134     return 1;
1135   }
1136   return 0;
1137 }
1138 /*******************************************************************************/
1139 /*  SL_FD_ZERO */
1140 /*******************************************************************************/
SL_FD_ZERO(SlFdSet_t * fdset)1141 void SL_FD_ZERO(SlFdSet_t *fdset)
1142 {
1143   fdset->fd_array[0] = 0;
1144 }
1145 
1146 #endif
1147 #endif
1148 
1149 
1150 
1151