DeepCover Embedded Security in IoT: Public-key Secured Data Paths
Dependencies: MaximInterface
socket.c
00001 /* 00002 * socket.c - CC31xx/CC32xx Host Driver Implementation 00003 * 00004 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ 00005 * 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 00011 * Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * 00014 * Redistributions in binary form must reproduce the above copyright 00015 * notice, this list of conditions and the following disclaimer in the 00016 * documentation and/or other materials provided with the 00017 * distribution. 00018 * 00019 * Neither the name of Texas Instruments Incorporated nor the names of 00020 * its contributors may be used to endorse or promote products derived 00021 * from this software without specific prior written permission. 00022 * 00023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00024 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00025 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00026 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00027 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00028 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00029 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00030 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00031 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00032 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00033 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 * 00035 */ 00036 00037 00038 00039 00040 /*****************************************************************************/ 00041 /* Include files */ 00042 /*****************************************************************************/ 00043 #include "simplelink.h" 00044 #include "protocol.h" 00045 #include "driver.h" 00046 00047 00048 static void _sl_BuildAddress(const SlSockAddr_t *addr, _SocketAddrCommand_u *pCmd); 00049 _SlReturnVal_t _sl_HandleAsync_Connect(void *pVoidBuf); 00050 00051 #ifndef SL_TINY_EXT 00052 void _sl_ParseAddress(_SocketAddrResponse_u *pRsp, SlSockAddr_t *addr, SlSocklen_t *addrlen); 00053 _SlReturnVal_t _sl_HandleAsync_Accept(void *pVoidBuf); 00054 _SlReturnVal_t _sl_HandleAsync_Select(void *pVoidBuf); 00055 #endif 00056 static _u16 _sl_TruncatePayloadByProtocol(const _i16 pSd, const _u16 length); 00057 00058 /*******************************************************************************/ 00059 /* Functions */ 00060 /*******************************************************************************/ 00061 00062 00063 /* Note: parsing of family and port in the generic way for all IPV4, IPV6 and EUI48 */ 00064 /* is possible as _i32 as these parameters are in the same offset and size for these */ 00065 /* three families. */ 00066 #define SL_SOCKET_PAYLOAD_BASE (1350) 00067 00068 static const _u8 _SlPayloadByProtocolLUT[16] = 00069 { 00070 (1472 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_UDP_IPV4 */ 00071 (1460 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_TCP_IPV4 */ 00072 (1452 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_UDP_IPV6 */ 00073 (1440 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_TCP_IPV6 */ 00074 (1386 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_TCP_IPV4_SECURE */ 00075 (1386 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_UDP_IPV4_SECURE */ 00076 (1396 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_UDP_IPV6_SECURE */ 00077 (1396 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_TCP_IPV6_SECURE */ 00078 (1476 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_RAW_TRANCEIVER */ 00079 (1514 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_RAW_PACKET */ 00080 (1480 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_RAW_IP4 */ 00081 (1480 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_RAW_IP6 */ 00082 (1440 - SL_SOCKET_PAYLOAD_BASE), /* Default */ 00083 (1440 - SL_SOCKET_PAYLOAD_BASE), /* Default */ 00084 (1440 - SL_SOCKET_PAYLOAD_BASE), /* Default */ 00085 (1440 - SL_SOCKET_PAYLOAD_BASE) /* Default */ 00086 }; 00087 00088 00089 00090 /* ******************************************************************************/ 00091 /* _sl_BuildAddress */ 00092 /* ******************************************************************************/ 00093 static void _sl_BuildAddress(const SlSockAddr_t *addr, _SocketAddrCommand_u *pCmd) 00094 { 00095 00096 /* Note: parsing of family and port in the generic way for all IPV4, IPV6 and EUI48 00097 is possible as long as these parameters are in the same offset and size for these 00098 three families. */ 00099 pCmd->IpV4.FamilyAndFlags = (_u8)((addr->sa_family << 4) & 0xF0); 00100 pCmd->IpV4.port = ((SlSockAddrIn_t *)addr)->sin_port; 00101 00102 if(SL_AF_INET == addr->sa_family) 00103 { 00104 pCmd->IpV4.address = ((SlSockAddrIn_t *)addr)->sin_addr.s_addr; 00105 } 00106 else if (SL_AF_INET6_EUI_48 == addr->sa_family ) 00107 { 00108 sl_Memcpy( pCmd->IpV6EUI48.address,((SlSockAddrIn6_t *)addr)->sin6_addr._S6_un._S6_u8, 6); 00109 } 00110 #ifdef SL_SUPPORT_IPV6 00111 else 00112 { 00113 sl_Memcpy(pCmd->IpV6.address, ((sockaddr_in6 *)addr)->sin6_addr._S6_un._S6_u32, 16 ); 00114 } 00115 #endif 00116 } 00117 00118 00119 /***************************************************************************** 00120 _sl_TruncatePayloadByProtocol 00121 *****************************************************************************/ 00122 static _u16 _sl_TruncatePayloadByProtocol(const _i16 sd, const _u16 length) 00123 { 00124 _u16 maxLength; 00125 00126 00127 maxLength = (_u16)(SL_SOCKET_PAYLOAD_BASE + _SlPayloadByProtocolLUT[((sd & SL_SOCKET_PAYLOAD_TYPE_MASK) >> 4)]); 00128 00129 00130 00131 if( length > maxLength ) 00132 { 00133 return maxLength; 00134 } 00135 else 00136 { 00137 return length; 00138 } 00139 } 00140 00141 /*******************************************************************************/ 00142 /* _sl_ParseAddress */ 00143 /*******************************************************************************/ 00144 00145 #ifndef SL_TINY_EXT 00146 void _sl_ParseAddress(_SocketAddrResponse_u *pRsp, SlSockAddr_t *addr, SlSocklen_t *addrlen) 00147 { 00148 /* Note: parsing of family and port in the generic way for all IPV4, IPV6 and EUI48 */ 00149 /* is possible as long as these parameters are in the same offset and size for these */ 00150 /* three families. */ 00151 addr->sa_family = pRsp->IpV4.family; 00152 ((SlSockAddrIn_t *)addr)->sin_port = pRsp->IpV4.port; 00153 00154 *addrlen = (SlSocklen_t)((SL_AF_INET == addr->sa_family) ? sizeof(SlSockAddrIn_t) : sizeof(SlSockAddrIn6_t)); 00155 00156 if(SL_AF_INET == addr->sa_family) 00157 { 00158 ((SlSockAddrIn_t *)addr)->sin_addr.s_addr = pRsp->IpV4.address; 00159 } 00160 else if (SL_AF_INET6_EUI_48 == addr->sa_family ) 00161 { 00162 sl_Memcpy(((SlSockAddrIn6_t *)addr)->sin6_addr._S6_un._S6_u8, pRsp->IpV6EUI48.address, 6); 00163 } 00164 #ifdef SL_SUPPORT_IPV6 00165 else 00166 { 00167 sl_Memcpy(((sockaddr_in6 *)addr)->sin6_addr._S6_un._S6_u32, pRsp->IpV6.address, 16); 00168 } 00169 #endif 00170 } 00171 00172 #endif 00173 00174 /*******************************************************************************/ 00175 /* sl_Socket */ 00176 /*******************************************************************************/ 00177 typedef union 00178 { 00179 _u32 Dummy; 00180 _SocketCommand_t Cmd; 00181 _SocketResponse_t Rsp; 00182 }_SlSockSocketMsg_u; 00183 00184 00185 00186 #if _SL_INCLUDE_FUNC(sl_Socket) 00187 00188 static const _SlCmdCtrl_t _SlSockSocketCmdCtrl = 00189 { 00190 SL_OPCODE_SOCKET_SOCKET, 00191 (_SlArgSize_t)sizeof(_SocketCommand_t), 00192 (_SlArgSize_t)sizeof(_SocketResponse_t) 00193 }; 00194 00195 _i16 sl_Socket(_i16 Domain, _i16 Type, _i16 Protocol) 00196 { 00197 _SlSockSocketMsg_u Msg; 00198 00199 Msg.Cmd.Domain = (_u8)Domain; 00200 Msg.Cmd.Type = (_u8)Type; 00201 Msg.Cmd.Protocol = (_u8)Protocol; 00202 00203 /* verify no erorr handling in progress. if in progress than 00204 ignore the API execution and return immediately with an error */ 00205 VERIFY_NO_ERROR_HANDLING_IN_PROGRESS(); 00206 00207 VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSockSocketCmdCtrl, &Msg, NULL)); 00208 00209 if( Msg.Rsp.statusOrLen < 0 ) 00210 { 00211 return( Msg.Rsp.statusOrLen ); 00212 } 00213 else 00214 { 00215 return (_i16)((_u8)Msg.Rsp.sd); 00216 } 00217 } 00218 #endif 00219 00220 /*******************************************************************************/ 00221 /* sl_Close */ 00222 /*******************************************************************************/ 00223 typedef union 00224 { 00225 _CloseCommand_t Cmd; 00226 _SocketResponse_t Rsp; 00227 }_SlSockCloseMsg_u; 00228 00229 00230 #if _SL_INCLUDE_FUNC(sl_Close) 00231 00232 static const _SlCmdCtrl_t _SlSockCloseCmdCtrl = 00233 { 00234 SL_OPCODE_SOCKET_CLOSE, 00235 (_SlArgSize_t)sizeof(_CloseCommand_t), 00236 (_SlArgSize_t)sizeof(_SocketResponse_t) 00237 }; 00238 00239 _i16 sl_Close(_i16 sd) 00240 { 00241 _SlSockCloseMsg_u Msg; 00242 00243 /* verify no erorr handling in progress. if in progress than 00244 ignore the API execution and return immediately with an error */ 00245 VERIFY_NO_ERROR_HANDLING_IN_PROGRESS(); 00246 00247 Msg.Cmd.sd = (_u8)sd; 00248 00249 VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSockCloseCmdCtrl, &Msg, NULL)); 00250 00251 return Msg.Rsp.statusOrLen; 00252 } 00253 #endif 00254 00255 /*******************************************************************************/ 00256 /* sl_Bind */ 00257 /*******************************************************************************/ 00258 typedef union 00259 { 00260 _SocketAddrCommand_u Cmd; 00261 _SocketResponse_t Rsp; 00262 }_SlSockBindMsg_u; 00263 00264 #if _SL_INCLUDE_FUNC(sl_Bind) 00265 _i16 sl_Bind(_i16 sd, const SlSockAddr_t *addr, _i16 addrlen) 00266 { 00267 _SlSockBindMsg_u Msg; 00268 _SlCmdCtrl_t CmdCtrl = {0, 0, (_SlArgSize_t)sizeof(_SocketResponse_t)}; 00269 00270 /* verify no erorr handling in progress. if in progress than 00271 ignore the API execution and return immediately with an error */ 00272 VERIFY_NO_ERROR_HANDLING_IN_PROGRESS(); 00273 00274 switch(addr->sa_family) 00275 { 00276 case SL_AF_INET : 00277 CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND; 00278 CmdCtrl.TxDescLen = (_SlArgSize_t)sizeof(_SocketAddrIPv4Command_t); 00279 break; 00280 #ifndef SL_TINY_EXT 00281 case SL_AF_INET6_EUI_48: 00282 CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND_V6; 00283 CmdCtrl.TxDescLen = (_SlArgSize_t)sizeof(_SocketAddrIPv6EUI48Command_t); 00284 break; 00285 00286 #ifdef SL_SUPPORT_IPV6 00287 case AF_INET6: 00288 CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND_V6; 00289 CmdCtrl.TxDescLen = (_SlArgSize_t)sizeof(_SocketAddrIPv6Command_t); 00290 break; 00291 #endif 00292 #endif 00293 00294 00295 case SL_AF_RF : 00296 default: 00297 return SL_RET_CODE_INVALID_INPUT; 00298 } 00299 00300 Msg.Cmd.IpV4.lenOrPadding = 0; 00301 Msg.Cmd.IpV4.sd = (_u8)sd; 00302 00303 _sl_BuildAddress(addr, &Msg.Cmd); 00304 00305 VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, &Msg, NULL)); 00306 00307 return Msg.Rsp.statusOrLen; 00308 } 00309 #endif 00310 00311 /*******************************************************************************/ 00312 /* sl_Sendto */ 00313 /*******************************************************************************/ 00314 typedef union 00315 { 00316 _SocketAddrCommand_u Cmd; 00317 /* no response for 'sendto' commands*/ 00318 }_SlSendtoMsg_u; 00319 00320 #if _SL_INCLUDE_FUNC(sl_SendTo) 00321 _i16 sl_SendTo(_i16 sd, const void *pBuf, _i16 Len, _i16 flags, const SlSockAddr_t *to, SlSocklen_t tolen) 00322 { 00323 _SlSendtoMsg_u Msg; 00324 _SlCmdCtrl_t CmdCtrl = {0, 0, 0}; 00325 _SlCmdExt_t CmdExt; 00326 _u16 ChunkLen; 00327 _i16 RetVal; 00328 00329 /* verify no erorr handling in progress. if in progress than 00330 ignore the API execution and return immediately with an error */ 00331 VERIFY_NO_ERROR_HANDLING_IN_PROGRESS(); 00332 00333 _SlDrvResetCmdExt(&CmdExt); 00334 CmdExt.TxPayloadLen = (_u16)Len; 00335 CmdExt.pTxPayload = (_u8 *)pBuf; 00336 00337 switch(to->sa_family) 00338 { 00339 case SL_AF_INET: 00340 CmdCtrl.Opcode = SL_OPCODE_SOCKET_SENDTO; 00341 CmdCtrl.TxDescLen = (_SlArgSize_t)sizeof(_SocketAddrIPv4Command_t); 00342 break; 00343 #ifndef SL_TINY_EXT 00344 case SL_AF_INET6_EUI_48: 00345 CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND_V6; 00346 CmdCtrl.TxDescLen = (_SlArgSize_t)sizeof(_SocketAddrIPv6EUI48Command_t); 00347 break; 00348 #ifdef SL_SUPPORT_IPV6 00349 case AF_INET6: 00350 CmdCtrl.Opcode = SL_OPCODE_SOCKET_SENDTO_V6; 00351 CmdCtrl.TxDescLen = (_SlArgSize_t)sizeof(_SocketAddrIPv6Command_t); 00352 break; 00353 #endif 00354 #endif 00355 case SL_AF_RF: 00356 default: 00357 return SL_RET_CODE_INVALID_INPUT; 00358 } 00359 00360 ChunkLen = _sl_TruncatePayloadByProtocol(sd,(_u16)Len); 00361 Msg.Cmd.IpV4.lenOrPadding = (_i16)ChunkLen; 00362 CmdExt.TxPayloadLen = ChunkLen; 00363 00364 Msg.Cmd.IpV4.sd = (_u8)sd; 00365 00366 _sl_BuildAddress(to, &Msg.Cmd); 00367 00368 Msg.Cmd.IpV4.FamilyAndFlags |= flags & 0x0F; 00369 00370 do 00371 { 00372 RetVal = _SlDrvDataWriteOp((_SlSd_t)sd, &CmdCtrl, &Msg, &CmdExt); 00373 00374 if(SL_OS_RET_CODE_OK == RetVal) 00375 { 00376 CmdExt.pTxPayload += ChunkLen; 00377 ChunkLen = (_u16)((_u8 *)pBuf + Len - CmdExt.pTxPayload); 00378 ChunkLen = _sl_TruncatePayloadByProtocol(sd,ChunkLen); 00379 CmdExt.TxPayloadLen = ChunkLen; 00380 Msg.Cmd.IpV4.lenOrPadding = (_i16)ChunkLen; 00381 } 00382 else 00383 { 00384 return RetVal; 00385 } 00386 }while(ChunkLen > 0); 00387 00388 return (_i16)Len; 00389 } 00390 #endif 00391 00392 /*******************************************************************************/ 00393 /* sl_Recvfrom */ 00394 /*******************************************************************************/ 00395 typedef union 00396 { 00397 _sendRecvCommand_t Cmd; 00398 _SocketAddrResponse_u Rsp; 00399 }_SlRecvfromMsg_u; 00400 00401 static const _SlCmdCtrl_t _SlRecvfomCmdCtrl = 00402 { 00403 SL_OPCODE_SOCKET_RECVFROM, 00404 (_SlArgSize_t)sizeof(_sendRecvCommand_t), 00405 (_SlArgSize_t)sizeof(_SocketAddrResponse_u) 00406 }; 00407 00408 00409 00410 #if _SL_INCLUDE_FUNC(sl_RecvFrom) 00411 _i16 sl_RecvFrom(_i16 sd, void *buf, _i16 Len, _i16 flags, SlSockAddr_t *from, SlSocklen_t *fromlen) 00412 { 00413 _SlRecvfromMsg_u Msg; 00414 _SlCmdExt_t CmdExt; 00415 _i16 RetVal; 00416 00417 /* verify no erorr handling in progress. if in progress than 00418 ignore the API execution and return immediately with an error */ 00419 VERIFY_NO_ERROR_HANDLING_IN_PROGRESS(); 00420 00421 _SlDrvResetCmdExt(&CmdExt); 00422 CmdExt.RxPayloadLen = Len; 00423 CmdExt.pRxPayload = (_u8 *)buf; 00424 00425 Msg.Cmd.sd = (_u8)sd; 00426 Msg.Cmd.StatusOrLen = (_u16)Len; 00427 00428 /* no size truncation in recv path */ 00429 CmdExt.RxPayloadLen = (_i16)Msg.Cmd.StatusOrLen; 00430 00431 00432 Msg.Cmd.FamilyAndFlags = (_u8)(flags & 0x0F); 00433 00434 00435 if(sizeof(SlSockAddrIn_t) == *fromlen) 00436 { 00437 Msg.Cmd.FamilyAndFlags |= (SL_AF_INET << 4); 00438 } 00439 else if (sizeof(SlSockAddrIn6_t) == *fromlen) 00440 { 00441 Msg.Cmd.FamilyAndFlags |= (SL_AF_INET6 << 4); 00442 } 00443 else 00444 { 00445 return SL_RET_CODE_INVALID_INPUT; 00446 } 00447 00448 RetVal = _SlDrvDataReadOp((_SlSd_t)sd, (_SlCmdCtrl_t *)&_SlRecvfomCmdCtrl, &Msg, &CmdExt); 00449 if( RetVal != SL_OS_RET_CODE_OK ) 00450 { 00451 return RetVal; 00452 } 00453 00454 RetVal = Msg.Rsp.IpV4.statusOrLen; 00455 00456 if(RetVal >= 0) 00457 { 00458 VERIFY_PROTOCOL(sd == (_i16)Msg.Rsp.IpV4.sd); 00459 #if 0 00460 _sl_ParseAddress(&Msg.Rsp, from, fromlen); 00461 #else 00462 from->sa_family = Msg.Rsp.IpV4.family; 00463 if(SL_AF_INET == from->sa_family) 00464 { 00465 ((SlSockAddrIn_t *)from)->sin_port = Msg.Rsp.IpV4.port; 00466 ((SlSockAddrIn_t *)from)->sin_addr.s_addr = Msg.Rsp.IpV4.address; 00467 *fromlen = (SlSocklen_t)sizeof(SlSockAddrIn_t); 00468 } 00469 else if (SL_AF_INET6_EUI_48 == from->sa_family ) 00470 { 00471 ((SlSockAddrIn6_t *)from)->sin6_port = Msg.Rsp.IpV6EUI48.port; 00472 sl_Memcpy(((SlSockAddrIn6_t *)from)->sin6_addr._S6_un._S6_u8, Msg.Rsp.IpV6EUI48.address, 6); 00473 } 00474 #ifdef SL_SUPPORT_IPV6 00475 else if(AF_INET6 == from->sa_family) 00476 { 00477 VERIFY_PROTOCOL(*fromlen >= sizeof(sockaddr_in6)); 00478 00479 ((sockaddr_in6 *)from)->sin6_port = Msg.Rsp.IpV6.port; 00480 sl_Memcpy(((sockaddr_in6 *)from)->sin6_addr._S6_un._S6_u32, Msg.Rsp.IpV6.address, 16); 00481 *fromlen = sizeof(sockaddr_in6); 00482 } 00483 #endif 00484 #endif 00485 } 00486 00487 return (_i16)RetVal; 00488 } 00489 #endif 00490 00491 /*******************************************************************************/ 00492 /* sl_Connect */ 00493 /*******************************************************************************/ 00494 typedef union 00495 { 00496 _SocketAddrCommand_u Cmd; 00497 _SocketResponse_t Rsp; 00498 }_SlSockConnectMsg_u; 00499 00500 #if _SL_INCLUDE_FUNC(sl_Connect) 00501 _i16 sl_Connect(_i16 sd, const SlSockAddr_t *addr, _i16 addrlen) 00502 { 00503 _SlSockConnectMsg_u Msg; 00504 _SlReturnVal_t RetVal; 00505 _SlCmdCtrl_t CmdCtrl = {0, (_SlArgSize_t)0, (_SlArgSize_t)sizeof(_SocketResponse_t)}; 00506 _SocketResponse_t AsyncRsp; 00507 _u8 ObjIdx = MAX_CONCURRENT_ACTIONS; 00508 00509 /* verify no erorr handling in progress. if in progress than 00510 ignore the API execution and return immediately with an error */ 00511 VERIFY_NO_ERROR_HANDLING_IN_PROGRESS(); 00512 00513 00514 switch(addr->sa_family) 00515 { 00516 case SL_AF_INET : 00517 CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT; 00518 CmdCtrl.TxDescLen = (_SlArgSize_t)sizeof(_SocketAddrIPv4Command_t); 00519 /* Do nothing - cmd already initialized to this type */ 00520 break; 00521 case SL_AF_INET6_EUI_48: 00522 CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT_V6; 00523 CmdCtrl.TxDescLen = (_SlArgSize_t)sizeof(_SocketAddrIPv6EUI48Command_t); 00524 break; 00525 #ifdef SL_SUPPORT_IPV6 00526 case AF_INET6: 00527 CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT_V6; 00528 CmdCtrl.TxDescLen = (_SlArgSize_t)sizeof(_SocketAddrIPv6Command_t); 00529 break; 00530 #endif 00531 case SL_AF_RF: 00532 default: 00533 return SL_RET_CODE_INVALID_INPUT; 00534 } 00535 00536 Msg.Cmd.IpV4.lenOrPadding = 0; 00537 Msg.Cmd.IpV4.sd = (_u8)sd; 00538 00539 _sl_BuildAddress(addr, &Msg.Cmd); 00540 00541 00542 ObjIdx = _SlDrvProtectAsyncRespSetting((_u8*)&AsyncRsp, CONNECT_ID, (_u8)(sd & BSD_SOCKET_ID_MASK)); 00543 00544 if (MAX_CONCURRENT_ACTIONS == ObjIdx) 00545 { 00546 return SL_POOL_IS_EMPTY; 00547 } 00548 00549 /* send the command */ 00550 VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, &Msg, NULL)); 00551 VERIFY_PROTOCOL(Msg.Rsp.sd == (_u8)sd) 00552 00553 RetVal = Msg.Rsp.statusOrLen; 00554 00555 if(SL_RET_CODE_OK == RetVal) 00556 { 00557 #ifndef SL_TINY_EXT 00558 /*In case socket is non-blocking one, the async event should be received immediately */ 00559 if( g_pCB->SocketNonBlocking >> (sd & BSD_SOCKET_ID_MASK)) 00560 { 00561 SL_DRV_SYNC_OBJ_WAIT_TIMEOUT(&g_pCB->ObjPool[ObjIdx].SyncObj, 00562 SL_DRIVER_TIMEOUT_SHORT, 00563 SL_DRIVER_API_SOCKET_CONNECT 00564 ); 00565 } 00566 else 00567 #endif 00568 { 00569 /* wait for async and get Data Read parameters */ 00570 SL_DRV_SYNC_OBJ_WAIT_FOREVER(&g_pCB->ObjPool[ObjIdx].SyncObj); 00571 } 00572 00573 VERIFY_PROTOCOL(AsyncRsp.sd == (_u8)sd); 00574 00575 RetVal = AsyncRsp.statusOrLen; 00576 } 00577 00578 00579 00580 _SlDrvReleasePoolObj(ObjIdx); 00581 return RetVal; 00582 } 00583 00584 #endif 00585 00586 00587 /*******************************************************************************/ 00588 /* _sl_HandleAsync_Connect */ 00589 /*******************************************************************************/ 00590 _SlReturnVal_t _sl_HandleAsync_Connect(void *pVoidBuf) 00591 { 00592 _SocketResponse_t *pMsgArgs = (_SocketResponse_t *)_SL_RESP_ARGS_START(pVoidBuf); 00593 00594 SL_DRV_PROTECTION_OBJ_LOCK_FOREVER(); 00595 00596 VERIFY_PROTOCOL((pMsgArgs->sd & BSD_SOCKET_ID_MASK) <= SL_MAX_SOCKETS); 00597 VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs); 00598 00599 00600 ((_SocketResponse_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->sd = pMsgArgs->sd; 00601 ((_SocketResponse_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->statusOrLen = pMsgArgs->statusOrLen; 00602 00603 00604 SL_DRV_SYNC_OBJ_SIGNAL(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj); 00605 SL_DRV_PROTECTION_OBJ_UNLOCK(); 00606 00607 return SL_RET_CODE_OK; 00608 } 00609 00610 /*******************************************************************************/ 00611 /* sl_Send */ 00612 /*******************************************************************************/ 00613 typedef union 00614 { 00615 _sendRecvCommand_t Cmd; 00616 /* no response for 'sendto' commands*/ 00617 }_SlSendMsg_u; 00618 00619 static const _SlCmdCtrl_t _SlSendCmdCtrl = 00620 { 00621 SL_OPCODE_SOCKET_SEND, 00622 (_SlArgSize_t)sizeof(_sendRecvCommand_t), 00623 (_SlArgSize_t)0 00624 }; 00625 00626 #if _SL_INCLUDE_FUNC(sl_Send) 00627 _i16 sl_Send(_i16 sd, const void *pBuf, _i16 Len, _i16 flags) 00628 { 00629 _SlSendMsg_u Msg; 00630 _SlCmdExt_t CmdExt; 00631 _u16 ChunkLen; 00632 _i16 RetVal; 00633 _u32 tempVal; 00634 _u8 runSingleChunk = FALSE; 00635 00636 /* verify no erorr handling in progress. if in progress than 00637 ignore the API execution and return immediately with an error */ 00638 VERIFY_NO_ERROR_HANDLING_IN_PROGRESS(); 00639 00640 _SlDrvResetCmdExt(&CmdExt); 00641 CmdExt.TxPayloadLen = (_u16)Len; 00642 CmdExt.pTxPayload = (_u8 *)pBuf; 00643 00644 /* Only for RAW transceiver type socket, relay the flags parameter in the 2 bytes (4 byte aligned) before the actual payload */ 00645 if ((sd & SL_SOCKET_PAYLOAD_TYPE_MASK) == SL_SOCKET_PAYLOAD_TYPE_RAW_TRANCEIVER) 00646 { 00647 tempVal = (_u32)flags; 00648 CmdExt.pRxPayload = (_u8 *)&tempVal; 00649 CmdExt.RxPayloadLen = -4; /* mark as Rx data to send */ 00650 runSingleChunk = TRUE; 00651 } 00652 else 00653 { 00654 CmdExt.pRxPayload = NULL; 00655 } 00656 00657 ChunkLen = _sl_TruncatePayloadByProtocol(sd,(_u16)Len); 00658 CmdExt.TxPayloadLen = ChunkLen; 00659 Msg.Cmd.StatusOrLen = ChunkLen; 00660 Msg.Cmd.sd = (_u8)sd; 00661 Msg.Cmd.FamilyAndFlags |= flags & 0x0F; 00662 00663 do 00664 { 00665 RetVal = _SlDrvDataWriteOp((_u8)sd, (_SlCmdCtrl_t *)&_SlSendCmdCtrl, &Msg, &CmdExt); 00666 if(SL_OS_RET_CODE_OK == RetVal) 00667 { 00668 CmdExt.pTxPayload += ChunkLen; 00669 ChunkLen = (_u16)((_u8 *)pBuf + Len - CmdExt.pTxPayload); 00670 ChunkLen = _sl_TruncatePayloadByProtocol(sd, ChunkLen); 00671 CmdExt.TxPayloadLen = ChunkLen; 00672 Msg.Cmd.StatusOrLen = ChunkLen; 00673 } 00674 else 00675 { 00676 return RetVal; 00677 } 00678 }while((ChunkLen > 0) && (runSingleChunk==FALSE)); 00679 00680 return (_i16)Len; 00681 } 00682 #endif 00683 00684 /*******************************************************************************/ 00685 /* sl_Listen */ 00686 /*******************************************************************************/ 00687 typedef union 00688 { 00689 _ListenCommand_t Cmd; 00690 _BasicResponse_t Rsp; 00691 }_SlListenMsg_u; 00692 00693 00694 00695 #if _SL_INCLUDE_FUNC(sl_Listen) 00696 00697 static const _SlCmdCtrl_t _SlListenCmdCtrl = 00698 { 00699 SL_OPCODE_SOCKET_LISTEN, 00700 (_SlArgSize_t)sizeof(_ListenCommand_t), 00701 (_SlArgSize_t)sizeof(_BasicResponse_t), 00702 }; 00703 00704 _i16 sl_Listen(_i16 sd, _i16 backlog) 00705 { 00706 _SlListenMsg_u Msg; 00707 00708 /* verify no erorr handling in progress. if in progress than 00709 ignore the API execution and return immediately with an error */ 00710 VERIFY_NO_ERROR_HANDLING_IN_PROGRESS(); 00711 00712 Msg.Cmd.sd = (_u8)sd; 00713 Msg.Cmd.backlog = (_u8)backlog; 00714 00715 VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlListenCmdCtrl, &Msg, NULL)); 00716 00717 return (_i16)Msg.Rsp.status; 00718 } 00719 #endif 00720 00721 /*******************************************************************************/ 00722 /* sl_Accept */ 00723 /*******************************************************************************/ 00724 typedef union 00725 { 00726 _AcceptCommand_t Cmd; 00727 _SocketResponse_t Rsp; 00728 }_SlSockAcceptMsg_u; 00729 00730 00731 00732 #if _SL_INCLUDE_FUNC(sl_Accept) 00733 00734 static const _SlCmdCtrl_t _SlAcceptCmdCtrl = 00735 { 00736 SL_OPCODE_SOCKET_ACCEPT, 00737 (_SlArgSize_t)sizeof(_AcceptCommand_t), 00738 (_SlArgSize_t)sizeof(_BasicResponse_t), 00739 }; 00740 00741 _i16 sl_Accept(_i16 sd, SlSockAddr_t *addr, SlSocklen_t *addrlen) 00742 { 00743 _SlSockAcceptMsg_u Msg; 00744 _SlReturnVal_t RetVal; 00745 _SocketAddrResponse_u AsyncRsp; 00746 00747 _u8 ObjIdx = MAX_CONCURRENT_ACTIONS; 00748 00749 /* verify no erorr handling in progress. if in progress than 00750 ignore the API execution and return immediately with an error */ 00751 VERIFY_NO_ERROR_HANDLING_IN_PROGRESS(); 00752 00753 00754 00755 Msg.Cmd.sd = (_u8)sd; 00756 Msg.Cmd.family = (_u8)((sizeof(SlSockAddrIn_t) == *addrlen) ? SL_AF_INET : SL_AF_INET6); 00757 00758 00759 ObjIdx = _SlDrvProtectAsyncRespSetting((_u8*)&AsyncRsp, ACCEPT_ID, (_u8)sd & BSD_SOCKET_ID_MASK ); 00760 00761 if (MAX_CONCURRENT_ACTIONS == ObjIdx) 00762 { 00763 return SL_POOL_IS_EMPTY; 00764 } 00765 00766 /* send the command */ 00767 VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlAcceptCmdCtrl, &Msg, NULL)); 00768 VERIFY_PROTOCOL(Msg.Rsp.sd == (_u8)sd); 00769 00770 RetVal = Msg.Rsp.statusOrLen; 00771 00772 if(SL_OS_RET_CODE_OK == RetVal) 00773 { 00774 #ifndef SL_TINY_EXT 00775 /* in case socket is non-blocking one, the async event should be received immediately */ 00776 if( g_pCB->SocketNonBlocking & (1<<(sd & BSD_SOCKET_ID_MASK) )) 00777 { 00778 SL_DRV_SYNC_OBJ_WAIT_TIMEOUT(&g_pCB->ObjPool[ObjIdx].SyncObj, 00779 SL_DRIVER_TIMEOUT_SHORT, 00780 SL_DRIVER_API_SOCKET_ACCEPT 00781 ); 00782 } 00783 else 00784 #endif 00785 { 00786 /* wait for async and get Data Read parameters */ 00787 SL_DRV_SYNC_OBJ_WAIT_FOREVER(&g_pCB->ObjPool[ObjIdx].SyncObj); 00788 } 00789 00790 VERIFY_PROTOCOL(AsyncRsp.IpV4.sd == (_u8)sd); 00791 00792 RetVal = AsyncRsp.IpV4.statusOrLen; 00793 if( (NULL != addr) && (NULL != addrlen) ) 00794 { 00795 #if 0 /* Kept for backup */ 00796 _sl_ParseAddress(&AsyncRsp, addr, addrlen); 00797 #else 00798 addr->sa_family = AsyncRsp.IpV4.family; 00799 00800 if(SL_AF_INET == addr->sa_family) 00801 { 00802 if( *addrlen == (SlSocklen_t)sizeof( SlSockAddrIn_t ) ) 00803 { 00804 ((SlSockAddrIn_t *)addr)->sin_port = AsyncRsp.IpV4.port; 00805 ((SlSockAddrIn_t *)addr)->sin_addr.s_addr = AsyncRsp.IpV4.address; 00806 } 00807 else 00808 { 00809 *addrlen = 0; 00810 } 00811 } 00812 else if (SL_AF_INET6_EUI_48 == addr->sa_family ) 00813 { 00814 if( *addrlen == (SlSocklen_t)sizeof( SlSockAddrIn6_t ) ) 00815 { 00816 ((SlSockAddrIn6_t *)addr)->sin6_port = AsyncRsp.IpV6EUI48.port ; 00817 /* will be called from here and from _sl_BuildAddress*/ 00818 sl_Memcpy(((SlSockAddrIn6_t *)addr)->sin6_addr._S6_un._S6_u8, AsyncRsp.IpV6EUI48.address, 6); 00819 } 00820 else 00821 { 00822 *addrlen = 0; 00823 } 00824 } 00825 #ifdef SL_SUPPORT_IPV6 00826 else 00827 { 00828 if( *addrlen == sizeof( sockaddr_in6 ) ) 00829 { 00830 ((sockaddr_in6 *)addr)->sin6_port = AsyncRsp.IpV6.port ; 00831 sl_Memcpy(((sockaddr_in6 *)addr)->sin6_addr._S6_un._S6_u32, AsyncRsp.IpV6.address, 16); 00832 } 00833 else 00834 { 00835 *addrlen = 0; 00836 } 00837 } 00838 #endif 00839 #endif 00840 } 00841 } 00842 00843 _SlDrvReleasePoolObj(ObjIdx); 00844 return (_i16)RetVal; 00845 } 00846 #endif 00847 00848 00849 /*******************************************************************************/ 00850 /* sl_Htonl */ 00851 /*******************************************************************************/ 00852 _u32 sl_Htonl( _u32 val ) 00853 { 00854 _u32 i = 1; 00855 _i8 *p = (_i8 *)&i; 00856 if (p[0] == 1) /* little endian */ 00857 { 00858 p[0] = ((_i8* )&val)[3]; 00859 p[1] = ((_i8* )&val)[2]; 00860 p[2] = ((_i8* )&val)[1]; 00861 p[3] = ((_i8* )&val)[0]; 00862 return i; 00863 } 00864 else /* big endian */ 00865 { 00866 return val; 00867 } 00868 } 00869 00870 /*******************************************************************************/ 00871 /* sl_Htonl */ 00872 /*******************************************************************************/ 00873 _u16 sl_Htons( _u16 val ) 00874 { 00875 _i16 i = 1; 00876 _i8 *p = (_i8 *)&i; 00877 if (p[0] == 1) /* little endian */ 00878 { 00879 p[0] = ((_i8* )&val)[1]; 00880 p[1] = ((_i8* )&val)[0]; 00881 return (_u16)i; 00882 } 00883 else /* big endian */ 00884 { 00885 return val; 00886 } 00887 } 00888 00889 /*******************************************************************************/ 00890 /* _sl_HandleAsync_Accept */ 00891 /*******************************************************************************/ 00892 #ifndef SL_TINY_EXT 00893 _SlReturnVal_t _sl_HandleAsync_Accept(void *pVoidBuf) 00894 { 00895 _SocketAddrResponse_u *pMsgArgs = (_SocketAddrResponse_u *)_SL_RESP_ARGS_START(pVoidBuf); 00896 00897 SL_DRV_PROTECTION_OBJ_LOCK_FOREVER(); 00898 00899 VERIFY_PROTOCOL(( pMsgArgs->IpV4.sd & BSD_SOCKET_ID_MASK) <= SL_MAX_SOCKETS); 00900 VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs); 00901 00902 sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs,sizeof(_SocketAddrResponse_u)); 00903 SL_DRV_SYNC_OBJ_SIGNAL(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj); 00904 00905 SL_DRV_PROTECTION_OBJ_UNLOCK(); 00906 return SL_RET_CODE_OK; 00907 } 00908 00909 /*******************************************************************************/ 00910 /* _sl_HandleAsync_Select */ 00911 /*******************************************************************************/ 00912 _SlReturnVal_t _sl_HandleAsync_Select(void *pVoidBuf) 00913 { 00914 _SelectAsyncResponse_t *pMsgArgs = (_SelectAsyncResponse_t *)_SL_RESP_ARGS_START(pVoidBuf); 00915 00916 SL_DRV_PROTECTION_OBJ_LOCK_FOREVER(); 00917 00918 VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs); 00919 00920 sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_SelectAsyncResponse_t)); 00921 00922 SL_DRV_SYNC_OBJ_SIGNAL(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj); 00923 00924 SL_DRV_PROTECTION_OBJ_UNLOCK(); 00925 00926 return SL_RET_CODE_OK; 00927 } 00928 00929 #endif 00930 00931 /*******************************************************************************/ 00932 /* sl_Recv */ 00933 /*******************************************************************************/ 00934 typedef union 00935 { 00936 _sendRecvCommand_t Cmd; 00937 _SocketResponse_t Rsp; 00938 }_SlRecvMsg_u; 00939 00940 00941 #if _SL_INCLUDE_FUNC(sl_Recv) 00942 00943 static const _SlCmdCtrl_t _SlRecvCmdCtrl = 00944 { 00945 SL_OPCODE_SOCKET_RECV, 00946 (_SlArgSize_t)sizeof(_sendRecvCommand_t), 00947 (_SlArgSize_t)sizeof(_SocketResponse_t) 00948 }; 00949 00950 00951 _i16 sl_Recv(_i16 sd, void *pBuf, _i16 Len, _i16 flags) 00952 { 00953 _SlRecvMsg_u Msg; 00954 _SlCmdExt_t CmdExt; 00955 _SlReturnVal_t status; 00956 00957 /* verify no erorr handling in progress. if in progress than 00958 ignore the API execution and return immediately with an error */ 00959 VERIFY_NO_ERROR_HANDLING_IN_PROGRESS(); 00960 00961 _SlDrvResetCmdExt(&CmdExt); 00962 CmdExt.RxPayloadLen = Len; 00963 CmdExt.pRxPayload = (_u8 *)pBuf; 00964 00965 Msg.Cmd.sd = (_u8)sd; 00966 Msg.Cmd.StatusOrLen = (_u16)Len; 00967 00968 /* no size truncation in recv path */ 00969 CmdExt.RxPayloadLen = (_i16)Msg.Cmd.StatusOrLen; 00970 00971 Msg.Cmd.FamilyAndFlags = (_u8)(flags & 0x0F); 00972 00973 status = _SlDrvDataReadOp((_SlSd_t)sd, (_SlCmdCtrl_t *)&_SlRecvCmdCtrl, &Msg, &CmdExt); 00974 if( status != SL_OS_RET_CODE_OK ) 00975 { 00976 return status; 00977 } 00978 00979 /* if the Device side sends less than expected it is not the Driver's role */ 00980 /* the returned value could be smaller than the requested size */ 00981 return (_i16)Msg.Rsp.statusOrLen; 00982 } 00983 #endif 00984 00985 /*******************************************************************************/ 00986 /* sl_SetSockOpt */ 00987 /*******************************************************************************/ 00988 typedef union 00989 { 00990 _setSockOptCommand_t Cmd; 00991 _SocketResponse_t Rsp; 00992 }_SlSetSockOptMsg_u; 00993 00994 static const _SlCmdCtrl_t _SlSetSockOptCmdCtrl = 00995 { 00996 SL_OPCODE_SOCKET_SETSOCKOPT, 00997 (_SlArgSize_t)sizeof(_setSockOptCommand_t), 00998 (_SlArgSize_t)sizeof(_SocketResponse_t) 00999 }; 01000 01001 #if _SL_INCLUDE_FUNC(sl_SetSockOpt) 01002 _i16 sl_SetSockOpt(_i16 sd, _i16 level, _i16 optname, const void *optval, SlSocklen_t optlen) 01003 { 01004 _SlSetSockOptMsg_u Msg; 01005 _SlCmdExt_t CmdExt; 01006 01007 /* verify no erorr handling in progress. if in progress than 01008 ignore the API execution and return immediately with an error */ 01009 VERIFY_NO_ERROR_HANDLING_IN_PROGRESS(); 01010 01011 _SlDrvResetCmdExt(&CmdExt); 01012 CmdExt.TxPayloadLen = optlen; 01013 CmdExt.pTxPayload = (_u8 *)optval; 01014 01015 Msg.Cmd.sd = (_u8)sd; 01016 Msg.Cmd.level = (_u8)level; 01017 Msg.Cmd.optionLen = (_u8)optlen; 01018 Msg.Cmd.optionName = (_u8)optname; 01019 01020 VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSetSockOptCmdCtrl, &Msg, &CmdExt)); 01021 01022 return (_i16)Msg.Rsp.statusOrLen; 01023 } 01024 #endif 01025 01026 /*******************************************************************************/ 01027 /* sl_GetSockOpt */ 01028 /*******************************************************************************/ 01029 typedef union 01030 { 01031 _getSockOptCommand_t Cmd; 01032 _getSockOptResponse_t Rsp; 01033 }_SlGetSockOptMsg_u; 01034 01035 01036 #if _SL_INCLUDE_FUNC(sl_GetSockOpt) 01037 01038 static const _SlCmdCtrl_t _SlGetSockOptCmdCtrl = 01039 { 01040 SL_OPCODE_SOCKET_GETSOCKOPT, 01041 (_SlArgSize_t)sizeof(_getSockOptCommand_t), 01042 (_SlArgSize_t)sizeof(_getSockOptResponse_t) 01043 }; 01044 01045 _i16 sl_GetSockOpt(_i16 sd, _i16 level, _i16 optname, void *optval, SlSocklen_t *optlen) 01046 { 01047 _SlGetSockOptMsg_u Msg; 01048 _SlCmdExt_t CmdExt; 01049 01050 /* verify no erorr handling in progress. if in progress than 01051 ignore the API execution and return immediately with an error */ 01052 VERIFY_NO_ERROR_HANDLING_IN_PROGRESS(); 01053 if (*optlen == 0) 01054 { 01055 return SL_EZEROLEN; 01056 } 01057 01058 _SlDrvResetCmdExt(&CmdExt); 01059 CmdExt.RxPayloadLen = (_i16)(*optlen); 01060 CmdExt.pRxPayload = optval; 01061 01062 Msg.Cmd.sd = (_u8)sd; 01063 Msg.Cmd.level = (_u8)level; 01064 Msg.Cmd.optionLen = (_u8)(*optlen); 01065 Msg.Cmd.optionName = (_u8)optname; 01066 01067 VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlGetSockOptCmdCtrl, &Msg, &CmdExt)); 01068 01069 if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) 01070 { 01071 *optlen = Msg.Rsp.optionLen; 01072 return SL_ESMALLBUF; 01073 } 01074 else 01075 { 01076 *optlen = (_u8)CmdExt.ActualRxPayloadLen; 01077 } 01078 return (_i16)Msg.Rsp.status; 01079 } 01080 #endif 01081 01082 /*******************************************************************************/ 01083 /* sl_Select */ 01084 /* ******************************************************************************/ 01085 typedef union 01086 { 01087 _SelectCommand_t Cmd; 01088 _BasicResponse_t Rsp; 01089 }_SlSelectMsg_u; 01090 01091 01092 01093 #ifndef SL_TINY_EXT 01094 #if _SL_INCLUDE_FUNC(sl_Select) 01095 01096 static const _SlCmdCtrl_t _SlSelectCmdCtrl = 01097 { 01098 SL_OPCODE_SOCKET_SELECT, 01099 (_SlArgSize_t)sizeof(_SelectCommand_t), 01100 (_SlArgSize_t)sizeof(_BasicResponse_t) 01101 }; 01102 01103 01104 _i16 sl_Select(_i16 nfds, SlFdSet_t *readsds, SlFdSet_t *writesds, SlFdSet_t *exceptsds, struct SlTimeval_t *timeout) 01105 { 01106 _SlSelectMsg_u Msg; 01107 _SelectAsyncResponse_t AsyncRsp; 01108 _u8 ObjIdx = MAX_CONCURRENT_ACTIONS; 01109 01110 /* verify no erorr handling in progress. if in progress than 01111 ignore the API execution and return immediately with an error */ 01112 VERIFY_NO_ERROR_HANDLING_IN_PROGRESS(); 01113 01114 Msg.Cmd.nfds = (_u8)nfds; 01115 Msg.Cmd.readFdsCount = 0; 01116 Msg.Cmd.writeFdsCount = 0; 01117 01118 Msg.Cmd.readFds = 0; 01119 Msg.Cmd.writeFds = 0; 01120 01121 01122 if( readsds ) 01123 { 01124 Msg.Cmd.readFds = (_u16)readsds->fd_array[0]; 01125 } 01126 if( writesds ) 01127 { 01128 Msg.Cmd.writeFds = (_u16)writesds->fd_array[0]; 01129 } 01130 if( NULL == timeout ) 01131 { 01132 Msg.Cmd.tv_sec = 0xffff; 01133 Msg.Cmd.tv_usec = 0xffff; 01134 } 01135 else 01136 { 01137 if( 0xffff <= timeout->tv_sec ) 01138 { 01139 Msg.Cmd.tv_sec = 0xffff; 01140 } 01141 else 01142 { 01143 Msg.Cmd.tv_sec = (_u16)timeout->tv_sec; 01144 } 01145 timeout->tv_usec = timeout->tv_usec >> 10; /* convert to milliseconds */ 01146 if( 0xffff <= timeout->tv_usec ) 01147 { 01148 Msg.Cmd.tv_usec = 0xffff; 01149 } 01150 else 01151 { 01152 Msg.Cmd.tv_usec = (_u16)timeout->tv_usec; 01153 } 01154 } 01155 01156 /* Use Obj to issue the command, if not available try later */ 01157 ObjIdx = _SlDrvProtectAsyncRespSetting((_u8*)&AsyncRsp, SELECT_ID, SL_MAX_SOCKETS); 01158 01159 if (MAX_CONCURRENT_ACTIONS == ObjIdx) 01160 { 01161 return SL_POOL_IS_EMPTY; 01162 } 01163 01164 01165 /* send the command */ 01166 VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSelectCmdCtrl, &Msg, NULL)); 01167 01168 if(SL_OS_RET_CODE_OK == (_i16)Msg.Rsp.status) 01169 { 01170 SL_DRV_SYNC_OBJ_WAIT_FOREVER(&g_pCB->ObjPool[ObjIdx].SyncObj); 01171 01172 Msg.Rsp.status = (_i16)AsyncRsp.status; 01173 01174 if( ((_i16)Msg.Rsp.status) >= 0 ) 01175 { 01176 if( readsds ) 01177 { 01178 readsds->fd_array[0] = AsyncRsp.readFds; 01179 } 01180 if( writesds ) 01181 { 01182 writesds->fd_array[0] = AsyncRsp.writeFds; 01183 } 01184 } 01185 } 01186 01187 _SlDrvReleasePoolObj(ObjIdx); 01188 return (_i16)Msg.Rsp.status; 01189 } 01190 01191 /* Select helper functions */ 01192 /*******************************************************************************/ 01193 /* SL_FD_SET */ 01194 /* ******************************************************************************/ 01195 void SL_FD_SET(_i16 fd, SlFdSet_t *fdset) 01196 { 01197 fdset->fd_array[0] |= (1<< (fd & BSD_SOCKET_ID_MASK)); 01198 } 01199 /*******************************************************************************/ 01200 /* SL_FD_CLR */ 01201 /*******************************************************************************/ 01202 void SL_FD_CLR(_i16 fd, SlFdSet_t *fdset) 01203 { 01204 fdset->fd_array[0] &= ~(1<< (fd & BSD_SOCKET_ID_MASK)); 01205 } 01206 /*******************************************************************************/ 01207 /* SL_FD_ISSET */ 01208 /*******************************************************************************/ 01209 _i16 SL_FD_ISSET(_i16 fd, SlFdSet_t *fdset) 01210 { 01211 if( fdset->fd_array[0] & (1<< (fd & BSD_SOCKET_ID_MASK)) ) 01212 { 01213 return 1; 01214 } 01215 return 0; 01216 } 01217 /*******************************************************************************/ 01218 /* SL_FD_ZERO */ 01219 /*******************************************************************************/ 01220 void SL_FD_ZERO(SlFdSet_t *fdset) 01221 { 01222 fdset->fd_array[0] = 0; 01223 } 01224 01225 #endif 01226 #endif 01227 01228 01229
Generated on Tue Jul 12 2022 12:06:49 by 1.7.2