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