Update revision to use TI's mqtt and Freertos.
Dependencies: mbed client server
Fork of cc3100_Test_mqtt_CM3 by
cc3100_socket.cpp
00001 /* 00002 * socket.c - CC31xx/CC32xx Host Driver Implementation 00003 * 00004 * Copyright (C) 2014 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 "cc3100_simplelink.h" 00044 #include "cc3100_protocol.h" 00045 #include "cc3100_driver.h" 00046 00047 #include "cc3100_socket.h" 00048 00049 namespace mbed_cc3100 { 00050 00051 /* Note: parsing of family and port in the generic way for all IPV4, IPV6 and EUI48 */ 00052 /* is possible as _i32 as these parameters are in the same offset and size for these */ 00053 /* three families. */ 00054 #define SL_SOCKET_PAYLOAD_BASE (1350) 00055 00056 const uint8_t _SlPayloadByProtocolLUT[16] = 00057 { 00058 (1472 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_UDP_IPV4 */ 00059 (1460 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_TCP_IPV4 */ 00060 (1452 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_UDP_IPV6 */ 00061 (1440 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_TCP_IPV6 */ 00062 (1386 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_TCP_IPV4_SECURE */ 00063 (1386 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_UDP_IPV4_SECURE */ 00064 (1396 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_UDP_IPV6_SECURE */ 00065 (1396 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_TCP_IPV6_SECURE */ 00066 (1476 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_RAW_TRANCEIVER */ 00067 (1514 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_RAW_PACKET */ 00068 (1480 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_RAW_IP4 */ 00069 (1480 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_RAW_IP6 */ 00070 (1440 - SL_SOCKET_PAYLOAD_BASE), /* Default */ 00071 (1440 - SL_SOCKET_PAYLOAD_BASE), /* Default */ 00072 (1440 - SL_SOCKET_PAYLOAD_BASE), /* Default */ 00073 (1440 - SL_SOCKET_PAYLOAD_BASE) /* Default */ 00074 }; 00075 00076 00077 cc3100_socket::cc3100_socket(cc3100_driver &driver, cc3100_nonos &nonos) 00078 : _driver(driver), _nonos(nonos) 00079 { 00080 00081 } 00082 00083 cc3100_socket::~cc3100_socket() 00084 { 00085 00086 } 00087 00088 /*******************************************************************************/ 00089 /* Functions */ 00090 /*******************************************************************************/ 00091 00092 /* ******************************************************************************/ 00093 /* _sl_BuildAddress */ 00094 /* ******************************************************************************/ 00095 void cc3100_socket::_sl_BuildAddress(const SlSockAddr_t *addr, _SocketAddrCommand_u *pCmd) 00096 { 00097 /* Note: parsing of family and port in the generic way for all IPV4, IPV6 and EUI48 00098 is possible as long as these parameters are in the same offset and size for these 00099 three families. */ 00100 pCmd->IpV4.FamilyAndFlags = (addr->sa_family << 4) & 0xF0; 00101 pCmd->IpV4.port = ((SlSockAddrIn_t *)addr)->sin_port; 00102 00103 if(SL_AF_INET == addr->sa_family) { 00104 pCmd->IpV4.address = ((SlSockAddrIn_t *)addr)->sin_addr.s_addr; 00105 } else if (SL_AF_INET6_EUI_48 == addr->sa_family ) { 00106 memcpy( pCmd->IpV6EUI48.address,((SlSockAddrIn6_t *)addr)->sin6_addr._S6_un._S6_u8, 6); 00107 } 00108 #ifdef SL_SUPPORT_IPV6 00109 else { 00110 memcpy(pCmd->IpV6.address, ((sockaddr_in6 *)addr)->sin6_addr._S6_un._S6_u32, 16 ); 00111 } 00112 #endif 00113 } 00114 00115 /* ******************************************************************************/ 00116 /* _sl_TruncatePayloadByProtocol */ 00117 /* ******************************************************************************/ 00118 uint16_t cc3100_socket::_sl_TruncatePayloadByProtocol(const int16_t sd,const uint16_t length) 00119 { 00120 00121 uint32_t maxLength; 00122 00123 maxLength = SL_SOCKET_PAYLOAD_BASE + _SlPayloadByProtocolLUT[((sd & SL_SOCKET_PAYLOAD_TYPE_MASK) >> 4)]; 00124 00125 if( length > maxLength ) 00126 { 00127 return maxLength; 00128 } 00129 else 00130 { 00131 return length; 00132 } 00133 00134 } 00135 00136 /*******************************************************************************/ 00137 /* _sl_ParseAddress */ 00138 /*******************************************************************************/ 00139 #ifndef SL_TINY_EXT 00140 void cc3100_socket::_sl_ParseAddress(_SocketAddrResponse_u *pRsp, SlSockAddr_t *addr, SlSocklen_t *addrlen) 00141 { 00142 /* Note: parsing of family and port in the generic way for all IPV4, IPV6 and EUI48 */ 00143 /* is possible as long as these parameters are in the same offset and size for these */ 00144 /* three families. */ 00145 addr->sa_family = pRsp->IpV4.family; 00146 ((SlSockAddrIn_t *)addr)->sin_port = pRsp->IpV4.port; 00147 00148 *addrlen = (SL_AF_INET == addr->sa_family) ? sizeof(SlSockAddrIn_t) : sizeof(SlSockAddrIn6_t); 00149 00150 if(SL_AF_INET == addr->sa_family) { 00151 ((SlSockAddrIn_t *)addr)->sin_addr.s_addr = pRsp->IpV4.address; 00152 } else if (SL_AF_INET6_EUI_48 == addr->sa_family ) { 00153 memcpy(((SlSockAddrIn6_t *)addr)->sin6_addr._S6_un._S6_u8, pRsp->IpV6EUI48.address, 6); 00154 } 00155 #ifdef SL_SUPPORT_IPV6 00156 else { 00157 memcpy(((sockaddr_in6 *)addr)->sin6_addr._S6_un._S6_u32, pRsp->IpV6.address, 16); 00158 } 00159 #endif 00160 } 00161 #endif 00162 00163 /*******************************************************************************/ 00164 /* sl_Socket */ 00165 /*******************************************************************************/ 00166 typedef union { 00167 uint32_t Dummy; 00168 _SocketCommand_t Cmd; 00169 _SocketResponse_t Rsp; 00170 } _SlSockSocketMsg_u; 00171 00172 #if _SL_INCLUDE_FUNC(sl_Socket) 00173 const _SlCmdCtrl_t _SlSockSocketCmdCtrl = { 00174 SL_OPCODE_SOCKET_SOCKET, 00175 sizeof(_SocketCommand_t), 00176 sizeof(_SocketResponse_t) 00177 }; 00178 00179 int16_t cc3100_socket::sl_Socket(int16_t Domain, int16_t Type, int16_t Protocol) 00180 { 00181 _SlSockSocketMsg_u Msg; 00182 00183 Msg.Cmd.Domain = (uint8_t)Domain; 00184 Msg.Cmd.Type = (uint8_t)Type; 00185 Msg.Cmd.Protocol = (uint8_t)Protocol; 00186 00187 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSockSocketCmdCtrl, &Msg, NULL)); 00188 00189 if( Msg.Rsp.statusOrLen < 0 ) { 00190 return( Msg.Rsp.statusOrLen ); 00191 } else { 00192 return (int16_t)((uint8_t)Msg.Rsp.sd); 00193 } 00194 } 00195 #endif 00196 00197 /*******************************************************************************/ 00198 /* sl_Close */ 00199 /*******************************************************************************/ 00200 typedef union { 00201 _CloseCommand_t Cmd; 00202 _SocketResponse_t Rsp; 00203 } _SlSockCloseMsg_u; 00204 00205 #if _SL_INCLUDE_FUNC(sl_Close) 00206 const _SlCmdCtrl_t _SlSockCloseCmdCtrl = { 00207 SL_OPCODE_SOCKET_CLOSE, 00208 sizeof(_CloseCommand_t), 00209 sizeof(_SocketResponse_t) 00210 }; 00211 00212 int16_t cc3100_socket::sl_Close(int16_t sd) 00213 { 00214 _SlSockCloseMsg_u Msg; 00215 00216 Msg.Cmd.sd = (uint8_t)sd; 00217 00218 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSockCloseCmdCtrl, &Msg, NULL)); 00219 00220 return Msg.Rsp.statusOrLen; 00221 } 00222 #endif 00223 00224 /*******************************************************************************/ 00225 /* sl_Bind */ 00226 /*******************************************************************************/ 00227 typedef union { 00228 _SocketAddrCommand_u Cmd; 00229 _SocketResponse_t Rsp; 00230 } _SlSockBindMsg_u; 00231 00232 #if _SL_INCLUDE_FUNC(sl_Bind) 00233 int16_t cc3100_socket::sl_Bind(int16_t sd, const SlSockAddr_t *addr, int16_t addrlen) 00234 { 00235 _SlSockBindMsg_u Msg; 00236 _SlCmdCtrl_t CmdCtrl = {0, 0, sizeof(_SocketResponse_t)}; 00237 00238 switch(addr->sa_family) { 00239 case SL_AF_INET : 00240 CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND; 00241 CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv4Command_t); 00242 break; 00243 #ifndef SL_TINY_EXT 00244 case SL_AF_INET6_EUI_48: 00245 CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND_V6; 00246 CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6EUI48Command_t); 00247 break; 00248 #ifdef SL_SUPPORT_IPV6 00249 case AF_INET6: 00250 CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND_V6; 00251 CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6Command_t); 00252 break; 00253 #endif 00254 #endif 00255 case SL_AF_RF : 00256 default: 00257 return SL_RET_CODE_INVALID_INPUT; 00258 } 00259 00260 Msg.Cmd.IpV4.lenOrPadding = 0; 00261 Msg.Cmd.IpV4.sd = (uint8_t)sd; 00262 00263 _sl_BuildAddress(addr, &Msg.Cmd); 00264 00265 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, &Msg, NULL)); 00266 00267 return Msg.Rsp.statusOrLen; 00268 } 00269 #endif 00270 00271 /*******************************************************************************/ 00272 /* sl_Sendto */ 00273 /*******************************************************************************/ 00274 typedef union { 00275 _SocketAddrCommand_u Cmd; 00276 /* no response for 'sendto' commands*/ 00277 } _SlSendtoMsg_u; 00278 00279 #if _SL_INCLUDE_FUNC(sl_SendTo) 00280 int16_t cc3100_socket::sl_SendTo(int16_t sd, const void *pBuf, int16_t Len, int16_t flags, const SlSockAddr_t *to, SlSocklen_t tolen) 00281 { 00282 _SlSendtoMsg_u Msg; 00283 _SlCmdCtrl_t CmdCtrl = {0, 0, 0}; 00284 _SlCmdExt_t CmdExt; 00285 uint16_t ChunkLen; 00286 int16_t RetVal; 00287 00288 _driver._SlDrvResetCmdExt(&CmdExt); 00289 CmdExt.TxPayloadLen = (uint16_t)Len; 00290 CmdExt.pTxPayload = (uint8_t *)pBuf; 00291 00292 switch(to->sa_family) { 00293 case SL_AF_INET: 00294 CmdCtrl.Opcode = SL_OPCODE_SOCKET_SENDTO; 00295 CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv4Command_t); 00296 break; 00297 #ifndef SL_TINY_EXT 00298 case SL_AF_INET6_EUI_48: 00299 CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND_V6; 00300 CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6EUI48Command_t); 00301 break; 00302 #ifdef SL_SUPPORT_IPV6 00303 case AF_INET6: 00304 CmdCtrl.Opcode = SL_OPCODE_SOCKET_SENDTO_V6; 00305 CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6Command_t); 00306 break; 00307 #endif 00308 #endif 00309 case SL_AF_RF: 00310 default: 00311 return SL_RET_CODE_INVALID_INPUT; 00312 } 00313 00314 ChunkLen = _sl_TruncatePayloadByProtocol(sd,Len); 00315 Msg.Cmd.IpV4.lenOrPadding = ChunkLen; 00316 CmdExt.TxPayloadLen = ChunkLen; 00317 00318 Msg.Cmd.IpV4.sd = (unsigned char)sd; 00319 00320 _sl_BuildAddress(to, &Msg.Cmd); 00321 00322 Msg.Cmd.IpV4.FamilyAndFlags |= flags & 0x0F; 00323 00324 do { 00325 RetVal = _driver._SlDrvDataWriteOp((_SlSd_t)sd, &CmdCtrl, &Msg, &CmdExt); 00326 00327 if(SL_OS_RET_CODE_OK == RetVal) { 00328 CmdExt.pTxPayload += ChunkLen; 00329 ChunkLen = (uint16_t)((unsigned char *)pBuf + Len - CmdExt.pTxPayload); 00330 ChunkLen = _sl_TruncatePayloadByProtocol(sd,ChunkLen); 00331 CmdExt.TxPayloadLen = ChunkLen; 00332 Msg.Cmd.IpV4.lenOrPadding = ChunkLen; 00333 } else { 00334 return RetVal; 00335 } 00336 } while(ChunkLen > 0); 00337 00338 return (int16_t)Len; 00339 } 00340 #endif 00341 00342 /*******************************************************************************/ 00343 /* sl_Recvfrom */ 00344 /*******************************************************************************/ 00345 typedef union { 00346 _sendRecvCommand_t Cmd; 00347 _SocketAddrResponse_u Rsp; 00348 } _SlRecvfromMsg_u; 00349 00350 const _SlCmdCtrl_t _SlRecvfomCmdCtrl = { 00351 SL_OPCODE_SOCKET_RECVFROM, 00352 sizeof(_sendRecvCommand_t), 00353 sizeof(_SocketAddrResponse_u) 00354 }; 00355 00356 #if _SL_INCLUDE_FUNC(sl_RecvFrom) 00357 int16_t cc3100_socket::sl_RecvFrom(int16_t sd, void *buf, int16_t Len, int16_t flags, SlSockAddr_t *from, SlSocklen_t *fromlen) 00358 { 00359 _SlRecvfromMsg_u Msg; 00360 _SlCmdExt_t CmdExt; 00361 int16_t RetVal; 00362 00363 _driver._SlDrvResetCmdExt(&CmdExt); 00364 CmdExt.RxPayloadLen = Len; 00365 CmdExt.pRxPayload = (uint8_t *)buf; 00366 00367 Msg.Cmd.sd = (uint8_t)sd; 00368 Msg.Cmd.StatusOrLen = Len; 00369 /* no size truncation in recv path */ 00370 CmdExt.RxPayloadLen = Msg.Cmd.StatusOrLen; 00371 00372 Msg.Cmd.FamilyAndFlags = flags & 0x0F; 00373 00374 if(sizeof(SlSockAddrIn_t) == *fromlen) { 00375 Msg.Cmd.FamilyAndFlags |= (SL_AF_INET << 4); 00376 } 00377 else if (sizeof(SlSockAddrIn6_t) == *fromlen) 00378 { 00379 Msg.Cmd.FamilyAndFlags |= (SL_AF_INET6 << 4); 00380 } 00381 else 00382 { 00383 return SL_RET_CODE_INVALID_INPUT; 00384 } 00385 00386 RetVal = _driver._SlDrvDataReadOp((_SlSd_t)sd, (_SlCmdCtrl_t *)&_SlRecvfomCmdCtrl, &Msg, &CmdExt); 00387 00388 if( RetVal != SL_OS_RET_CODE_OK ) { 00389 return RetVal; 00390 } 00391 00392 RetVal = Msg.Rsp.IpV4.statusOrLen; 00393 00394 if(RetVal >= 0) { 00395 VERIFY_PROTOCOL(sd == Msg.Rsp.IpV4.sd); 00396 #if 0 00397 _sl_ParseAddress(&Msg.Rsp, from, fromlen); 00398 #else 00399 from->sa_family = Msg.Rsp.IpV4.family; 00400 if(SL_AF_INET == from->sa_family) { 00401 ((SlSockAddrIn_t *)from)->sin_port = Msg.Rsp.IpV4.port; 00402 ((SlSockAddrIn_t *)from)->sin_addr.s_addr = Msg.Rsp.IpV4.address; 00403 *fromlen = sizeof(SlSockAddrIn_t); 00404 } else if (SL_AF_INET6_EUI_48 == from->sa_family ) { 00405 ((SlSockAddrIn6_t *)from)->sin6_port = Msg.Rsp.IpV6EUI48.port; 00406 memcpy(((SlSockAddrIn6_t *)from)->sin6_addr._S6_un._S6_u8, Msg.Rsp.IpV6EUI48.address, 6); 00407 } 00408 #ifdef SL_SUPPORT_IPV6 00409 else if(AF_INET6 == from->sa_family) { 00410 VERIFY_PROTOCOL(*fromlen >= sizeof(sockaddr_in6)); 00411 00412 ((sockaddr_in6 *)from)->sin6_port = Msg.Rsp.IpV6.port; 00413 memcpy(((sockaddr_in6 *)from)->sin6_addr._S6_un._S6_u32, Msg.Rsp.IpV6.address, 16); 00414 *fromlen = sizeof(sockaddr_in6); 00415 } 00416 #endif 00417 #endif 00418 } 00419 00420 return (int16_t)RetVal; 00421 } 00422 #endif 00423 00424 /*******************************************************************************/ 00425 /* sl_Connect */ 00426 /*******************************************************************************/ 00427 typedef union { 00428 _SocketAddrCommand_u Cmd; 00429 _SocketResponse_t Rsp; 00430 } _SlSockConnectMsg_u; 00431 00432 #if _SL_INCLUDE_FUNC(sl_Connect) 00433 int16_t cc3100_socket::sl_Connect(int16_t sd, const SlSockAddr_t *addr, int16_t addrlen) 00434 { 00435 _SlSockConnectMsg_u Msg; 00436 _SlReturnVal_t RetVal; 00437 _SlCmdCtrl_t CmdCtrl = {0, 0, sizeof(_SocketResponse_t)}; 00438 _SocketResponse_t AsyncRsp; 00439 uint8_t ObjIdx = MAX_CONCURRENT_ACTIONS; 00440 00441 00442 switch(addr->sa_family) { 00443 case SL_AF_INET : 00444 CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT; 00445 CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv4Command_t); 00446 /* Do nothing - cmd already initialized to this type */ 00447 break; 00448 case SL_AF_INET6_EUI_48: 00449 CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT_V6; 00450 CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6EUI48Command_t); 00451 break; 00452 #ifdef SL_SUPPORT_IPV6 00453 case AF_INET6: 00454 CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT_V6; 00455 CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6Command_t); 00456 break; 00457 #endif 00458 case SL_AF_RF : 00459 default: 00460 return SL_RET_CODE_INVALID_INPUT; 00461 } 00462 00463 Msg.Cmd.IpV4.lenOrPadding = 0; 00464 Msg.Cmd.IpV4.sd = (uint8_t)sd; 00465 00466 _sl_BuildAddress(addr, &Msg.Cmd); 00467 00468 00469 ObjIdx = _driver._SlDrvProtectAsyncRespSetting((uint8_t*)&AsyncRsp, CONNECT_ID, sd & BSD_SOCKET_ID_MASK); 00470 00471 if (MAX_CONCURRENT_ACTIONS == ObjIdx) 00472 { 00473 return SL_POOL_IS_EMPTY; 00474 } 00475 00476 /* send the command */ 00477 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, &Msg, NULL)); 00478 VERIFY_PROTOCOL(Msg.Rsp.sd == sd) 00479 00480 RetVal = Msg.Rsp.statusOrLen; 00481 00482 if(SL_RET_CODE_OK == RetVal) { 00483 /* wait for async and get Data Read parameters */ 00484 _driver._SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj); 00485 00486 VERIFY_PROTOCOL(AsyncRsp.sd == sd); 00487 00488 RetVal = AsyncRsp.statusOrLen; 00489 } 00490 _driver._SlDrvReleasePoolObj(ObjIdx); 00491 return RetVal; 00492 } 00493 #endif 00494 00495 /*******************************************************************************/ 00496 /* sl_Send */ 00497 /*******************************************************************************/ 00498 typedef union { 00499 _sendRecvCommand_t Cmd; 00500 /* no response for 'sendto' commands*/ 00501 } _SlSendMsg_u; 00502 00503 const _SlCmdCtrl_t _SlSendCmdCtrl = { 00504 SL_OPCODE_SOCKET_SEND, 00505 sizeof(_sendRecvCommand_t), 00506 0 00507 }; 00508 00509 #if _SL_INCLUDE_FUNC(sl_Send) 00510 int16_t cc3100_socket::sl_Send(int16_t sd, const void *pBuf, int16_t Len, int16_t flags) 00511 { 00512 _SlSendMsg_u Msg; 00513 _SlCmdExt_t CmdExt; 00514 uint16_t ChunkLen; 00515 int16_t RetVal; 00516 uint32_t tempVal; 00517 uint8_t runSingleChunk = FALSE; 00518 00519 _driver._SlDrvResetCmdExt(&CmdExt); 00520 CmdExt.TxPayloadLen = Len; 00521 CmdExt.pTxPayload = (uint8_t *)pBuf; 00522 00523 /* Only for RAW transceiver type socket, relay the flags parameter in the 2 bytes (4 byte aligned) before the actual payload */ 00524 if ((sd & SL_SOCKET_PAYLOAD_TYPE_MASK) == SL_SOCKET_PAYLOAD_TYPE_RAW_TRANCEIVER) { 00525 tempVal = flags; 00526 CmdExt.pRxPayload = (uint8_t *)&tempVal; 00527 CmdExt.RxPayloadLen = -4; /* mark as Rx data to send */ 00528 runSingleChunk = TRUE; 00529 } else { 00530 CmdExt.pRxPayload = NULL; 00531 } 00532 00533 ChunkLen = _sl_TruncatePayloadByProtocol(sd,Len); 00534 CmdExt.TxPayloadLen = ChunkLen; 00535 00536 Msg.Cmd.StatusOrLen = ChunkLen; 00537 Msg.Cmd.sd = (uint8_t)sd; 00538 Msg.Cmd.FamilyAndFlags |= flags & 0x0F; 00539 00540 do { 00541 RetVal = _driver._SlDrvDataWriteOp((uint8_t)sd, (_SlCmdCtrl_t *)&_SlSendCmdCtrl, &Msg, &CmdExt); 00542 if(SL_OS_RET_CODE_OK == RetVal) { 00543 CmdExt.pTxPayload += ChunkLen; 00544 ChunkLen = (uint8_t *)pBuf + Len - CmdExt.pTxPayload; 00545 ChunkLen = _sl_TruncatePayloadByProtocol(sd,ChunkLen); 00546 CmdExt.TxPayloadLen = ChunkLen; 00547 Msg.Cmd.StatusOrLen = ChunkLen; 00548 } else { 00549 return RetVal; 00550 } 00551 } while((ChunkLen > 0) && (runSingleChunk==FALSE)); 00552 00553 return (int16_t)Len; 00554 } 00555 #endif 00556 00557 /*******************************************************************************/ 00558 /* sl_Listen */ 00559 /*******************************************************************************/ 00560 typedef union { 00561 _ListenCommand_t Cmd; 00562 _BasicResponse_t Rsp; 00563 } _SlListenMsg_u; 00564 00565 #if _SL_INCLUDE_FUNC(sl_Listen) 00566 const _SlCmdCtrl_t _SlListenCmdCtrl = { 00567 SL_OPCODE_SOCKET_LISTEN, 00568 sizeof(_ListenCommand_t), 00569 sizeof(_BasicResponse_t), 00570 }; 00571 00572 int16_t cc3100_socket::sl_Listen(int16_t sd, int16_t backlog) 00573 { 00574 _SlListenMsg_u Msg; 00575 00576 Msg.Cmd.sd = (uint8_t)sd; 00577 Msg.Cmd.backlog = (uint8_t)backlog; 00578 00579 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlListenCmdCtrl, &Msg, NULL)); 00580 00581 return (int16_t)Msg.Rsp.status; 00582 } 00583 #endif 00584 00585 /*******************************************************************************/ 00586 /* sl_Accept */ 00587 /*******************************************************************************/ 00588 typedef union { 00589 _AcceptCommand_t Cmd; 00590 _SocketResponse_t Rsp; 00591 } _SlSockAcceptMsg_u; 00592 00593 #if _SL_INCLUDE_FUNC(sl_Accept) 00594 const _SlCmdCtrl_t _SlAcceptCmdCtrl = { 00595 SL_OPCODE_SOCKET_ACCEPT, 00596 sizeof(_AcceptCommand_t), 00597 sizeof(_BasicResponse_t), 00598 }; 00599 00600 int16_t cc3100_socket::sl_Accept(int16_t sd, SlSockAddr_t *addr, SlSocklen_t *addrlen) 00601 { 00602 _SlSockAcceptMsg_u Msg; 00603 _SlReturnVal_t RetVal; 00604 _SocketAddrResponse_u AsyncRsp; 00605 00606 uint8_t ObjIdx = MAX_CONCURRENT_ACTIONS; 00607 00608 00609 Msg.Cmd.sd = (uint8_t)sd; 00610 Msg.Cmd.family = (sizeof(SlSockAddrIn_t) == *addrlen) ? SL_AF_INET : SL_AF_INET6; 00611 00612 ObjIdx = _driver._SlDrvProtectAsyncRespSetting((uint8_t*)&AsyncRsp, ACCEPT_ID, sd & BSD_SOCKET_ID_MASK ); 00613 00614 if (MAX_CONCURRENT_ACTIONS == ObjIdx) 00615 { 00616 return SL_POOL_IS_EMPTY; 00617 } 00618 00619 /* send the command */ 00620 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlAcceptCmdCtrl, &Msg, NULL)); 00621 VERIFY_PROTOCOL(Msg.Rsp.sd == sd); 00622 00623 RetVal = Msg.Rsp.statusOrLen; 00624 00625 if(SL_OS_RET_CODE_OK == RetVal) { 00626 /* wait for async and get Data Read parameters */ 00627 _driver._SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj); 00628 00629 VERIFY_PROTOCOL(AsyncRsp.IpV4.sd == sd); 00630 00631 RetVal = AsyncRsp.IpV4.statusOrLen; 00632 if( (NULL != addr) && (NULL != addrlen) ) { 00633 #if 0 /* Kept for backup */ 00634 _sl_ParseAddress(&AsyncRsp, addr, addrlen); 00635 #else 00636 addr->sa_family = AsyncRsp.IpV4.family; 00637 00638 if(SL_AF_INET == addr->sa_family) { 00639 if( *addrlen == sizeof( SlSockAddrIn_t ) ) { 00640 ((SlSockAddrIn_t *)addr)->sin_port = AsyncRsp.IpV4.port; 00641 ((SlSockAddrIn_t *)addr)->sin_addr.s_addr = AsyncRsp.IpV4.address; 00642 } else { 00643 *addrlen = 0; 00644 } 00645 } else if (SL_AF_INET6_EUI_48 == addr->sa_family ) { 00646 if( *addrlen == sizeof( SlSockAddrIn6_t ) ) { 00647 ((SlSockAddrIn6_t *)addr)->sin6_port = AsyncRsp.IpV6EUI48.port ; 00648 /* will be called from here and from _sl_BuildAddress*/ 00649 memcpy(((SlSockAddrIn6_t *)addr)->sin6_addr._S6_un._S6_u8, AsyncRsp.IpV6EUI48.address, 6); 00650 } else { 00651 *addrlen = 0; 00652 } 00653 } 00654 #ifdef SL_SUPPORT_IPV6 00655 else { 00656 if( *addrlen == sizeof( sockaddr_in6 ) ) { 00657 ((sockaddr_in6 *)addr)->sin6_port = AsyncRsp.IpV6.port ; 00658 memcpy(((sockaddr_in6 *)addr)->sin6_addr._S6_un._S6_u32, AsyncRsp.IpV6.address, 16); 00659 } else { 00660 *addrlen = 0; 00661 } 00662 } 00663 #endif 00664 #endif 00665 } 00666 } 00667 00668 _driver._SlDrvReleasePoolObj(ObjIdx); 00669 return (int16_t)RetVal; 00670 } 00671 #endif 00672 00673 00674 /*******************************************************************************/ 00675 /* sl_Htonl */ 00676 /*******************************************************************************/ 00677 uint32_t cc3100_socket::sl_Htonl( uint32_t val ) 00678 { 00679 uint32_t i = 1; 00680 int8_t *p = (int8_t *)&i; 00681 if (p[0] == 1) { /* little endian */ 00682 p[0] = ((int8_t* )&val)[3]; 00683 p[1] = ((int8_t* )&val)[2]; 00684 p[2] = ((int8_t* )&val)[1]; 00685 p[3] = ((int8_t* )&val)[0]; 00686 return i; 00687 } else { /* big endian */ 00688 return val; 00689 } 00690 } 00691 00692 /*******************************************************************************/ 00693 /* sl_Htonl */ 00694 /*******************************************************************************/ 00695 uint16_t cc3100_socket::sl_Htons( uint16_t val ) 00696 { 00697 int16_t i = 1; 00698 int8_t *p = (int8_t *)&i; 00699 if (p[0] == 1) { /* little endian */ 00700 p[0] = ((int8_t* )&val)[1]; 00701 p[1] = ((int8_t* )&val)[0]; 00702 return i; 00703 } else { /* big endian */ 00704 return val; 00705 } 00706 } 00707 00708 /*******************************************************************************/ 00709 /* sl_Recv */ 00710 /*******************************************************************************/ 00711 typedef union { 00712 _sendRecvCommand_t Cmd; 00713 _SocketResponse_t Rsp; 00714 } _SlRecvMsg_u; 00715 00716 #if _SL_INCLUDE_FUNC(sl_Recv) 00717 const _SlCmdCtrl_t _SlRecvCmdCtrl = { 00718 SL_OPCODE_SOCKET_RECV, 00719 sizeof(_sendRecvCommand_t), 00720 sizeof(_SocketResponse_t) 00721 }; 00722 00723 int16_t cc3100_socket::sl_Recv(int16_t sd, void *pBuf, int16_t Len, int16_t flags) 00724 { 00725 _SlRecvMsg_u Msg; 00726 _SlCmdExt_t CmdExt; 00727 _SlReturnVal_t status; 00728 00729 _driver._SlDrvResetCmdExt(&CmdExt); 00730 CmdExt.RxPayloadLen = Len; 00731 CmdExt.pRxPayload = (uint8_t *)pBuf; 00732 00733 Msg.Cmd.sd = (uint8_t)sd; 00734 Msg.Cmd.StatusOrLen = Len; 00735 00736 /* no size truncation in recv path */ 00737 CmdExt.RxPayloadLen = Msg.Cmd.StatusOrLen; 00738 00739 Msg.Cmd.FamilyAndFlags = flags & 0x0F; 00740 00741 status = _driver._SlDrvDataReadOp((_SlSd_t)sd, (_SlCmdCtrl_t *)&_SlRecvCmdCtrl, &Msg, &CmdExt); 00742 if( status != SL_OS_RET_CODE_OK ) { 00743 return status; 00744 } 00745 00746 /* if the Device side sends less than expected it is not the Driver's role */ 00747 /* the returned value could be smaller than the requested size */ 00748 return (int16_t)Msg.Rsp.statusOrLen; 00749 } 00750 #endif 00751 00752 /*******************************************************************************/ 00753 /* sl_SetSockOpt */ 00754 /*******************************************************************************/ 00755 typedef union { 00756 _setSockOptCommand_t Cmd; 00757 _SocketResponse_t Rsp; 00758 } _SlSetSockOptMsg_u; 00759 00760 const _SlCmdCtrl_t _SlSetSockOptCmdCtrl = { 00761 SL_OPCODE_SOCKET_SETSOCKOPT, 00762 sizeof(_setSockOptCommand_t), 00763 sizeof(_SocketResponse_t) 00764 }; 00765 00766 #if _SL_INCLUDE_FUNC(sl_SetSockOpt) 00767 int16_t cc3100_socket::sl_SetSockOpt(int16_t sd, int16_t level, int16_t optname, const void *optval, SlSocklen_t optlen) 00768 { 00769 _SlSetSockOptMsg_u Msg; 00770 _SlCmdExt_t CmdExt; 00771 00772 _driver._SlDrvResetCmdExt(&CmdExt); 00773 CmdExt.TxPayloadLen = optlen; 00774 CmdExt.pTxPayload = (uint8_t *)optval; 00775 00776 Msg.Cmd.sd = (uint8_t)sd; 00777 Msg.Cmd.level = (uint8_t)level; 00778 Msg.Cmd.optionLen = (uint8_t)optlen; 00779 Msg.Cmd.optionName = (uint8_t)optname; 00780 00781 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSetSockOptCmdCtrl, &Msg, &CmdExt)); 00782 00783 return (int16_t)Msg.Rsp.statusOrLen; 00784 } 00785 #endif 00786 00787 /*******************************************************************************/ 00788 /* sl_GetSockOpt */ 00789 /*******************************************************************************/ 00790 typedef union { 00791 _getSockOptCommand_t Cmd; 00792 _getSockOptResponse_t Rsp; 00793 } _SlGetSockOptMsg_u; 00794 00795 #if _SL_INCLUDE_FUNC(sl_GetSockOpt) 00796 const _SlCmdCtrl_t _SlGetSockOptCmdCtrl = { 00797 SL_OPCODE_SOCKET_GETSOCKOPT, 00798 sizeof(_getSockOptCommand_t), 00799 sizeof(_getSockOptResponse_t) 00800 }; 00801 00802 int16_t cc3100_socket::sl_GetSockOpt(int16_t sd, int16_t level, int16_t optname, void *optval, SlSocklen_t *optlen) 00803 { 00804 _SlGetSockOptMsg_u Msg; 00805 _SlCmdExt_t CmdExt; 00806 00807 if (*optlen == 0) { 00808 return SL_EZEROLEN; 00809 } 00810 00811 _driver._SlDrvResetCmdExt(&CmdExt); 00812 CmdExt.RxPayloadLen = *optlen; 00813 CmdExt.pRxPayload = (uint8_t*)optval; 00814 00815 Msg.Cmd.sd = (uint8_t)sd; 00816 Msg.Cmd.level = (uint8_t)level; 00817 Msg.Cmd.optionLen = (uint8_t)(*optlen); 00818 Msg.Cmd.optionName = (uint8_t)optname; 00819 00820 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlGetSockOptCmdCtrl, &Msg, &CmdExt)); 00821 00822 if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) { 00823 *optlen = Msg.Rsp.optionLen; 00824 return SL_ESMALLBUF; 00825 } else { 00826 *optlen = (uint8_t)CmdExt.ActualRxPayloadLen; 00827 } 00828 return (int16_t)Msg.Rsp.status; 00829 } 00830 #endif 00831 00832 /*******************************************************************************/ 00833 /* sl_Select */ 00834 /* ******************************************************************************/ 00835 typedef union { 00836 _SelectCommand_t Cmd; 00837 _BasicResponse_t Rsp; 00838 } _SlSelectMsg_u; 00839 00840 #ifndef SL_TINY_EXT 00841 #if _SL_INCLUDE_FUNC(sl_Select) 00842 const _SlCmdCtrl_t _SlSelectCmdCtrl = { 00843 SL_OPCODE_SOCKET_SELECT, 00844 sizeof(_SelectCommand_t), 00845 sizeof(_BasicResponse_t) 00846 }; 00847 00848 int16_t cc3100_socket::sl_Select(int16_t nfds, SlFdSet_t *readsds, SlFdSet_t *writesds, SlFdSet_t *exceptsds, SlTimeval_t *timeout) 00849 { 00850 _SlSelectMsg_u Msg; 00851 _SelectAsyncResponse_t AsyncRsp; 00852 uint8_t ObjIdx = MAX_CONCURRENT_ACTIONS; 00853 00854 Msg.Cmd.nfds = (uint8_t)nfds; 00855 Msg.Cmd.readFdsCount = 0; 00856 Msg.Cmd.writeFdsCount = 0; 00857 00858 Msg.Cmd.readFds = 0; 00859 Msg.Cmd.writeFds = 0; 00860 00861 if( readsds ) { 00862 Msg.Cmd.readFds = (uint16_t)readsds->fd_array[0]; 00863 } 00864 if( writesds ) { 00865 Msg.Cmd.writeFds = (uint16_t)writesds->fd_array[0]; 00866 } 00867 if( NULL == timeout ) { 00868 Msg.Cmd.tv_sec = 0xffff; 00869 Msg.Cmd.tv_usec = 0xffff; 00870 } else { 00871 if( 0xffff <= timeout->tv_sec ) { 00872 Msg.Cmd.tv_sec = 0xffff; 00873 } else { 00874 Msg.Cmd.tv_sec = (uint16_t)timeout->tv_sec; 00875 } 00876 timeout->tv_usec = timeout->tv_usec >> 10; /* convert to milliseconds */ 00877 if( 0xffff <= timeout->tv_usec ) { 00878 Msg.Cmd.tv_usec = 0xffff; 00879 } else { 00880 Msg.Cmd.tv_usec = (uint16_t)timeout->tv_usec; 00881 } 00882 } 00883 00884 /* Use Obj to issue the command, if not available try later */ 00885 ObjIdx = _driver._SlDrvProtectAsyncRespSetting((uint8_t*)&AsyncRsp, SELECT_ID, SL_MAX_SOCKETS); 00886 00887 if (MAX_CONCURRENT_ACTIONS == ObjIdx) 00888 { 00889 return SL_POOL_IS_EMPTY; 00890 } 00891 00892 /* send the command */ 00893 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSelectCmdCtrl, &Msg, NULL)); 00894 00895 if(SL_OS_RET_CODE_OK == (int16_t)Msg.Rsp.status) { 00896 _driver._SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj); 00897 Msg.Rsp.status = AsyncRsp.status; 00898 00899 if( ((int16_t)Msg.Rsp.status) >= 0 ) { 00900 if( readsds ) { 00901 readsds->fd_array[0] = AsyncRsp.readFds; 00902 } 00903 if( writesds ) { 00904 writesds->fd_array[0] = AsyncRsp.writeFds; 00905 } 00906 } 00907 } 00908 00909 _driver._SlDrvReleasePoolObj(ObjIdx); 00910 return (int16_t)Msg.Rsp.status; 00911 } 00912 00913 /* Select helper functions */ 00914 /*******************************************************************************/ 00915 /* SL_FD_SET */ 00916 /* ******************************************************************************/ 00917 void cc3100_socket::SL_FD_SET(int16_t fd, SlFdSet_t *fdset) 00918 { 00919 fdset->fd_array[0] |= (1<< (fd & BSD_SOCKET_ID_MASK)); 00920 } 00921 /*******************************************************************************/ 00922 /* SL_FD_CLR */ 00923 /*******************************************************************************/ 00924 void cc3100_socket::SL_FD_CLR(int16_t fd, SlFdSet_t *fdset) 00925 { 00926 fdset->fd_array[0] &= ~(1<< (fd & BSD_SOCKET_ID_MASK)); 00927 } 00928 /*******************************************************************************/ 00929 /* SL_FD_ISSET */ 00930 /*******************************************************************************/ 00931 int16_t cc3100_socket::SL_FD_ISSET(int16_t fd, SlFdSet_t *fdset) 00932 { 00933 if( fdset->fd_array[0] & (1<< (fd & BSD_SOCKET_ID_MASK)) ) { 00934 return 1; 00935 } 00936 return 0; 00937 } 00938 /*******************************************************************************/ 00939 /* SL_FD_ZERO */ 00940 /*******************************************************************************/ 00941 void cc3100_socket::SL_FD_ZERO(SlFdSet_t *fdset) 00942 { 00943 fdset->fd_array[0] = 0; 00944 } 00945 00946 #endif 00947 #endif 00948 00949 }//namespace mbed_cc3100 00950 00951 00952
Generated on Tue Jul 12 2022 18:55:10 by
1.7.2
