SimpleLink CC3120/CC3220 Host Driver  Version 2.0.1.15
Simplifies the implementation of Internet connectivity
sl_socket.c
1 /*
2  * Copyright (C) 2016 Texas Instruments Incorporated
3  *
4  * All rights reserved. Property of Texas Instruments Incorporated.
5  * Restricted rights to use, duplicate or disclose this code are
6  * granted through contract.
7  *
8  * The program may not be used without the written permission of
9  * Texas Instruments Incorporated or against the terms and conditions
10  * stipulated in the agreement under which this program has been supplied,
11  * and under no circumstances can it be used with non-TI connectivity device.
12  *
13  */
14 
15 
16 
17 
18 /*****************************************************************************/
19 /* Include files */
20 /*****************************************************************************/
21 #include <ti/drivers/net/wifi/simplelink.h>
22 #include <ti/drivers/net/wifi/source/protocol.h>
23 #include <ti/drivers/net/wifi/source/driver.h>
24 
25 static void _SlSocketBuildAddress(const SlSockAddr_t *addr, SlSocketAddrCommand_u *pCmd);
26 _SlReturnVal_t _SlSocketHandleAsync_Connect(void *pVoidBuf);
27 _SlReturnVal_t _SlSocketHandleAsync_Close(void *pVoidBuf);
28 
29 #ifndef SL_TINY
30 void _SlSocketParseAddress(SlSocketAddrResponse_u *pRsp, SlSockAddr_t *addr, SlSocklen_t *addrlen);
31 _SlReturnVal_t _SlSocketHandleAsync_Accept(void *pVoidBuf);
32 _SlReturnVal_t _SlSocketHandleAsync_Select(void *pVoidBuf);
33 #endif
34 
35 /*******************************************************************************/
36 /* Functions */
37 /*******************************************************************************/
38 
39 
40 
41 
42 
43 /* ******************************************************************************/
44 /* _SlSocketBuildAddress */
45 /* ******************************************************************************/
46 static void _SlSocketBuildAddress(const SlSockAddr_t *addr, SlSocketAddrCommand_u *pCmd)
47 {
48 
49  /* Note: parsing of family and port in the generic way for all IPV4, IPV6 and EUI48
50  is possible as long as these parameters are in the same offset and size for these
51  three families. */
52  pCmd->IpV4.FamilyAndFlags = (_u8)((addr->sa_family << 4) & 0xF0);
53  pCmd->IpV4.Port = ((SlSockAddrIn_t *)addr)->sin_port;
54 
55  if(SL_AF_INET == addr->sa_family)
56  {
57  pCmd->IpV4.Address = ((SlSockAddrIn_t *)addr)->sin_addr.s_addr;
58  }
59 #ifdef SL_SUPPORT_IPV6
60  else
61  {
62  sl_Memcpy(pCmd->IpV6.Address, ((SlSockAddrIn6_t *)addr)->sin6_addr._S6_un._S6_u32, 16 );
63  }
64 #endif
65 }
66 
67 
68 /*******************************************************************************/
69 /* _SlSocketParseAddress */
70 /*******************************************************************************/
71 
72 #ifndef SL_TINY
73 void _SlSocketParseAddress(SlSocketAddrResponse_u *pRsp, SlSockAddr_t *addr, SlSocklen_t *addrlen)
74 {
75  /* Note: parsing of family and port in the generic way for all IPV4, IPV6 and EUI48 */
76  /* is possible as long as these parameters are in the same offset and size for these */
77  /* three families. */
78  addr->sa_family = pRsp->IpV4.Family;
79  ((SlSockAddrIn_t *)addr)->sin_port = pRsp->IpV4.Port;
80 
81  *addrlen = (SL_AF_INET == addr->sa_family) ? sizeof(SlSockAddrIn_t) : sizeof(SlSockAddrIn6_t);
82 
83  if(SL_AF_INET == addr->sa_family)
84  {
85  ((SlSockAddrIn_t *)addr)->sin_addr.s_addr = pRsp->IpV4.Address;
86  }
87 #ifdef SL_SUPPORT_IPV6
88  else
89  {
90  sl_Memcpy(((SlSockAddrIn6_t *)addr)->sin6_addr._S6_un._S6_u32, pRsp->IpV6.Address, 16);
91  }
92 #endif
93 }
94 
95 #endif
96 
97 /*******************************************************************************/
98 /* sl_Socket */
99 /*******************************************************************************/
100 typedef union
101 {
102  _u32 Dummy;
103  SlSocketCommand_t Cmd;
104  SlSocketResponse_t Rsp;
105 }_SlSockSocketMsg_u;
106 
107 
108 
109 #if _SL_INCLUDE_FUNC(sl_Socket)
110 
111 static const _SlCmdCtrl_t _SlSockSocketCmdCtrl =
112 {
113  SL_OPCODE_SOCKET_SOCKET,
114  (_SlArgSize_t)sizeof(SlSocketCommand_t),
115  (_SlArgSize_t)sizeof(SlSocketResponse_t)
116 };
117 
118 _i16 sl_Socket(_i16 Domain, _i16 Type, _i16 Protocol)
119 {
120  _SlSockSocketMsg_u Msg;
121 
122  Msg.Cmd.Domain = (_u8)Domain;
123  Msg.Cmd.Type = (_u8)Type;
124  Msg.Cmd.Protocol = (_u8)Protocol;
125 
126  /* verify that this api is allowed. if not allowed then
127  ignore the API execution and return immediately with an error */
128  VERIFY_API_ALLOWED(SL_OPCODE_SILO_SOCKET);
129 
130  VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSockSocketCmdCtrl, &Msg, NULL));
131 
132  if( Msg.Rsp.StatusOrLen < 0 )
133  {
134  return ( Msg.Rsp.StatusOrLen);
135  }
136  else
137  {
138  return (_i16)((_u8)Msg.Rsp.Sd);
139  }
140 }
141 #endif
142 
143 /*******************************************************************************/
144 /* sl_Close */
145 /*******************************************************************************/
146 typedef union
147 {
148  SlCloseCommand_t Cmd;
149  SlSocketResponse_t Rsp;
150 }_SlSockCloseMsg_u;
151 
152 
153 #if _SL_INCLUDE_FUNC(sl_Close)
154 
155 static const _SlCmdCtrl_t _SlSockCloseCmdCtrl =
156 {
157  SL_OPCODE_SOCKET_CLOSE,
158  (_SlArgSize_t)sizeof(SlCloseCommand_t),
159  (_SlArgSize_t)sizeof(SlSocketResponse_t)
160 };
161 
162 _i16 sl_Close(_i16 sd)
163 {
164  _SlSockCloseMsg_u Msg;
165  _u8 ObjIdx = MAX_CONCURRENT_ACTIONS;
166  SlSocketResponse_t AsyncRsp;
167  _SlReturnVal_t RetVal;
168  _u8 bSocketInAction = FALSE;
169 
170  /* verify that this api is allowed. if not allowed then
171  ignore the API execution and return immediately with an error */
172  VERIFY_API_ALLOWED(SL_OPCODE_SILO_SOCKET);
173 
174  Msg.Cmd.Sd = (_u8)sd;
175 
176  /* check if the socket has already action in progress */
177  bSocketInAction = !!(g_pCB->ActiveActionsBitmap & (1<<sd));
178 
179  if (bSocketInAction == FALSE)
180  {
181  ObjIdx = _SlDrvProtectAsyncRespSetting((_u8*)&AsyncRsp, CLOSE_ID, (_u8)(sd & SL_BSD_SOCKET_ID_MASK));
182 
183  if (MAX_CONCURRENT_ACTIONS == ObjIdx)
184  {
185  return SL_POOL_IS_EMPTY;
186  }
187  }
188 
189  VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSockCloseCmdCtrl, &Msg, NULL));
190 
191  RetVal = Msg.Rsp.StatusOrLen;
192 
193  if (bSocketInAction == FALSE)
194  {
195  if( SL_RET_CODE_OK == RetVal)
196  {
197  SL_DRV_SYNC_OBJ_WAIT_TIMEOUT(&g_pCB->ObjPool[ObjIdx].SyncObj,
198  SL_DRIVER_TIMEOUT_LONG,
199  SL_OPCODE_SOCKET_SOCKETCLOSEASYNCEVENT
200  );
201  RetVal = AsyncRsp.StatusOrLen;
202  }
203 
204  _SlDrvReleasePoolObj(ObjIdx);
205  }
206 
207  return RetVal;
208 }
209 #endif
210 
211 /*******************************************************************************/
212 /* sl_Bind */
213 /*******************************************************************************/
214 typedef union
215 {
217  SlSocketResponse_t Rsp;
218 }_SlSockBindMsg_u;
219 
220 #if _SL_INCLUDE_FUNC(sl_Bind)
221 _i16 sl_Bind(_i16 sd, const SlSockAddr_t *addr, _i16 addrlen)
222 {
223  _SlSockBindMsg_u Msg;
224  _SlCmdCtrl_t CmdCtrl = {0, 0, (_SlArgSize_t)sizeof(SlSocketResponse_t)};
225 
226  /* verify that this api is allowed. if not allowed then
227  ignore the API execution and return immediately with an error */
228  VERIFY_API_ALLOWED(SL_OPCODE_SILO_SOCKET);
229 
230  switch(addr->sa_family)
231  {
232  case SL_AF_INET :
233  CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND;
234  CmdCtrl.TxDescLen = (_SlArgSize_t)sizeof(SlSocketAddrIPv4Command_t);
235  break;
236 #ifndef SL_TINY
237 #ifdef SL_SUPPORT_IPV6
238  case SL_AF_INET6:
239  CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND_V6;
240  CmdCtrl.TxDescLen = (_SlArgSize_t)sizeof(SlSocketAddrIPv6Command_t);
241  break;
242 #endif
243 #endif
244 
245  case SL_AF_RF :
246  default:
247  return SL_RET_CODE_INVALID_INPUT;
248  }
249 
250  Msg.Cmd.IpV4.LenOrPadding = 0;
251  Msg.Cmd.IpV4.Sd = (_u8)sd;
252 
253  _SlSocketBuildAddress(addr, &Msg.Cmd);
254  VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, &Msg, NULL));
255 
256  return Msg.Rsp.StatusOrLen;
257 }
258 #endif
259 
260 /*******************************************************************************/
261 /* sl_Sendto */
262 /*******************************************************************************/
263 typedef union
264 {
266  /* no response for 'sendto' commands*/
267 }_SlSendtoMsg_u;
268 
269 #if _SL_INCLUDE_FUNC(sl_SendTo)
270 _i16 sl_SendTo(_i16 sd, const void *pBuf, _i16 Len, _i16 flags, const SlSockAddr_t *to, SlSocklen_t tolen)
271 {
272  _SlSendtoMsg_u Msg;
273  _SlCmdCtrl_t CmdCtrl = {0, 0, 0};
274  _SlCmdExt_t CmdExt;
275  _i16 RetVal;
276 
277  /* verify that this api is allowed. if not allowed then
278  ignore the API execution and return immediately with an error */
279  VERIFY_API_ALLOWED(SL_OPCODE_SILO_SOCKET);
280  /* RAW transceiver use only sl_Send */
281  if ((sd & SL_SOCKET_PAYLOAD_TYPE_MASK) == SL_SOCKET_PAYLOAD_TYPE_RAW_TRANCEIVER)
282  {
283  return SL_ERROR_BSD_SOC_ERROR;
284  }
285  else
286  {
287  if (Len < 1)
288  {
289  /* ignore */
290  return 0;
291  }
292  }
293 
294  _SlDrvResetCmdExt(&CmdExt);
295  CmdExt.TxPayload1Len = (_u16)Len;
296  CmdExt.pTxPayload1 = (_u8 *)pBuf;
297 
298  switch(to->sa_family)
299  {
300  case SL_AF_INET:
301  CmdCtrl.Opcode = SL_OPCODE_SOCKET_SENDTO;
302  CmdCtrl.TxDescLen = (_SlArgSize_t)sizeof(SlSocketAddrIPv4Command_t);
303  break;
304 #ifndef SL_TINY
305 #ifdef SL_SUPPORT_IPV6
306  case SL_AF_INET6:
307  CmdCtrl.Opcode = SL_OPCODE_SOCKET_SENDTO_V6;
308  CmdCtrl.TxDescLen = (_SlArgSize_t)sizeof(SlSocketAddrIPv6Command_t);
309  break;
310 #endif
311 #endif
312  case SL_AF_RF:
313  default:
314  return SL_RET_CODE_INVALID_INPUT;
315  }
316 
317  Msg.Cmd.IpV4.LenOrPadding = Len;
318  Msg.Cmd.IpV4.Sd = (_u8)sd;
319  _SlSocketBuildAddress(to, &Msg.Cmd);
320  Msg.Cmd.IpV4.FamilyAndFlags |= flags & 0x0F;
321 
322  RetVal = _SlDrvDataWriteOp((_SlSd_t)sd, &CmdCtrl, &Msg, &CmdExt);
323  if(SL_OS_RET_CODE_OK != RetVal)
324  {
325  return RetVal;
326  }
327 
328  return (_i16)Len;
329 }
330 #endif
331 
332 /*******************************************************************************/
333 /* sl_Recvfrom */
334 /*******************************************************************************/
335 typedef union
336 {
339 }_SlRecvfromMsg_u;
340 
341 static const _SlCmdCtrl_t _SlRecvfomCmdCtrl =
342 {
343  SL_OPCODE_SOCKET_RECVFROM,
344  (_SlArgSize_t)sizeof(SlSendRecvCommand_t),
345  (_SlArgSize_t)sizeof(SlSocketAddrResponse_u)
346 };
347 
348 
349 
350 #if _SL_INCLUDE_FUNC(sl_RecvFrom)
351 _i16 sl_RecvFrom(_i16 sd, void *buf, _i16 Len, _i16 flags, SlSockAddr_t *from, SlSocklen_t *fromlen)
352 {
353  _SlRecvfromMsg_u Msg;
354  _SlCmdExt_t CmdExt;
355  _i16 RetVal;
356 
357  /* verify that this api is allowed. if not allowed then
358  ignore the API execution and return immediately with an error */
359  VERIFY_API_ALLOWED(SL_OPCODE_SILO_SOCKET);
360 
361  /* RAW transceiver use only sl_Recv */
362  if ((sd & SL_SOCKET_PAYLOAD_TYPE_MASK) == SL_SOCKET_PAYLOAD_TYPE_RAW_TRANCEIVER)
363  {
364  return SL_ERROR_BSD_SOC_ERROR;
365  }
366 
367  _SlDrvResetCmdExt(&CmdExt);
368  CmdExt.RxPayloadLen = Len;
369  CmdExt.pRxPayload = (_u8 *)buf;
370 
371  Msg.Cmd.Sd = (_u8)sd;
372  Msg.Cmd.StatusOrLen = (_u16)Len;
373 
374  /* no size truncation in recv path */
375  CmdExt.RxPayloadLen = (_i16)Msg.Cmd.StatusOrLen;
376 
377  Msg.Cmd.FamilyAndFlags = (_u8)(flags & 0x0F);
378 
379  if(sizeof(SlSockAddrIn_t) == *fromlen)
380  {
381  Msg.Cmd.FamilyAndFlags |= (SL_AF_INET << 4);
382  }
383  else if (sizeof(SlSockAddrIn6_t) == *fromlen)
384  {
385  Msg.Cmd.FamilyAndFlags |= (SL_AF_INET6 << 4);
386  }
387  else
388  {
389  return SL_RET_CODE_INVALID_INPUT;
390  }
391 
392  RetVal = _SlDrvDataReadOp((_SlSd_t)sd, (_SlCmdCtrl_t *)&_SlRecvfomCmdCtrl, &Msg, &CmdExt);
393  if( RetVal != SL_OS_RET_CODE_OK )
394  {
395  return RetVal;
396  }
397 
398  RetVal = Msg.Rsp.IpV4.StatusOrLen;
399 
400  if(RetVal >= 0)
401  {
402  VERIFY_PROTOCOL(sd == (_i16)Msg.Rsp.IpV4.Sd);
403 #if 0
404  _SlSocketParseAddress(&Msg.Rsp, from, fromlen);
405 #else
406  from->sa_family = Msg.Rsp.IpV4.Family;
407  if(SL_AF_INET == from->sa_family)
408  {
409  ((SlSockAddrIn_t *)from)->sin_port = Msg.Rsp.IpV4.Port;
410  ((SlSockAddrIn_t *)from)->sin_addr.s_addr = Msg.Rsp.IpV4.Address;
411  *fromlen = (SlSocklen_t)sizeof(SlSockAddrIn_t);
412  }
413 #ifdef SL_SUPPORT_IPV6
414  else if(SL_AF_INET6 == from->sa_family)
415  {
416  VERIFY_PROTOCOL(*fromlen >= sizeof(SlSockAddrIn6_t));
417 
418  ((SlSockAddrIn6_t *)from)->sin6_port = Msg.Rsp.IpV6.Port;
419  sl_Memcpy(((SlSockAddrIn6_t *)from)->sin6_addr._S6_un._S6_u32, Msg.Rsp.IpV6.Address, 16);
420  *fromlen = sizeof(SlSockAddrIn6_t);
421  }
422 #endif
423 #endif
424  }
425 
426  return (_i16)RetVal;
427 }
428 #endif
429 
430 /*******************************************************************************/
431 /* sl_Connect */
432 /*******************************************************************************/
433 typedef union
434 {
436  SlSocketResponse_t Rsp;
437 }_SlSockConnectMsg_u;
438 
439 #if _SL_INCLUDE_FUNC(sl_Connect)
440 _i16 sl_Connect(_i16 sd, const SlSockAddr_t *addr, _i16 addrlen)
441 {
442  _SlSockConnectMsg_u Msg;
443  _SlReturnVal_t RetVal;
444  _SlCmdCtrl_t CmdCtrl = {0, (_SlArgSize_t)0, (_SlArgSize_t)sizeof(SlSocketResponse_t)};
445  SlSocketResponse_t AsyncRsp;
446  _u8 ObjIdx = MAX_CONCURRENT_ACTIONS;
447 
448  /* verify that this api is allowed. if not allowed then
449  ignore the API execution and return immediately with an error */
450  VERIFY_API_ALLOWED(SL_OPCODE_SILO_SOCKET);
451 
452  switch(addr->sa_family)
453  {
454  case SL_AF_INET :
455  CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT;
456  CmdCtrl.TxDescLen = (_SlArgSize_t)sizeof(SlSocketAddrIPv4Command_t);
457  /* Do nothing - cmd already initialized to this type */
458  break;
459 #ifdef SL_SUPPORT_IPV6
460  case SL_AF_INET6:
461  CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT_V6;
462  CmdCtrl.TxDescLen = (_SlArgSize_t)sizeof(SlSocketAddrIPv6Command_t);
463  break;
464 #endif
465  case SL_AF_RF:
466  default:
467  return SL_RET_CODE_INVALID_INPUT;
468  }
469 
470  Msg.Cmd.IpV4.LenOrPadding = 0;
471  Msg.Cmd.IpV4.Sd = (_u8)sd;
472 
473  _SlSocketBuildAddress(addr, &Msg.Cmd);
474 
475  ObjIdx = _SlDrvProtectAsyncRespSetting((_u8*)&AsyncRsp, CONNECT_ID, (_u8)(sd & SL_BSD_SOCKET_ID_MASK));
476 
477  if (MAX_CONCURRENT_ACTIONS == ObjIdx)
478  {
479  return SL_POOL_IS_EMPTY;
480  }
481 
482  /* send the command */
483  VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, &Msg, NULL));
484  VERIFY_PROTOCOL(Msg.Rsp.Sd == (_u8)sd);
485 
486  RetVal = Msg.Rsp.StatusOrLen;
487 
488  if(SL_RET_CODE_OK == RetVal)
489  {
490 #ifndef SL_TINY
491  /*In case socket is non-blocking one, the async event should be received immediately */
492  if( g_pCB->SocketNonBlocking & (1<<(sd & SL_BSD_SOCKET_ID_MASK) ))
493  {
494  SL_DRV_SYNC_OBJ_WAIT_TIMEOUT(&g_pCB->ObjPool[ObjIdx].SyncObj,
495  SL_DRIVER_TIMEOUT_SHORT,
496  SL_OPCODE_SOCKET_CONNECTASYNCRESPONSE
497  );
498  }
499  else
500 #endif
501  {
502 
503  /* wait for async and get Data Read parameters */
504  SL_DRV_SYNC_OBJ_WAIT_FOREVER(&g_pCB->ObjPool[ObjIdx].SyncObj);
505  }
506 
507  VERIFY_PROTOCOL(AsyncRsp.Sd == (_u8)sd);
508  RetVal = AsyncRsp.StatusOrLen;
509  }
510 
511  _SlDrvReleasePoolObj(ObjIdx);
512  return RetVal;
513 }
514 
515 #endif
516 
517 
518 /*******************************************************************************/
519 /* _SlSocketHandleAsync_Connect */
520 /*******************************************************************************/
521 _SlReturnVal_t _SlSocketHandleAsync_Connect(void *pVoidBuf)
522 {
523  SlSocketResponse_t *pMsgArgs = (SlSocketResponse_t *)_SL_RESP_ARGS_START(pVoidBuf);
524 
525  SL_DRV_PROTECTION_OBJ_LOCK_FOREVER();
526 
527  VERIFY_PROTOCOL((pMsgArgs->Sd & SL_BSD_SOCKET_ID_MASK) <= SL_MAX_SOCKETS);
528  VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs);
529 
530 
531  ((SlSocketResponse_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->Sd = pMsgArgs->Sd;
532  ((SlSocketResponse_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->StatusOrLen = pMsgArgs->StatusOrLen;
533 
534 
535  SL_DRV_SYNC_OBJ_SIGNAL(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
536  SL_DRV_PROTECTION_OBJ_UNLOCK();
537 
538  return SL_OS_RET_CODE_OK;
539 }
540 
541 /*******************************************************************************/
542 /* _SlSocketHandleAsync_Close */
543 /*******************************************************************************/
544 _SlReturnVal_t _SlSocketHandleAsync_Close(void *pVoidBuf)
545 {
546  SlSocketResponse_t *pMsgArgs = (SlSocketResponse_t *)_SL_RESP_ARGS_START(pVoidBuf);
547 
548  SL_DRV_PROTECTION_OBJ_LOCK_FOREVER();
549 
550  VERIFY_PROTOCOL((pMsgArgs->Sd & SL_BSD_SOCKET_ID_MASK) <= SL_MAX_SOCKETS);
551  VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs);
552 
553 
554  ((SlSocketResponse_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->Sd = pMsgArgs->Sd;
555  ((SlSocketResponse_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->StatusOrLen = pMsgArgs->StatusOrLen;
556 
557 
558  SL_DRV_SYNC_OBJ_SIGNAL(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
559  SL_DRV_PROTECTION_OBJ_UNLOCK();
560 
561  return SL_OS_RET_CODE_OK;
562 }
563 
564 /*******************************************************************************/
565 /* sl_Send */
566 /*******************************************************************************/
567 typedef union
568 {
570  /* no response for 'sendto' commands*/
571 }_SlSendMsg_u;
572 
573 static const _SlCmdCtrl_t _SlSendCmdCtrl =
574 {
575  SL_OPCODE_SOCKET_SEND,
576  (_SlArgSize_t)sizeof(SlSendRecvCommand_t),
577  (_SlArgSize_t)0
578 };
579 
580 #if _SL_INCLUDE_FUNC(sl_Send)
581 _i16 sl_Send(_i16 sd, const void *pBuf, _i16 Len, _i16 flags)
582 {
583  _SlSendMsg_u Msg;
584  _SlCmdExt_t CmdExt;
585  _i16 RetVal;
586  _u32 tempVal;
587 
588  /* verify that this api is allowed. if not allowed then
589  ignore the API execution and return immediately with an error */
590  VERIFY_API_ALLOWED(SL_OPCODE_SILO_SOCKET);
591 
592  _SlDrvResetCmdExt(&CmdExt);
593  CmdExt.TxPayload1Len = (_u16)Len;
594  CmdExt.pTxPayload1 = (_u8 *)pBuf;
595 
596  /* Only for RAW transceiver type socket, relay the flags parameter in the 2 bytes (4 byte aligned) before the actual payload */
597  if ((sd & SL_SOCKET_PAYLOAD_TYPE_MASK) == SL_SOCKET_PAYLOAD_TYPE_RAW_TRANCEIVER)
598  {
599  tempVal = (_u32)flags;
600  CmdExt.pRxPayload = (_u8 *)&tempVal;
601  CmdExt.RxPayloadLen = -4; /* the (-) sign is used to mark the rx buff as output buff as well*/
602  }
603  else
604  {
605  CmdExt.pRxPayload = NULL;
606  if (Len < 1)
607  {
608  /* ignore */
609  return 0;
610  }
611  }
612 
613  Msg.Cmd.StatusOrLen = Len;
614  Msg.Cmd.Sd = (_u8)sd;
615  Msg.Cmd.FamilyAndFlags |= flags & 0x0F;
616 
617  RetVal = _SlDrvDataWriteOp((_u8)sd, (_SlCmdCtrl_t *)&_SlSendCmdCtrl, &Msg, &CmdExt);
618  if(SL_OS_RET_CODE_OK != RetVal)
619  {
620  return RetVal;
621  }
622 
623  return (_i16)Len;
624 }
625 #endif
626 
627 /*******************************************************************************/
628 /* sl_Listen */
629 /*******************************************************************************/
630 typedef union
631 {
632  SlListenCommand_t Cmd;
633  _BasicResponse_t Rsp;
634 }_SlListenMsg_u;
635 
636 
637 
638 #if _SL_INCLUDE_FUNC(sl_Listen)
639 
640 static const _SlCmdCtrl_t _SlListenCmdCtrl =
641 {
642  SL_OPCODE_SOCKET_LISTEN,
643  (_SlArgSize_t)sizeof(SlListenCommand_t),
644  (_SlArgSize_t)sizeof(_BasicResponse_t),
645 };
646 
647 _i16 sl_Listen(_i16 sd, _i16 backlog)
648 {
649  _SlListenMsg_u Msg;
650 
651  /* verify that this api is allowed. if not allowed then
652  ignore the API execution and return immediately with an error */
653  VERIFY_API_ALLOWED(SL_OPCODE_SILO_SOCKET);
654 
655  Msg.Cmd.Sd = (_u8)sd;
656  Msg.Cmd.Backlog = (_u8)backlog;
657 
658  VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlListenCmdCtrl, &Msg, NULL));
659  return (_i16)Msg.Rsp.status;
660 }
661 #endif
662 
663 /*******************************************************************************/
664 /* sl_Accept */
665 /*******************************************************************************/
666 typedef union
667 {
668  SlAcceptCommand_t Cmd;
669  SlSocketResponse_t Rsp;
670 }_SlSockAcceptMsg_u;
671 
672 
673 
674 #if _SL_INCLUDE_FUNC(sl_Accept)
675 
676 static const _SlCmdCtrl_t _SlAcceptCmdCtrl =
677 {
678  SL_OPCODE_SOCKET_ACCEPT,
679  (_SlArgSize_t)sizeof(SlAcceptCommand_t),
680  (_SlArgSize_t)sizeof(_BasicResponse_t),
681 };
682 
683 _i16 sl_Accept(_i16 sd, SlSockAddr_t *addr, SlSocklen_t *addrlen)
684 {
685  _SlSockAcceptMsg_u Msg;
686  _SlReturnVal_t RetVal;
687  SlSocketAddrResponse_u AsyncRsp;
688 
689  _u8 ObjIdx = MAX_CONCURRENT_ACTIONS;
690 
691  /* verify that this api is allowed. if not allowed then
692  ignore the API execution and return immediately with an error */
693  VERIFY_API_ALLOWED(SL_OPCODE_SILO_SOCKET);
694 
695  Msg.Cmd.Sd = (_u8)sd;
696  Msg.Cmd.Family = (_u8)((sizeof(SlSockAddrIn_t) == *addrlen) ? SL_AF_INET : SL_AF_INET6);
697 
698  ObjIdx = _SlDrvProtectAsyncRespSetting((_u8*)&AsyncRsp, ACCEPT_ID, (_u8)sd & SL_BSD_SOCKET_ID_MASK);
699 
700  if (MAX_CONCURRENT_ACTIONS == ObjIdx)
701  {
702  return SL_POOL_IS_EMPTY;
703  }
704 
705  /* send the command */
706  VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlAcceptCmdCtrl, &Msg, NULL));
707  VERIFY_PROTOCOL(Msg.Rsp.Sd == (_u8)sd);
708 
709  RetVal = Msg.Rsp.StatusOrLen;
710 
711  if(SL_OS_RET_CODE_OK == RetVal)
712  {
713 #ifndef SL_TINY
714  /* in case socket is non-blocking one, the async event should be received immediately */
715  if( g_pCB->SocketNonBlocking & (1<<(sd & SL_BSD_SOCKET_ID_MASK) ))
716  {
717  SL_DRV_SYNC_OBJ_WAIT_TIMEOUT(&g_pCB->ObjPool[ObjIdx].SyncObj,
718  SL_DRIVER_TIMEOUT_SHORT,
719  SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE
720  );
721  }
722  else
723 #endif
724  {
725  /* wait for async and get Data Read parameters */
726  SL_DRV_SYNC_OBJ_WAIT_FOREVER(&g_pCB->ObjPool[ObjIdx].SyncObj);
727  }
728 
729  VERIFY_PROTOCOL(AsyncRsp.IpV4.Sd == (_u8)sd);
730 
731  RetVal = AsyncRsp.IpV4.StatusOrLen;
732  if( (NULL != addr) && (NULL != addrlen) )
733  {
734 #if 0 /* Kept for backup */
735  _SlSocketParseAddress(&AsyncRsp, addr, addrlen);
736 #else
737  addr->sa_family = AsyncRsp.IpV4.Family;
738 
739  if(SL_AF_INET == addr->sa_family)
740  {
741  if( *addrlen == (SlSocklen_t)sizeof( SlSockAddrIn_t ) )
742  {
743  ((SlSockAddrIn_t *)addr)->sin_port = AsyncRsp.IpV4.Port;
744  ((SlSockAddrIn_t *)addr)->sin_addr.s_addr = AsyncRsp.IpV4.Address;
745  }
746  else
747  {
748  *addrlen = 0;
749  }
750  }
751 #ifdef SL_SUPPORT_IPV6
752  else
753  {
754  if( *addrlen == sizeof( SlSockAddrIn6_t ) )
755  {
756  ((SlSockAddrIn6_t *)addr)->sin6_port = AsyncRsp.IpV6.Port ;
757  sl_Memcpy(((SlSockAddrIn6_t *)addr)->sin6_addr._S6_un._S6_u32, AsyncRsp.IpV6.Address, 16);
758  }
759  else
760  {
761  *addrlen = 0;
762  }
763  }
764 #endif
765 #endif
766  }
767  }
768 
769  _SlDrvReleasePoolObj(ObjIdx);
770  return (_i16)RetVal;
771 }
772 #endif
773 
774 
775 /*******************************************************************************/
776 /* sl_Htonl */
777 /*******************************************************************************/
778 _u32 sl_Htonl( _u32 val )
779 {
780  _u32 i = 1;
781  _i8 *p = (_i8 *)&i;
782  if (p[0] == 1) /* little endian */
783  {
784  p[0] = ((_i8* )&val)[3];
785  p[1] = ((_i8* )&val)[2];
786  p[2] = ((_i8* )&val)[1];
787  p[3] = ((_i8* )&val)[0];
788  return i;
789  }
790  else /* big endian */
791  {
792  return val;
793  }
794 }
795 
796 /*******************************************************************************/
797 /* sl_Htonl */
798 /*******************************************************************************/
799 _u16 sl_Htons( _u16 val )
800 {
801  _i16 i = 1;
802  _i8 *p = (_i8 *)&i;
803  if (p[0] == 1) /* little endian */
804  {
805  p[0] = ((_i8* )&val)[1];
806  p[1] = ((_i8* )&val)[0];
807  return (_u16)i;
808  }
809  else /* big endian */
810  {
811  return val;
812  }
813 }
814 
815 /*******************************************************************************/
816 /* _SlSocketHandleAsync_Accept */
817 /*******************************************************************************/
818 #ifndef SL_TINY
819 _SlReturnVal_t _SlSocketHandleAsync_Accept(void *pVoidBuf)
820 {
821  SlSocketAddrResponse_u *pMsgArgs = (SlSocketAddrResponse_u *)_SL_RESP_ARGS_START(pVoidBuf);
822 
823  SL_DRV_PROTECTION_OBJ_LOCK_FOREVER();
824 
825  VERIFY_PROTOCOL(( pMsgArgs->IpV4.Sd & SL_BSD_SOCKET_ID_MASK) <= SL_MAX_SOCKETS);
826  VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs);
827 
828  sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs,sizeof(SlSocketAddrResponse_u));
829  SL_DRV_SYNC_OBJ_SIGNAL(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
830 
831  SL_DRV_PROTECTION_OBJ_UNLOCK();
832 
833  return SL_OS_RET_CODE_OK;
834 }
835 
836 /*******************************************************************************/
837 /* _SlSocketHandleAsync_Select */
838 /*******************************************************************************/
839 _SlReturnVal_t _SlSocketHandleAsync_Select(void *pVoidBuf)
840 {
841  SlSelectAsyncResponse_t *pMsgArgs = (SlSelectAsyncResponse_t *)_SL_RESP_ARGS_START(pVoidBuf);
842 #if ((defined(SL_RUNTIME_EVENT_REGISTERATION) || defined(slcb_SocketTriggerEventHandler)))
843  SlSockTriggerEvent_t SockTriggerEvent;
844 #endif
845 
846  SL_DRV_PROTECTION_OBJ_LOCK_FOREVER();
847 
848  VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs);
849 
850  sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(SlSelectAsyncResponse_t));
851 
852 #if ((defined(SL_RUNTIME_EVENT_REGISTERATION) || defined(slcb_SocketTriggerEventHandler)))
853  if(1 == _SlIsEventRegistered(SL_EVENT_HDL_SOCKET_TRIGGER))
854  {
855  if (g_pCB->SocketTriggerSelect.Info.State == SOCK_TRIGGER_WAITING_FOR_RESP)
856  {
857 
858  SockTriggerEvent.Event = SL_SOCKET_TRIGGER_EVENT_SELECT;
859  SockTriggerEvent.EventData = 0;
860 
861 
862  g_pCB->SocketTriggerSelect.Info.State = SOCK_TRIGGER_RESP_RECEIVED;
863 
864  SL_DRV_PROTECTION_OBJ_UNLOCK();
865 
866  /* call the user handler */
867  _SlDrvHandleSocketTriggerEvents(&SockTriggerEvent);
868 
869  return SL_OS_RET_CODE_OK;
870  }
871  else
872  {
873  SL_DRV_SYNC_OBJ_SIGNAL(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
874  }
875  }
876  else
877 #endif
878  {
879 
880  SL_DRV_SYNC_OBJ_SIGNAL(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
881 
882  }
883 
884  SL_DRV_PROTECTION_OBJ_UNLOCK();
885 
886  return SL_OS_RET_CODE_OK;
887 }
888 
889 #endif
890 
891 /*******************************************************************************/
892 /* sl_Recv */
893 /*******************************************************************************/
894 typedef union
895 {
897  SlSocketResponse_t Rsp;
898 }_SlRecvMsg_u;
899 
900 
901 #if _SL_INCLUDE_FUNC(sl_Recv)
902 
903 static const _SlCmdCtrl_t _SlRecvCmdCtrl =
904 {
905  SL_OPCODE_SOCKET_RECV,
906  (_SlArgSize_t)sizeof(SlSendRecvCommand_t),
907  (_SlArgSize_t)sizeof(SlSocketResponse_t)
908 };
909 
910 
911 _i16 sl_Recv(_i16 sd, void *pBuf, _i16 Len, _i16 flags)
912 {
913  _SlRecvMsg_u Msg;
914  _SlCmdExt_t CmdExt;
915  _SlReturnVal_t status;
916 
917  /* verify that this api is allowed. if not allowed then
918  ignore the API execution and return immediately with an error */
919  VERIFY_API_ALLOWED(SL_OPCODE_SILO_SOCKET);
920 
921  _SlDrvResetCmdExt(&CmdExt);
922  CmdExt.RxPayloadLen = Len;
923  CmdExt.pRxPayload = (_u8 *)pBuf;
924 
925  Msg.Cmd.Sd = (_u8)sd;
926  Msg.Cmd.StatusOrLen = (_u16)Len;
927 
928  /* no size truncation in recv path */
929  CmdExt.RxPayloadLen = (_i16)Msg.Cmd.StatusOrLen;
930 
931  Msg.Cmd.FamilyAndFlags = (_u8)(flags & 0x0F);
932 
933  status = _SlDrvDataReadOp((_SlSd_t)sd, (_SlCmdCtrl_t *)&_SlRecvCmdCtrl, &Msg, &CmdExt);
934  if( status != SL_OS_RET_CODE_OK )
935  {
936  return status;
937  }
938 
939  /* if the Device side sends less than expected it is not the Driver's role */
940  /* the returned value could be smaller than the requested size */
941  return (_i16)Msg.Rsp.StatusOrLen;
942 }
943 #endif
944 
945 /*******************************************************************************/
946 /* sl_SetSockOpt */
947 /*******************************************************************************/
948 typedef union
949 {
951  SlSocketResponse_t Rsp;
952 }_SlSetSockOptMsg_u;
953 
954 static const _SlCmdCtrl_t _SlSetSockOptCmdCtrl =
955 {
956  SL_OPCODE_SOCKET_SETSOCKOPT,
957  (_SlArgSize_t)sizeof(SlSetSockOptCommand_t),
958  (_SlArgSize_t)sizeof(SlSocketResponse_t)
959 };
960 
961 #if _SL_INCLUDE_FUNC(sl_SetSockOpt)
962 _i16 sl_SetSockOpt(_i16 sd, _i16 level, _i16 optname, const void *optval, SlSocklen_t optlen)
963 {
964  _SlSetSockOptMsg_u Msg;
965  _SlCmdExt_t CmdExt;
966 
967  /* verify that this api is allowed. if not allowed then
968  ignore the API execution and return immediately with an error */
969  VERIFY_API_ALLOWED(SL_OPCODE_SILO_SOCKET);
970 
971  _SlDrvResetCmdExt(&CmdExt);
972  CmdExt.TxPayload1Len = optlen;
973  CmdExt.pTxPayload1 = (_u8 *)optval;
974 
975  Msg.Cmd.Sd = (_u8)sd;
976  Msg.Cmd.Level = (_u8)level;
977  Msg.Cmd.OptionLen = (_u8)optlen;
978  Msg.Cmd.OptionName = (_u8)optname;
979 
980  VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSetSockOptCmdCtrl, &Msg, &CmdExt));
981 
982  return (_i16)Msg.Rsp.StatusOrLen;
983 }
984 #endif
985 
986 /*******************************************************************************/
987 /* sl_GetSockOpt */
988 /*******************************************************************************/
989 typedef union
990 {
993 }_SlGetSockOptMsg_u;
994 
995 
996 #if _SL_INCLUDE_FUNC(sl_GetSockOpt)
997 
998 static const _SlCmdCtrl_t _SlGetSockOptCmdCtrl =
999 {
1000  SL_OPCODE_SOCKET_GETSOCKOPT,
1001  (_SlArgSize_t)sizeof(SlGetSockOptCommand_t),
1002  (_SlArgSize_t)sizeof(SlGetSockOptResponse_t)
1003 };
1004 
1005 _i16 sl_GetSockOpt(_i16 sd, _i16 level, _i16 optname, void *optval, SlSocklen_t *optlen)
1006 {
1007  _SlGetSockOptMsg_u Msg;
1008  _SlCmdExt_t CmdExt;
1009 
1010  /* verify that this api is allowed. if not allowed then
1011  ignore the API execution and return immediately with an error */
1012  VERIFY_API_ALLOWED(SL_OPCODE_SILO_SOCKET);
1013  if (*optlen == 0)
1014  {
1015  return SL_EZEROLEN;
1016  }
1017 
1018  _SlDrvResetCmdExt(&CmdExt);
1019  CmdExt.RxPayloadLen = (_i16)(*optlen);
1020  CmdExt.pRxPayload = optval;
1021 
1022  Msg.Cmd.Sd = (_u8)sd;
1023  Msg.Cmd.Level = (_u8)level;
1024  Msg.Cmd.OptionLen = (_u8)(*optlen);
1025  Msg.Cmd.OptionName = (_u8)optname;
1026 
1027  VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlGetSockOptCmdCtrl, &Msg, &CmdExt));
1028 
1029  if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen)
1030  {
1031  *optlen = Msg.Rsp.OptionLen;
1032  return SL_ESMALLBUF;
1033  }
1034  else
1035  {
1036  *optlen = (_u8)CmdExt.ActualRxPayloadLen;
1037  }
1038  return (_i16)Msg.Rsp.Status;
1039 }
1040 #endif
1041 
1042 /*******************************************************************************/
1043 /* sl_Select */
1044 /* ******************************************************************************/
1045 typedef union
1046 {
1047  SlSelectCommand_t Cmd;
1048  _BasicResponse_t Rsp;
1049 }_SlSelectMsg_u;
1050 
1051 /* Select helper functions */
1052 /*******************************************************************************/
1053 /* SL_SOCKET_FD_SET */
1054 /* ******************************************************************************/
1055 void SL_SOCKET_FD_SET(_i16 fd, SlFdSet_t *fdset)
1056 {
1057  fdset->fd_array[0] |= (1<< (fd & SL_BSD_SOCKET_ID_MASK));
1058 }
1059 /*******************************************************************************/
1060 /* SL_SOCKET_FD_CLR */
1061 /*******************************************************************************/
1062 void SL_SOCKET_FD_CLR(_i16 fd, SlFdSet_t *fdset)
1063 {
1064  fdset->fd_array[0] &= ~(1<< (fd & SL_BSD_SOCKET_ID_MASK));
1065 }
1066 /*******************************************************************************/
1067 /* SL_SOCKET_FD_ISSET */
1068 /*******************************************************************************/
1069 _i16 SL_SOCKET_FD_ISSET(_i16 fd, SlFdSet_t *fdset)
1070 {
1071  if( fdset->fd_array[0] & (1<< (fd & SL_BSD_SOCKET_ID_MASK)) )
1072  {
1073  return 1;
1074  }
1075  return 0;
1076 }
1077 /*******************************************************************************/
1078 /* SL_SOCKET_FD_ZERO */
1079 /*******************************************************************************/
1080 void SL_SOCKET_FD_ZERO(SlFdSet_t *fdset)
1081 {
1082  fdset->fd_array[0] = 0;
1083 }
1084 
1085 #ifndef SL_TINY
1086 #if _SL_INCLUDE_FUNC(sl_Select)
1087 
1088 static const _SlCmdCtrl_t _SlSelectCmdCtrl =
1089 {
1090  SL_OPCODE_SOCKET_SELECT,
1091  (_SlArgSize_t)sizeof(SlSelectCommand_t),
1092  (_SlArgSize_t)sizeof(_BasicResponse_t)
1093 };
1094 
1095 
1096 _i16 sl_Select(_i16 nfds, SlFdSet_t *readsds, SlFdSet_t *writesds, SlFdSet_t *exceptsds, struct SlTimeval_t *timeout)
1097 {
1098  _SlSelectMsg_u Msg;
1099  SlSelectAsyncResponse_t AsyncRsp;
1100  _u8 ObjIdx = MAX_CONCURRENT_ACTIONS;
1101 #if ((defined(SL_RUNTIME_EVENT_REGISTERATION) || defined(slcb_SocketTriggerEventHandler)))
1102  _u8 IsNonBlocking = FALSE;
1103 #endif
1104 
1105  /* verify that this API is allowed. if not allowed then
1106  ignore the API execution and return immediately with an error */
1107  VERIFY_API_ALLOWED(SL_OPCODE_SILO_SOCKET);
1108 
1109 #if ((defined(SL_RUNTIME_EVENT_REGISTERATION) || defined(slcb_SocketTriggerEventHandler)))
1110  if(1 == _SlIsEventRegistered(SL_EVENT_HDL_SOCKET_TRIGGER))
1111  {
1112  if( NULL != timeout )
1113  {
1114  /* Set that we are in Non-Blocking mode */
1115  if ( (0 == timeout->tv_sec) && (0 == timeout->tv_usec) )
1116  {
1117  IsNonBlocking = TRUE;
1118  }
1119  else
1120  {
1121  SL_DRV_PROTECTION_OBJ_LOCK_FOREVER();
1122 
1123  /* If there is a trigger select running in the progress abort the new blocking request */
1124  if (g_pCB->SocketTriggerSelect.Info.State > SOCK_TRIGGER_READY)
1125  {
1126  SL_DRV_PROTECTION_OBJ_UNLOCK();
1127  return SL_RET_CODE_SOCKET_SELECT_IN_PROGRESS_ERROR;
1128  }
1129 
1130  SL_DRV_PROTECTION_OBJ_UNLOCK();
1131  }
1132 
1133  if (IsNonBlocking == TRUE)
1134  {
1135  /* return EAGAIN if we alreay have select trigger in progress */
1136  if (g_pCB->SocketTriggerSelect.Info.State == SOCK_TRIGGER_WAITING_FOR_RESP)
1137  {
1138  return SL_ERROR_BSD_EAGAIN;
1139  }
1140  /* return the stored response if already received */
1141  else if (g_pCB->SocketTriggerSelect.Info.State == SOCK_TRIGGER_RESP_RECEIVED)
1142  {
1143 
1144  if( ((_i16)g_pCB->SocketTriggerSelect.Resp.Status) >= 0 )
1145  {
1146  if( readsds )
1147  {
1148  readsds->fd_array[0] = g_pCB->SocketTriggerSelect.Resp.ReadFds;
1149  }
1150  if( writesds )
1151  {
1152  writesds->fd_array[0] = g_pCB->SocketTriggerSelect.Resp.WriteFds;
1153  }
1154  }
1155 
1156  /* Now relaese the pool object */
1157  _SlDrvReleasePoolObj(g_pCB->SocketTriggerSelect.Info.ObjPoolIdx);
1158 
1159  g_pCB->SocketTriggerSelect.Info.ObjPoolIdx = MAX_CONCURRENT_ACTIONS;
1160 
1161  /* Reset the socket select trigger object */
1162  g_pCB->SocketTriggerSelect.Info.State = SOCK_TRIGGER_READY;
1163 
1164  return (_i16)g_pCB->SocketTriggerSelect.Resp.Status;
1165  }
1166  }
1167  }
1168  }
1169 #endif
1170 
1171  Msg.Cmd.Nfds = (_u8)nfds;
1172  Msg.Cmd.ReadFdsCount = 0;
1173  Msg.Cmd.WriteFdsCount = 0;
1174 
1175  Msg.Cmd.ReadFds = 0;
1176  Msg.Cmd.WriteFds = 0;
1177 
1178 
1179  if( readsds )
1180  {
1181  Msg.Cmd.ReadFds = (_u16)readsds->fd_array[0];
1182  }
1183  if( writesds )
1184  {
1185  Msg.Cmd.WriteFds = (_u16)writesds->fd_array[0];
1186  }
1187  if( NULL == timeout )
1188  {
1189  Msg.Cmd.tv_sec = 0xffff;
1190  Msg.Cmd.tv_usec = 0xffff;
1191  }
1192  else
1193  {
1194  if( 0xffff <= timeout->tv_sec )
1195  {
1196  Msg.Cmd.tv_sec = 0xffff;
1197  }
1198  else
1199  {
1200  Msg.Cmd.tv_sec = (_u16)timeout->tv_sec;
1201  }
1202 
1203  /* convert to milliseconds */
1204  timeout->tv_usec = timeout->tv_usec >> 10;
1205 
1206  if( 0xffff <= timeout->tv_usec )
1207  {
1208  Msg.Cmd.tv_usec = 0xffff;
1209  }
1210  else
1211  {
1212  Msg.Cmd.tv_usec = (_u16)timeout->tv_usec;
1213  }
1214 
1215  }
1216 
1217  /* Use Obj to issue the command, if not available try later */
1218  ObjIdx = _SlDrvProtectAsyncRespSetting((_u8*)&AsyncRsp, SELECT_ID, SL_MAX_SOCKETS);
1219 
1220  if (MAX_CONCURRENT_ACTIONS == ObjIdx)
1221  {
1222  return SL_POOL_IS_EMPTY;
1223  }
1224 
1225  /* send the command */
1226  VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSelectCmdCtrl, &Msg, NULL));
1227 
1228  if(SL_OS_RET_CODE_OK == (_i16)Msg.Rsp.status)
1229  {
1230  SL_DRV_SYNC_OBJ_WAIT_FOREVER(&g_pCB->ObjPool[ObjIdx].SyncObj);
1231 
1232  Msg.Rsp.status = (_i16)AsyncRsp.Status;
1233 
1234  /* this code handles the socket trigger mode case */
1235 #if((defined(SL_RUNTIME_EVENT_REGISTERATION) || defined(slcb_SocketTriggerEventHandler)))
1236  if(1 == _SlIsEventRegistered(SL_EVENT_HDL_SOCKET_TRIGGER))
1237  {
1238  /* if no data returned and we are in trigger mode,
1239  send another select cmd but now with timeout infinite,
1240  and return immediately with EAGAIN to the user */
1241  if ((IsNonBlocking == TRUE) && (AsyncRsp.Status == 0))
1242  {
1243  /* set the select trigger-in-progress bit */
1244  g_pCB->SocketTriggerSelect.Info.State = SOCK_TRIGGER_WAITING_FOR_RESP;
1245 
1246  Msg.Cmd.tv_sec = 0xffff;
1247  Msg.Cmd.tv_usec = 0xffff;
1248 
1249  /* Release pool object and try to take another call */
1250  _SlDrvReleasePoolObj(ObjIdx);
1251 
1252  /* Use Obj to issue the command, if not available try later */
1253  ObjIdx = _SlDrvProtectAsyncRespSetting((_u8*)&g_pCB->SocketTriggerSelect.Resp, SELECT_ID, SL_MAX_SOCKETS);
1254 
1255  if (MAX_CONCURRENT_ACTIONS == ObjIdx)
1256  {
1257  return SL_POOL_IS_EMPTY;
1258  }
1259 
1260  /* Save the pool index to be released only after the user read the response */
1261  g_pCB->SocketTriggerSelect.Info.ObjPoolIdx = ObjIdx;
1262 
1263  /* send the command */
1264  VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSelectCmdCtrl, &Msg, NULL));
1265  return SL_ERROR_BSD_EAGAIN;
1266 
1267  }
1268  }
1269 #endif
1270 
1271  if( ((_i16)Msg.Rsp.status) >= 0 )
1272  {
1273  if( readsds )
1274  {
1275  readsds->fd_array[0] = AsyncRsp.ReadFds;
1276  }
1277  if( writesds )
1278  {
1279  writesds->fd_array[0] = AsyncRsp.WriteFds;
1280  }
1281  }
1282  }
1283 
1284  _SlDrvReleasePoolObj(ObjIdx);
1285  return (_i16)Msg.Rsp.status;
1286 }
1287 
1288 #endif
1289 #endif
1290 
_i16 sl_Bind(_i16 sd, const SlSockAddr_t *addr, _i16 addrlen)
Assign a name to a socket.
Definition: sl_socket.c:221
_u32 sl_Htonl(_u32 val)
Reorder the bytes of a 32-bit unsigned value.
Definition: sl_socket.c:778
_i16 sl_Select(_i16 nfds, SlFdSet_t *readsds, SlFdSet_t *writesds, SlFdSet_t *exceptsds, struct SlTimeval_t *timeout)
Monitor socket activity.
Definition: sl_socket.c:1096
void slcb_SocketTriggerEventHandler(SlSockTriggerEvent_t *pSlSockTriggerEvent)
Socket trigger routine. This routine will notify the application that a netwrok activity has been com...
_i16 sl_SetSockOpt(_i16 sd, _i16 level, _i16 optname, const void *optval, SlSocklen_t optlen)
Set socket options-.
Definition: sl_socket.c:962
_u16 sl_Htons(_u16 val)
Reorder the bytes of a 16-bit unsigned value.
Definition: sl_socket.c:799
_i16 sl_Close(_i16 sd)
Gracefully close socket.
Definition: sl_socket.c:162
_i16 sl_Recv(_i16 sd, void *pBuf, _i16 Len, _i16 flags)
Read data from TCP socket.
Definition: sl_socket.c:911
_i16 sl_GetSockOpt(_i16 sd, _i16 level, _i16 optname, void *optval, SlSocklen_t *optlen)
Get socket options.
Definition: sl_socket.c:1005
_i16 sl_Socket(_i16 Domain, _i16 Type, _i16 Protocol)
Create an endpoint for communication.
Definition: sl_socket.c:118
_i16 sl_RecvFrom(_i16 sd, void *buf, _i16 Len, _i16 flags, SlSockAddr_t *from, SlSocklen_t *fromlen)
Read data from socket.
Definition: sl_socket.c:351
_i16 sl_Accept(_i16 sd, SlSockAddr_t *addr, SlSocklen_t *addrlen)
Accept a connection on a socket.
Definition: sl_socket.c:683
_i16 sl_Connect(_i16 sd, const SlSockAddr_t *addr, _i16 addrlen)
Initiate a connection on a socket.
Definition: sl_socket.c:440
_i16 sl_Listen(_i16 sd, _i16 backlog)
Listen for connections on a socket.
Definition: sl_socket.c:647
_i16 sl_SendTo(_i16 sd, const void *pBuf, _i16 Len, _i16 flags, const SlSockAddr_t *to, SlSocklen_t tolen)
Write data to socket.
Definition: sl_socket.c:270
_i16 sl_Send(_i16 sd, const void *pBuf, _i16 Len, _i16 flags)
Write data to TCP socket.
Definition: sl_socket.c:581