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