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