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