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