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.

Dependencies:   mbed

Committer:
dflet
Date:
Thu Sep 10 17:56:09 2015 +0000
Revision:
19:3dd3e7f30f8b
Parent:
0:50cedd586816
Solved part of the problem with spi, looks like there is maybe a fault with the Seeed Arch Max, fault or by design i don't know, program seems to work fine on an STMF32407I (Waveshare) baord.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dflet 0:50cedd586816 1 /*
dflet 0:50cedd586816 2 * socket.c - CC31xx/CC32xx Host Driver Implementation
dflet 0:50cedd586816 3 *
dflet 0:50cedd586816 4 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
dflet 0:50cedd586816 5 *
dflet 0:50cedd586816 6 *
dflet 0:50cedd586816 7 * Redistribution and use in source and binary forms, with or without
dflet 0:50cedd586816 8 * modification, are permitted provided that the following conditions
dflet 0:50cedd586816 9 * are met:
dflet 0:50cedd586816 10 *
dflet 0:50cedd586816 11 * Redistributions of source code must retain the above copyright
dflet 0:50cedd586816 12 * notice, this list of conditions and the following disclaimer.
dflet 0:50cedd586816 13 *
dflet 0:50cedd586816 14 * Redistributions in binary form must reproduce the above copyright
dflet 0:50cedd586816 15 * notice, this list of conditions and the following disclaimer in the
dflet 0:50cedd586816 16 * documentation and/or other materials provided with the
dflet 0:50cedd586816 17 * distribution.
dflet 0:50cedd586816 18 *
dflet 0:50cedd586816 19 * Neither the name of Texas Instruments Incorporated nor the names of
dflet 0:50cedd586816 20 * its contributors may be used to endorse or promote products derived
dflet 0:50cedd586816 21 * from this software without specific prior written permission.
dflet 0:50cedd586816 22 *
dflet 0:50cedd586816 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
dflet 0:50cedd586816 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
dflet 0:50cedd586816 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
dflet 0:50cedd586816 26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
dflet 0:50cedd586816 27 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
dflet 0:50cedd586816 28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
dflet 0:50cedd586816 29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
dflet 0:50cedd586816 30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
dflet 0:50cedd586816 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
dflet 0:50cedd586816 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
dflet 0:50cedd586816 33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dflet 0:50cedd586816 34 *
dflet 0:50cedd586816 35 */
dflet 0:50cedd586816 36
dflet 0:50cedd586816 37
dflet 0:50cedd586816 38
dflet 0:50cedd586816 39
dflet 0:50cedd586816 40 /*****************************************************************************/
dflet 0:50cedd586816 41 /* Include files */
dflet 0:50cedd586816 42 /*****************************************************************************/
dflet 0:50cedd586816 43 #include "cc3100_simplelink.h"
dflet 0:50cedd586816 44 #include "cc3100_protocol.h"
dflet 0:50cedd586816 45 #include "cc3100_driver.h"
dflet 0:50cedd586816 46
dflet 0:50cedd586816 47 #include "cc3100_socket.h"
dflet 0:50cedd586816 48 #include "HttpDebug.h"
dflet 0:50cedd586816 49
dflet 0:50cedd586816 50 namespace mbed_cc3100 {
dflet 0:50cedd586816 51
dflet 0:50cedd586816 52 /* Note: parsing of family and port in the generic way for all IPV4, IPV6 and EUI48 */
dflet 0:50cedd586816 53 /* is possible as _i32 as these parameters are in the same offset and size for these */
dflet 0:50cedd586816 54 /* three families. */
dflet 0:50cedd586816 55 #define SL_SOCKET_PAYLOAD_BASE (1350)
dflet 0:50cedd586816 56
dflet 0:50cedd586816 57 const uint8_t _SlPayloadByProtocolLUT[16] =
dflet 0:50cedd586816 58 {
dflet 0:50cedd586816 59 (1472 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_UDP_IPV4 */
dflet 0:50cedd586816 60 (1460 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_TCP_IPV4 */
dflet 0:50cedd586816 61 (1452 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_UDP_IPV6 */
dflet 0:50cedd586816 62 (1440 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_TCP_IPV6 */
dflet 0:50cedd586816 63 (1386 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_TCP_IPV4_SECURE */
dflet 0:50cedd586816 64 (1386 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_UDP_IPV4_SECURE */
dflet 0:50cedd586816 65 (1396 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_UDP_IPV6_SECURE */
dflet 0:50cedd586816 66 (1396 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_TCP_IPV6_SECURE */
dflet 0:50cedd586816 67 (1476 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_RAW_TRANCEIVER */
dflet 0:50cedd586816 68 (1514 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_RAW_PACKET */
dflet 0:50cedd586816 69 (1480 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_RAW_IP4 */
dflet 0:50cedd586816 70 (1480 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_RAW_IP6 */
dflet 0:50cedd586816 71 (1440 - SL_SOCKET_PAYLOAD_BASE), /* Default */
dflet 0:50cedd586816 72 (1440 - SL_SOCKET_PAYLOAD_BASE), /* Default */
dflet 0:50cedd586816 73 (1440 - SL_SOCKET_PAYLOAD_BASE), /* Default */
dflet 0:50cedd586816 74 (1440 - SL_SOCKET_PAYLOAD_BASE) /* Default */
dflet 0:50cedd586816 75 };
dflet 0:50cedd586816 76
dflet 19:3dd3e7f30f8b 77 //#ifndef SL_PLATFORM_MULTI_THREADED
dflet 19:3dd3e7f30f8b 78 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))
dflet 0:50cedd586816 79 cc3100_socket::cc3100_socket(cc3100_driver &driver, cc3100_nonos &nonos)
dflet 0:50cedd586816 80 : _driver(driver), _nonos(nonos)
dflet 0:50cedd586816 81 {
dflet 0:50cedd586816 82 }
dflet 0:50cedd586816 83 #else
dflet 0:50cedd586816 84 cc3100_socket::cc3100_socket(cc3100_driver &driver)
dflet 0:50cedd586816 85 : _driver(driver)
dflet 0:50cedd586816 86 {
dflet 0:50cedd586816 87 }
dflet 0:50cedd586816 88 #endif
dflet 0:50cedd586816 89 cc3100_socket::~cc3100_socket()
dflet 0:50cedd586816 90 {
dflet 0:50cedd586816 91
dflet 0:50cedd586816 92 }
dflet 0:50cedd586816 93
dflet 0:50cedd586816 94 /*******************************************************************************/
dflet 0:50cedd586816 95 /* Functions */
dflet 0:50cedd586816 96 /*******************************************************************************/
dflet 0:50cedd586816 97
dflet 0:50cedd586816 98 /* ******************************************************************************/
dflet 0:50cedd586816 99 /* _sl_BuildAddress */
dflet 0:50cedd586816 100 /* ******************************************************************************/
dflet 0:50cedd586816 101 void cc3100_socket::_sl_BuildAddress(const SlSockAddr_t *addr, _SocketAddrCommand_u *pCmd)
dflet 0:50cedd586816 102 {
dflet 0:50cedd586816 103 /* Note: parsing of family and port in the generic way for all IPV4, IPV6 and EUI48
dflet 0:50cedd586816 104 is possible as long as these parameters are in the same offset and size for these
dflet 0:50cedd586816 105 three families. */
dflet 0:50cedd586816 106 pCmd->IpV4.FamilyAndFlags = (addr->sa_family << 4) & 0xF0;
dflet 0:50cedd586816 107 pCmd->IpV4.port = ((SlSockAddrIn_t *)addr)->sin_port;
dflet 0:50cedd586816 108
dflet 0:50cedd586816 109 if(SL_AF_INET == addr->sa_family) {
dflet 0:50cedd586816 110 pCmd->IpV4.address = ((SlSockAddrIn_t *)addr)->sin_addr.s_addr;
dflet 0:50cedd586816 111 } else if (SL_AF_INET6_EUI_48 == addr->sa_family ) {
dflet 0:50cedd586816 112 memcpy( pCmd->IpV6EUI48.address,((SlSockAddrIn6_t *)addr)->sin6_addr._S6_un._S6_u8, 6);
dflet 0:50cedd586816 113 }
dflet 0:50cedd586816 114 #ifdef SL_SUPPORT_IPV6
dflet 0:50cedd586816 115 else {
dflet 0:50cedd586816 116 memcpy(pCmd->IpV6.address, ((sockaddr_in6 *)addr)->sin6_addr._S6_un._S6_u32, 16 );
dflet 0:50cedd586816 117 }
dflet 0:50cedd586816 118 #endif
dflet 0:50cedd586816 119 }
dflet 0:50cedd586816 120
dflet 0:50cedd586816 121 /* ******************************************************************************/
dflet 0:50cedd586816 122 /* _sl_TruncatePayloadByProtocol */
dflet 0:50cedd586816 123 /* ******************************************************************************/
dflet 0:50cedd586816 124 uint16_t cc3100_socket::_sl_TruncatePayloadByProtocol(const int16_t sd,const uint16_t length)
dflet 0:50cedd586816 125 {
dflet 0:50cedd586816 126
dflet 0:50cedd586816 127 uint32_t maxLength;
dflet 0:50cedd586816 128
dflet 0:50cedd586816 129 maxLength = SL_SOCKET_PAYLOAD_BASE + _SlPayloadByProtocolLUT[((sd & SL_SOCKET_PAYLOAD_TYPE_MASK) >> 4)];
dflet 0:50cedd586816 130
dflet 0:50cedd586816 131 if( length > maxLength )
dflet 0:50cedd586816 132 {
dflet 0:50cedd586816 133 return maxLength;
dflet 0:50cedd586816 134 }
dflet 0:50cedd586816 135 else
dflet 0:50cedd586816 136 {
dflet 0:50cedd586816 137 return length;
dflet 0:50cedd586816 138 }
dflet 0:50cedd586816 139
dflet 0:50cedd586816 140 }
dflet 0:50cedd586816 141
dflet 0:50cedd586816 142 /*******************************************************************************/
dflet 0:50cedd586816 143 /* _sl_ParseAddress */
dflet 0:50cedd586816 144 /*******************************************************************************/
dflet 0:50cedd586816 145 #ifndef SL_TINY_EXT
dflet 0:50cedd586816 146 void cc3100_socket::_sl_ParseAddress(_SocketAddrResponse_u *pRsp, SlSockAddr_t *addr, SlSocklen_t *addrlen)
dflet 0:50cedd586816 147 {
dflet 0:50cedd586816 148 /* Note: parsing of family and port in the generic way for all IPV4, IPV6 and EUI48 */
dflet 0:50cedd586816 149 /* is possible as long as these parameters are in the same offset and size for these */
dflet 0:50cedd586816 150 /* three families. */
dflet 0:50cedd586816 151 addr->sa_family = pRsp->IpV4.family;
dflet 0:50cedd586816 152 ((SlSockAddrIn_t *)addr)->sin_port = pRsp->IpV4.port;
dflet 0:50cedd586816 153
dflet 0:50cedd586816 154 *addrlen = (SL_AF_INET == addr->sa_family) ? sizeof(SlSockAddrIn_t) : sizeof(SlSockAddrIn6_t);
dflet 0:50cedd586816 155
dflet 0:50cedd586816 156 if(SL_AF_INET == addr->sa_family) {
dflet 0:50cedd586816 157 ((SlSockAddrIn_t *)addr)->sin_addr.s_addr = pRsp->IpV4.address;
dflet 0:50cedd586816 158 } else if (SL_AF_INET6_EUI_48 == addr->sa_family ) {
dflet 0:50cedd586816 159 memcpy(((SlSockAddrIn6_t *)addr)->sin6_addr._S6_un._S6_u8, pRsp->IpV6EUI48.address, 6);
dflet 0:50cedd586816 160 }
dflet 0:50cedd586816 161 #ifdef SL_SUPPORT_IPV6
dflet 0:50cedd586816 162 else {
dflet 0:50cedd586816 163 memcpy(((sockaddr_in6 *)addr)->sin6_addr._S6_un._S6_u32, pRsp->IpV6.address, 16);
dflet 0:50cedd586816 164 }
dflet 0:50cedd586816 165 #endif
dflet 0:50cedd586816 166 }
dflet 0:50cedd586816 167 #endif
dflet 0:50cedd586816 168
dflet 0:50cedd586816 169 /*******************************************************************************/
dflet 0:50cedd586816 170 /* sl_Socket */
dflet 0:50cedd586816 171 /*******************************************************************************/
dflet 0:50cedd586816 172 typedef union {
dflet 0:50cedd586816 173 uint32_t Dummy;
dflet 0:50cedd586816 174 _SocketCommand_t Cmd;
dflet 0:50cedd586816 175 _SocketResponse_t Rsp;
dflet 0:50cedd586816 176 } _SlSockSocketMsg_u;
dflet 0:50cedd586816 177
dflet 0:50cedd586816 178 #if _SL_INCLUDE_FUNC(sl_Socket)
dflet 0:50cedd586816 179 const _SlCmdCtrl_t _SlSockSocketCmdCtrl = {
dflet 0:50cedd586816 180 SL_OPCODE_SOCKET_SOCKET,
dflet 0:50cedd586816 181 sizeof(_SocketCommand_t),
dflet 0:50cedd586816 182 sizeof(_SocketResponse_t)
dflet 0:50cedd586816 183 };
dflet 0:50cedd586816 184
dflet 0:50cedd586816 185 int16_t cc3100_socket::sl_Socket(int16_t Domain, int16_t Type, int16_t Protocol)
dflet 0:50cedd586816 186 {
dflet 0:50cedd586816 187 _SlSockSocketMsg_u Msg;
dflet 0:50cedd586816 188
dflet 0:50cedd586816 189 Msg.Cmd.Domain = (uint8_t)Domain;
dflet 0:50cedd586816 190 Msg.Cmd.Type = (uint8_t)Type;
dflet 0:50cedd586816 191 Msg.Cmd.Protocol = (uint8_t)Protocol;
dflet 0:50cedd586816 192
dflet 0:50cedd586816 193 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSockSocketCmdCtrl, &Msg, NULL));
dflet 0:50cedd586816 194
dflet 0:50cedd586816 195 if( Msg.Rsp.statusOrLen < 0 ) {
dflet 0:50cedd586816 196 return( Msg.Rsp.statusOrLen );
dflet 0:50cedd586816 197 } else {
dflet 0:50cedd586816 198 return (int16_t)((uint8_t)Msg.Rsp.sd);
dflet 0:50cedd586816 199 }
dflet 0:50cedd586816 200 }
dflet 0:50cedd586816 201 #endif
dflet 0:50cedd586816 202
dflet 0:50cedd586816 203 /*******************************************************************************/
dflet 0:50cedd586816 204 /* sl_Close */
dflet 0:50cedd586816 205 /*******************************************************************************/
dflet 0:50cedd586816 206 typedef union {
dflet 0:50cedd586816 207 _CloseCommand_t Cmd;
dflet 0:50cedd586816 208 _SocketResponse_t Rsp;
dflet 0:50cedd586816 209 } _SlSockCloseMsg_u;
dflet 0:50cedd586816 210
dflet 0:50cedd586816 211 #if _SL_INCLUDE_FUNC(sl_Close)
dflet 0:50cedd586816 212 const _SlCmdCtrl_t _SlSockCloseCmdCtrl = {
dflet 0:50cedd586816 213 SL_OPCODE_SOCKET_CLOSE,
dflet 0:50cedd586816 214 sizeof(_CloseCommand_t),
dflet 0:50cedd586816 215 sizeof(_SocketResponse_t)
dflet 0:50cedd586816 216 };
dflet 0:50cedd586816 217
dflet 0:50cedd586816 218 int16_t cc3100_socket::sl_Close(int16_t sd)
dflet 0:50cedd586816 219 {
dflet 0:50cedd586816 220 _SlSockCloseMsg_u Msg;
dflet 0:50cedd586816 221
dflet 0:50cedd586816 222 Msg.Cmd.sd = (uint8_t)sd;
dflet 0:50cedd586816 223
dflet 0:50cedd586816 224 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSockCloseCmdCtrl, &Msg, NULL));
dflet 0:50cedd586816 225
dflet 0:50cedd586816 226 return Msg.Rsp.statusOrLen;
dflet 0:50cedd586816 227 }
dflet 0:50cedd586816 228 #endif
dflet 0:50cedd586816 229
dflet 0:50cedd586816 230 /*******************************************************************************/
dflet 0:50cedd586816 231 /* sl_Bind */
dflet 0:50cedd586816 232 /*******************************************************************************/
dflet 0:50cedd586816 233 typedef union {
dflet 0:50cedd586816 234 _SocketAddrCommand_u Cmd;
dflet 0:50cedd586816 235 _SocketResponse_t Rsp;
dflet 0:50cedd586816 236 } _SlSockBindMsg_u;
dflet 0:50cedd586816 237
dflet 0:50cedd586816 238 #if _SL_INCLUDE_FUNC(sl_Bind)
dflet 0:50cedd586816 239 int16_t cc3100_socket::sl_Bind(int16_t sd, const SlSockAddr_t *addr, int16_t addrlen)
dflet 0:50cedd586816 240 {
dflet 0:50cedd586816 241 _SlSockBindMsg_u Msg;
dflet 0:50cedd586816 242 _SlCmdCtrl_t CmdCtrl = {0, 0, sizeof(_SocketResponse_t)};
dflet 0:50cedd586816 243
dflet 0:50cedd586816 244 switch(addr->sa_family) {
dflet 0:50cedd586816 245 case SL_AF_INET :
dflet 0:50cedd586816 246 CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND;
dflet 0:50cedd586816 247 CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv4Command_t);
dflet 0:50cedd586816 248 break;
dflet 0:50cedd586816 249 #ifndef SL_TINY_EXT
dflet 0:50cedd586816 250 case SL_AF_INET6_EUI_48:
dflet 0:50cedd586816 251 CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND_V6;
dflet 0:50cedd586816 252 CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6EUI48Command_t);
dflet 0:50cedd586816 253 break;
dflet 0:50cedd586816 254 #ifdef SL_SUPPORT_IPV6
dflet 0:50cedd586816 255 case AF_INET6:
dflet 0:50cedd586816 256 CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND_V6;
dflet 0:50cedd586816 257 CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6Command_t);
dflet 0:50cedd586816 258 break;
dflet 0:50cedd586816 259 #endif
dflet 0:50cedd586816 260 #endif
dflet 0:50cedd586816 261 case SL_AF_RF :
dflet 0:50cedd586816 262 default:
dflet 0:50cedd586816 263 return SL_RET_CODE_INVALID_INPUT;
dflet 0:50cedd586816 264 }
dflet 0:50cedd586816 265
dflet 0:50cedd586816 266 Msg.Cmd.IpV4.lenOrPadding = 0;
dflet 0:50cedd586816 267 Msg.Cmd.IpV4.sd = (uint8_t)sd;
dflet 0:50cedd586816 268
dflet 0:50cedd586816 269 _sl_BuildAddress(addr, &Msg.Cmd);
dflet 0:50cedd586816 270
dflet 0:50cedd586816 271 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, &Msg, NULL));
dflet 0:50cedd586816 272
dflet 0:50cedd586816 273 return Msg.Rsp.statusOrLen;
dflet 0:50cedd586816 274 }
dflet 0:50cedd586816 275 #endif
dflet 0:50cedd586816 276
dflet 0:50cedd586816 277 /*******************************************************************************/
dflet 0:50cedd586816 278 /* sl_Sendto */
dflet 0:50cedd586816 279 /*******************************************************************************/
dflet 0:50cedd586816 280 typedef union {
dflet 0:50cedd586816 281 _SocketAddrCommand_u Cmd;
dflet 0:50cedd586816 282 /* no response for 'sendto' commands*/
dflet 0:50cedd586816 283 } _SlSendtoMsg_u;
dflet 0:50cedd586816 284
dflet 0:50cedd586816 285 #if _SL_INCLUDE_FUNC(sl_SendTo)
dflet 0:50cedd586816 286 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)
dflet 0:50cedd586816 287 {
dflet 0:50cedd586816 288 _SlSendtoMsg_u Msg;
dflet 0:50cedd586816 289 _SlCmdCtrl_t CmdCtrl = {0, 0, 0};
dflet 0:50cedd586816 290 _SlCmdExt_t CmdExt;
dflet 0:50cedd586816 291 uint16_t ChunkLen;
dflet 0:50cedd586816 292 int16_t RetVal;
dflet 0:50cedd586816 293
dflet 0:50cedd586816 294 _driver._SlDrvResetCmdExt(&CmdExt);
dflet 0:50cedd586816 295 CmdExt.TxPayloadLen = (uint16_t)Len;
dflet 0:50cedd586816 296 CmdExt.pTxPayload = (uint8_t *)pBuf;
dflet 0:50cedd586816 297
dflet 0:50cedd586816 298 switch(to->sa_family) {
dflet 0:50cedd586816 299 case SL_AF_INET:
dflet 0:50cedd586816 300 CmdCtrl.Opcode = SL_OPCODE_SOCKET_SENDTO;
dflet 0:50cedd586816 301 CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv4Command_t);
dflet 0:50cedd586816 302 break;
dflet 0:50cedd586816 303 #ifndef SL_TINY_EXT
dflet 0:50cedd586816 304 case SL_AF_INET6_EUI_48:
dflet 0:50cedd586816 305 CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND_V6;
dflet 0:50cedd586816 306 CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6EUI48Command_t);
dflet 0:50cedd586816 307 break;
dflet 0:50cedd586816 308 #ifdef SL_SUPPORT_IPV6
dflet 0:50cedd586816 309 case AF_INET6:
dflet 0:50cedd586816 310 CmdCtrl.Opcode = SL_OPCODE_SOCKET_SENDTO_V6;
dflet 0:50cedd586816 311 CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6Command_t);
dflet 0:50cedd586816 312 break;
dflet 0:50cedd586816 313 #endif
dflet 0:50cedd586816 314 #endif
dflet 0:50cedd586816 315 case SL_AF_RF:
dflet 0:50cedd586816 316 default:
dflet 0:50cedd586816 317 return SL_RET_CODE_INVALID_INPUT;
dflet 0:50cedd586816 318 }
dflet 0:50cedd586816 319
dflet 0:50cedd586816 320 ChunkLen = _sl_TruncatePayloadByProtocol(sd,Len);
dflet 0:50cedd586816 321 Msg.Cmd.IpV4.lenOrPadding = ChunkLen;
dflet 0:50cedd586816 322 CmdExt.TxPayloadLen = ChunkLen;
dflet 0:50cedd586816 323
dflet 0:50cedd586816 324 Msg.Cmd.IpV4.sd = (unsigned char)sd;
dflet 0:50cedd586816 325
dflet 0:50cedd586816 326 _sl_BuildAddress(to, &Msg.Cmd);
dflet 0:50cedd586816 327
dflet 0:50cedd586816 328 Msg.Cmd.IpV4.FamilyAndFlags |= flags & 0x0F;
dflet 0:50cedd586816 329
dflet 0:50cedd586816 330 do {
dflet 0:50cedd586816 331 RetVal = _driver._SlDrvDataWriteOp((_SlSd_t)sd, &CmdCtrl, &Msg, &CmdExt);
dflet 0:50cedd586816 332
dflet 0:50cedd586816 333 if(SL_OS_RET_CODE_OK == RetVal) {
dflet 0:50cedd586816 334 CmdExt.pTxPayload += ChunkLen;
dflet 0:50cedd586816 335 ChunkLen = (uint16_t)((unsigned char *)pBuf + Len - CmdExt.pTxPayload);
dflet 0:50cedd586816 336 ChunkLen = _sl_TruncatePayloadByProtocol(sd,ChunkLen);
dflet 0:50cedd586816 337 CmdExt.TxPayloadLen = ChunkLen;
dflet 0:50cedd586816 338 Msg.Cmd.IpV4.lenOrPadding = ChunkLen;
dflet 0:50cedd586816 339 } else {
dflet 0:50cedd586816 340 return RetVal;
dflet 0:50cedd586816 341 }
dflet 0:50cedd586816 342 } while(ChunkLen > 0);
dflet 0:50cedd586816 343
dflet 0:50cedd586816 344 return (int16_t)Len;
dflet 0:50cedd586816 345 }
dflet 0:50cedd586816 346 #endif
dflet 0:50cedd586816 347
dflet 0:50cedd586816 348 /*******************************************************************************/
dflet 0:50cedd586816 349 /* sl_Recvfrom */
dflet 0:50cedd586816 350 /*******************************************************************************/
dflet 0:50cedd586816 351 typedef union {
dflet 0:50cedd586816 352 _sendRecvCommand_t Cmd;
dflet 0:50cedd586816 353 _SocketAddrResponse_u Rsp;
dflet 0:50cedd586816 354 } _SlRecvfromMsg_u;
dflet 0:50cedd586816 355
dflet 0:50cedd586816 356 const _SlCmdCtrl_t _SlRecvfomCmdCtrl = {
dflet 0:50cedd586816 357 SL_OPCODE_SOCKET_RECVFROM,
dflet 0:50cedd586816 358 sizeof(_sendRecvCommand_t),
dflet 0:50cedd586816 359 sizeof(_SocketAddrResponse_u)
dflet 0:50cedd586816 360 };
dflet 0:50cedd586816 361
dflet 0:50cedd586816 362 #if _SL_INCLUDE_FUNC(sl_RecvFrom)
dflet 0:50cedd586816 363 int16_t cc3100_socket::sl_RecvFrom(int16_t sd, void *buf, int16_t Len, int16_t flags, SlSockAddr_t *from, SlSocklen_t *fromlen)
dflet 0:50cedd586816 364 {
dflet 0:50cedd586816 365 _SlRecvfromMsg_u Msg;
dflet 0:50cedd586816 366 _SlCmdExt_t CmdExt;
dflet 0:50cedd586816 367 int16_t RetVal;
dflet 0:50cedd586816 368
dflet 0:50cedd586816 369 _driver._SlDrvResetCmdExt(&CmdExt);
dflet 0:50cedd586816 370 CmdExt.RxPayloadLen = Len;
dflet 0:50cedd586816 371 CmdExt.pRxPayload = (uint8_t *)buf;
dflet 0:50cedd586816 372
dflet 0:50cedd586816 373 Msg.Cmd.sd = (uint8_t)sd;
dflet 0:50cedd586816 374 Msg.Cmd.StatusOrLen = Len;
dflet 0:50cedd586816 375 /* no size truncation in recv path */
dflet 0:50cedd586816 376 CmdExt.RxPayloadLen = Msg.Cmd.StatusOrLen;
dflet 0:50cedd586816 377
dflet 0:50cedd586816 378 Msg.Cmd.FamilyAndFlags = flags & 0x0F;
dflet 0:50cedd586816 379
dflet 0:50cedd586816 380 if(sizeof(SlSockAddrIn_t) == *fromlen) {
dflet 0:50cedd586816 381 Msg.Cmd.FamilyAndFlags |= (SL_AF_INET << 4);
dflet 0:50cedd586816 382 }
dflet 0:50cedd586816 383 else if (sizeof(SlSockAddrIn6_t) == *fromlen)
dflet 0:50cedd586816 384 {
dflet 0:50cedd586816 385 Msg.Cmd.FamilyAndFlags |= (SL_AF_INET6 << 4);
dflet 0:50cedd586816 386 }
dflet 0:50cedd586816 387 else
dflet 0:50cedd586816 388 {
dflet 0:50cedd586816 389 return SL_RET_CODE_INVALID_INPUT;
dflet 0:50cedd586816 390 }
dflet 0:50cedd586816 391
dflet 0:50cedd586816 392 RetVal = _driver._SlDrvDataReadOp((_SlSd_t)sd, (_SlCmdCtrl_t *)&_SlRecvfomCmdCtrl, &Msg, &CmdExt);
dflet 0:50cedd586816 393
dflet 0:50cedd586816 394 if( RetVal != SL_OS_RET_CODE_OK ) {
dflet 0:50cedd586816 395 return RetVal;
dflet 0:50cedd586816 396 }
dflet 0:50cedd586816 397
dflet 0:50cedd586816 398 RetVal = Msg.Rsp.IpV4.statusOrLen;
dflet 0:50cedd586816 399
dflet 0:50cedd586816 400 if(RetVal >= 0) {
dflet 0:50cedd586816 401 VERIFY_PROTOCOL(sd == Msg.Rsp.IpV4.sd);
dflet 0:50cedd586816 402 #if 0
dflet 0:50cedd586816 403 _sl_ParseAddress(&Msg.Rsp, from, fromlen);
dflet 0:50cedd586816 404 #else
dflet 0:50cedd586816 405 from->sa_family = Msg.Rsp.IpV4.family;
dflet 0:50cedd586816 406 if(SL_AF_INET == from->sa_family) {
dflet 0:50cedd586816 407 ((SlSockAddrIn_t *)from)->sin_port = Msg.Rsp.IpV4.port;
dflet 0:50cedd586816 408 ((SlSockAddrIn_t *)from)->sin_addr.s_addr = Msg.Rsp.IpV4.address;
dflet 0:50cedd586816 409 *fromlen = sizeof(SlSockAddrIn_t);
dflet 0:50cedd586816 410 } else if (SL_AF_INET6_EUI_48 == from->sa_family ) {
dflet 0:50cedd586816 411 ((SlSockAddrIn6_t *)from)->sin6_port = Msg.Rsp.IpV6EUI48.port;
dflet 0:50cedd586816 412 memcpy(((SlSockAddrIn6_t *)from)->sin6_addr._S6_un._S6_u8, Msg.Rsp.IpV6EUI48.address, 6);
dflet 0:50cedd586816 413 }
dflet 0:50cedd586816 414 #ifdef SL_SUPPORT_IPV6
dflet 0:50cedd586816 415 else if(AF_INET6 == from->sa_family) {
dflet 0:50cedd586816 416 VERIFY_PROTOCOL(*fromlen >= sizeof(sockaddr_in6));
dflet 0:50cedd586816 417
dflet 0:50cedd586816 418 ((sockaddr_in6 *)from)->sin6_port = Msg.Rsp.IpV6.port;
dflet 0:50cedd586816 419 memcpy(((sockaddr_in6 *)from)->sin6_addr._S6_un._S6_u32, Msg.Rsp.IpV6.address, 16);
dflet 0:50cedd586816 420 *fromlen = sizeof(sockaddr_in6);
dflet 0:50cedd586816 421 }
dflet 0:50cedd586816 422 #endif
dflet 0:50cedd586816 423 #endif
dflet 0:50cedd586816 424 }
dflet 0:50cedd586816 425
dflet 0:50cedd586816 426 return (int16_t)RetVal;
dflet 0:50cedd586816 427 }
dflet 0:50cedd586816 428 #endif
dflet 0:50cedd586816 429
dflet 0:50cedd586816 430 /*******************************************************************************/
dflet 0:50cedd586816 431 /* sl_Connect */
dflet 0:50cedd586816 432 /*******************************************************************************/
dflet 0:50cedd586816 433 typedef union {
dflet 0:50cedd586816 434 _SocketAddrCommand_u Cmd;
dflet 0:50cedd586816 435 _SocketResponse_t Rsp;
dflet 0:50cedd586816 436 } _SlSockConnectMsg_u;
dflet 0:50cedd586816 437
dflet 0:50cedd586816 438 #if _SL_INCLUDE_FUNC(sl_Connect)
dflet 0:50cedd586816 439 int16_t cc3100_socket::sl_Connect(int16_t sd, const SlSockAddr_t *addr, int16_t addrlen)
dflet 0:50cedd586816 440 {
dflet 0:50cedd586816 441 _SlSockConnectMsg_u Msg;
dflet 0:50cedd586816 442 _SlReturnVal_t RetVal;
dflet 0:50cedd586816 443 _SlCmdCtrl_t CmdCtrl = {0, 0, sizeof(_SocketResponse_t)};
dflet 0:50cedd586816 444 _SocketResponse_t AsyncRsp;
dflet 0:50cedd586816 445 uint8_t ObjIdx = MAX_CONCURRENT_ACTIONS;
dflet 0:50cedd586816 446
dflet 0:50cedd586816 447
dflet 0:50cedd586816 448 switch(addr->sa_family) {
dflet 0:50cedd586816 449 case SL_AF_INET :
dflet 0:50cedd586816 450 CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT;
dflet 0:50cedd586816 451 CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv4Command_t);
dflet 0:50cedd586816 452 /* Do nothing - cmd already initialized to this type */
dflet 0:50cedd586816 453 break;
dflet 0:50cedd586816 454 case SL_AF_INET6_EUI_48:
dflet 0:50cedd586816 455 CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT_V6;
dflet 0:50cedd586816 456 CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6EUI48Command_t);
dflet 0:50cedd586816 457 break;
dflet 0:50cedd586816 458 #ifdef SL_SUPPORT_IPV6
dflet 0:50cedd586816 459 case AF_INET6:
dflet 0:50cedd586816 460 CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT_V6;
dflet 0:50cedd586816 461 CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6Command_t);
dflet 0:50cedd586816 462 break;
dflet 0:50cedd586816 463 #endif
dflet 0:50cedd586816 464 case SL_AF_RF :
dflet 0:50cedd586816 465 default:
dflet 0:50cedd586816 466 return SL_RET_CODE_INVALID_INPUT;
dflet 0:50cedd586816 467 }
dflet 0:50cedd586816 468
dflet 0:50cedd586816 469 Msg.Cmd.IpV4.lenOrPadding = 0;
dflet 0:50cedd586816 470 Msg.Cmd.IpV4.sd = (uint8_t)sd;
dflet 0:50cedd586816 471
dflet 0:50cedd586816 472 _sl_BuildAddress(addr, &Msg.Cmd);
dflet 0:50cedd586816 473
dflet 0:50cedd586816 474
dflet 0:50cedd586816 475 ObjIdx = _driver._SlDrvProtectAsyncRespSetting((uint8_t*)&AsyncRsp, CONNECT_ID, sd & BSD_SOCKET_ID_MASK);
dflet 0:50cedd586816 476
dflet 0:50cedd586816 477 if (MAX_CONCURRENT_ACTIONS == ObjIdx)
dflet 0:50cedd586816 478 {
dflet 0:50cedd586816 479 return SL_POOL_IS_EMPTY;
dflet 0:50cedd586816 480 }
dflet 0:50cedd586816 481
dflet 0:50cedd586816 482 /* send the command */
dflet 0:50cedd586816 483 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, &Msg, NULL));
dflet 0:50cedd586816 484 VERIFY_PROTOCOL(Msg.Rsp.sd == sd)
dflet 0:50cedd586816 485
dflet 0:50cedd586816 486 RetVal = Msg.Rsp.statusOrLen;
dflet 0:50cedd586816 487
dflet 0:50cedd586816 488 if(SL_RET_CODE_OK == RetVal) {
dflet 0:50cedd586816 489 /* wait for async and get Data Read parameters */
dflet 0:50cedd586816 490 _driver._SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj);
dflet 0:50cedd586816 491
dflet 0:50cedd586816 492 VERIFY_PROTOCOL(AsyncRsp.sd == sd);
dflet 0:50cedd586816 493
dflet 0:50cedd586816 494 RetVal = AsyncRsp.statusOrLen;
dflet 0:50cedd586816 495 }
dflet 0:50cedd586816 496 _driver._SlDrvReleasePoolObj(ObjIdx);
dflet 0:50cedd586816 497 return RetVal;
dflet 0:50cedd586816 498 }
dflet 0:50cedd586816 499 #endif
dflet 0:50cedd586816 500
dflet 0:50cedd586816 501 /*******************************************************************************/
dflet 0:50cedd586816 502 /* sl_Send */
dflet 0:50cedd586816 503 /*******************************************************************************/
dflet 0:50cedd586816 504 typedef union {
dflet 0:50cedd586816 505 _sendRecvCommand_t Cmd;
dflet 0:50cedd586816 506 /* no response for 'sendto' commands*/
dflet 0:50cedd586816 507 } _SlSendMsg_u;
dflet 0:50cedd586816 508
dflet 0:50cedd586816 509 const _SlCmdCtrl_t _SlSendCmdCtrl = {
dflet 0:50cedd586816 510 SL_OPCODE_SOCKET_SEND,
dflet 0:50cedd586816 511 sizeof(_sendRecvCommand_t),
dflet 0:50cedd586816 512 0
dflet 0:50cedd586816 513 };
dflet 0:50cedd586816 514
dflet 0:50cedd586816 515 #if _SL_INCLUDE_FUNC(sl_Send)
dflet 0:50cedd586816 516 int16_t cc3100_socket::sl_Send(int16_t sd, const void *pBuf, int16_t Len, int16_t flags)
dflet 0:50cedd586816 517 {
dflet 0:50cedd586816 518 _SlSendMsg_u Msg;
dflet 0:50cedd586816 519 _SlCmdExt_t CmdExt;
dflet 0:50cedd586816 520 uint16_t ChunkLen;
dflet 0:50cedd586816 521 int16_t RetVal;
dflet 0:50cedd586816 522 uint32_t tempVal;
dflet 0:50cedd586816 523 uint8_t runSingleChunk = FALSE;
dflet 0:50cedd586816 524
dflet 0:50cedd586816 525 _driver._SlDrvResetCmdExt(&CmdExt);
dflet 0:50cedd586816 526 CmdExt.TxPayloadLen = Len;
dflet 0:50cedd586816 527 CmdExt.pTxPayload = (uint8_t *)pBuf;
dflet 0:50cedd586816 528
dflet 0:50cedd586816 529 /* Only for RAW transceiver type socket, relay the flags parameter in the 2 bytes (4 byte aligned) before the actual payload */
dflet 0:50cedd586816 530 if ((sd & SL_SOCKET_PAYLOAD_TYPE_MASK) == SL_SOCKET_PAYLOAD_TYPE_RAW_TRANCEIVER) {
dflet 0:50cedd586816 531 tempVal = flags;
dflet 0:50cedd586816 532 CmdExt.pRxPayload = (uint8_t *)&tempVal;
dflet 0:50cedd586816 533 CmdExt.RxPayloadLen = -4; /* mark as Rx data to send */
dflet 0:50cedd586816 534 runSingleChunk = TRUE;
dflet 0:50cedd586816 535 } else {
dflet 0:50cedd586816 536 CmdExt.pRxPayload = NULL;
dflet 0:50cedd586816 537 }
dflet 0:50cedd586816 538
dflet 0:50cedd586816 539 ChunkLen = _sl_TruncatePayloadByProtocol(sd,Len);
dflet 0:50cedd586816 540 CmdExt.TxPayloadLen = ChunkLen;
dflet 0:50cedd586816 541
dflet 0:50cedd586816 542 Msg.Cmd.StatusOrLen = ChunkLen;
dflet 0:50cedd586816 543 Msg.Cmd.sd = (uint8_t)sd;
dflet 0:50cedd586816 544 Msg.Cmd.FamilyAndFlags |= flags & 0x0F;
dflet 0:50cedd586816 545
dflet 0:50cedd586816 546 do {
dflet 0:50cedd586816 547 RetVal = _driver._SlDrvDataWriteOp((uint8_t)sd, (_SlCmdCtrl_t *)&_SlSendCmdCtrl, &Msg, &CmdExt);
dflet 0:50cedd586816 548 if(SL_OS_RET_CODE_OK == RetVal) {
dflet 0:50cedd586816 549 CmdExt.pTxPayload += ChunkLen;
dflet 0:50cedd586816 550 ChunkLen = (uint8_t *)pBuf + Len - CmdExt.pTxPayload;
dflet 0:50cedd586816 551 ChunkLen = _sl_TruncatePayloadByProtocol(sd,ChunkLen);
dflet 0:50cedd586816 552 CmdExt.TxPayloadLen = ChunkLen;
dflet 0:50cedd586816 553 Msg.Cmd.StatusOrLen = ChunkLen;
dflet 0:50cedd586816 554 } else {
dflet 0:50cedd586816 555 return RetVal;
dflet 0:50cedd586816 556 }
dflet 0:50cedd586816 557 } while((ChunkLen > 0) && (runSingleChunk==FALSE));
dflet 0:50cedd586816 558
dflet 0:50cedd586816 559 return (int16_t)Len;
dflet 0:50cedd586816 560 }
dflet 0:50cedd586816 561 #endif
dflet 0:50cedd586816 562
dflet 0:50cedd586816 563 /*******************************************************************************/
dflet 0:50cedd586816 564 /* sl_Listen */
dflet 0:50cedd586816 565 /*******************************************************************************/
dflet 0:50cedd586816 566 typedef union {
dflet 0:50cedd586816 567 _ListenCommand_t Cmd;
dflet 0:50cedd586816 568 _BasicResponse_t Rsp;
dflet 0:50cedd586816 569 } _SlListenMsg_u;
dflet 0:50cedd586816 570
dflet 0:50cedd586816 571 #if _SL_INCLUDE_FUNC(sl_Listen)
dflet 0:50cedd586816 572 const _SlCmdCtrl_t _SlListenCmdCtrl = {
dflet 0:50cedd586816 573 SL_OPCODE_SOCKET_LISTEN,
dflet 0:50cedd586816 574 sizeof(_ListenCommand_t),
dflet 0:50cedd586816 575 sizeof(_BasicResponse_t),
dflet 0:50cedd586816 576 };
dflet 0:50cedd586816 577
dflet 0:50cedd586816 578 int16_t cc3100_socket::sl_Listen(int16_t sd, int16_t backlog)
dflet 0:50cedd586816 579 {
dflet 0:50cedd586816 580 _SlListenMsg_u Msg;
dflet 0:50cedd586816 581
dflet 0:50cedd586816 582 Msg.Cmd.sd = (uint8_t)sd;
dflet 0:50cedd586816 583 Msg.Cmd.backlog = (uint8_t)backlog;
dflet 0:50cedd586816 584
dflet 0:50cedd586816 585 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlListenCmdCtrl, &Msg, NULL));
dflet 0:50cedd586816 586
dflet 0:50cedd586816 587 return (int16_t)Msg.Rsp.status;
dflet 0:50cedd586816 588 }
dflet 0:50cedd586816 589 #endif
dflet 0:50cedd586816 590
dflet 0:50cedd586816 591 /*******************************************************************************/
dflet 0:50cedd586816 592 /* sl_Accept */
dflet 0:50cedd586816 593 /*******************************************************************************/
dflet 0:50cedd586816 594 typedef union {
dflet 0:50cedd586816 595 _AcceptCommand_t Cmd;
dflet 0:50cedd586816 596 _SocketResponse_t Rsp;
dflet 0:50cedd586816 597 } _SlSockAcceptMsg_u;
dflet 0:50cedd586816 598
dflet 0:50cedd586816 599 #if _SL_INCLUDE_FUNC(sl_Accept)
dflet 0:50cedd586816 600 const _SlCmdCtrl_t _SlAcceptCmdCtrl = {
dflet 0:50cedd586816 601 SL_OPCODE_SOCKET_ACCEPT,
dflet 0:50cedd586816 602 sizeof(_AcceptCommand_t),
dflet 0:50cedd586816 603 sizeof(_BasicResponse_t),
dflet 0:50cedd586816 604 };
dflet 0:50cedd586816 605
dflet 0:50cedd586816 606 int16_t cc3100_socket::sl_Accept(int16_t sd, SlSockAddr_t *addr, SlSocklen_t *addrlen)
dflet 0:50cedd586816 607 {
dflet 0:50cedd586816 608 _SlSockAcceptMsg_u Msg;
dflet 0:50cedd586816 609 _SlReturnVal_t RetVal;
dflet 0:50cedd586816 610 _SocketAddrResponse_u AsyncRsp;
dflet 0:50cedd586816 611
dflet 0:50cedd586816 612 uint8_t ObjIdx = MAX_CONCURRENT_ACTIONS;
dflet 0:50cedd586816 613
dflet 0:50cedd586816 614
dflet 0:50cedd586816 615 Msg.Cmd.sd = (uint8_t)sd;
dflet 0:50cedd586816 616 Msg.Cmd.family = (sizeof(SlSockAddrIn_t) == *addrlen) ? SL_AF_INET : SL_AF_INET6;
dflet 0:50cedd586816 617
dflet 0:50cedd586816 618 ObjIdx = _driver._SlDrvProtectAsyncRespSetting((uint8_t*)&AsyncRsp, ACCEPT_ID, sd & BSD_SOCKET_ID_MASK );
dflet 0:50cedd586816 619
dflet 0:50cedd586816 620 if (MAX_CONCURRENT_ACTIONS == ObjIdx)
dflet 0:50cedd586816 621 {
dflet 0:50cedd586816 622 return SL_POOL_IS_EMPTY;
dflet 0:50cedd586816 623 }
dflet 0:50cedd586816 624
dflet 0:50cedd586816 625 /* send the command */
dflet 0:50cedd586816 626 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlAcceptCmdCtrl, &Msg, NULL));
dflet 0:50cedd586816 627 VERIFY_PROTOCOL(Msg.Rsp.sd == sd);
dflet 0:50cedd586816 628
dflet 0:50cedd586816 629 RetVal = Msg.Rsp.statusOrLen;
dflet 0:50cedd586816 630
dflet 0:50cedd586816 631 if(SL_OS_RET_CODE_OK == RetVal) {
dflet 0:50cedd586816 632 /* wait for async and get Data Read parameters */
dflet 0:50cedd586816 633 _driver._SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj);
dflet 0:50cedd586816 634
dflet 0:50cedd586816 635 VERIFY_PROTOCOL(AsyncRsp.IpV4.sd == sd);
dflet 0:50cedd586816 636
dflet 0:50cedd586816 637 RetVal = AsyncRsp.IpV4.statusOrLen;
dflet 0:50cedd586816 638 if( (NULL != addr) && (NULL != addrlen) ) {
dflet 0:50cedd586816 639 #if 0 /* Kept for backup */
dflet 0:50cedd586816 640 _sl_ParseAddress(&AsyncRsp, addr, addrlen);
dflet 0:50cedd586816 641 #else
dflet 0:50cedd586816 642 addr->sa_family = AsyncRsp.IpV4.family;
dflet 0:50cedd586816 643
dflet 0:50cedd586816 644 if(SL_AF_INET == addr->sa_family) {
dflet 0:50cedd586816 645 if( *addrlen == sizeof( SlSockAddrIn_t ) ) {
dflet 0:50cedd586816 646 ((SlSockAddrIn_t *)addr)->sin_port = AsyncRsp.IpV4.port;
dflet 0:50cedd586816 647 ((SlSockAddrIn_t *)addr)->sin_addr.s_addr = AsyncRsp.IpV4.address;
dflet 0:50cedd586816 648 } else {
dflet 0:50cedd586816 649 *addrlen = 0;
dflet 0:50cedd586816 650 }
dflet 0:50cedd586816 651 } else if (SL_AF_INET6_EUI_48 == addr->sa_family ) {
dflet 0:50cedd586816 652 if( *addrlen == sizeof( SlSockAddrIn6_t ) ) {
dflet 0:50cedd586816 653 ((SlSockAddrIn6_t *)addr)->sin6_port = AsyncRsp.IpV6EUI48.port;
dflet 0:50cedd586816 654 /* will be called from here and from _sl_BuildAddress*/
dflet 0:50cedd586816 655 memcpy(((SlSockAddrIn6_t *)addr)->sin6_addr._S6_un._S6_u8, AsyncRsp.IpV6EUI48.address, 6);
dflet 0:50cedd586816 656 } else {
dflet 0:50cedd586816 657 *addrlen = 0;
dflet 0:50cedd586816 658 }
dflet 0:50cedd586816 659 }
dflet 0:50cedd586816 660 #ifdef SL_SUPPORT_IPV6
dflet 0:50cedd586816 661 else {
dflet 0:50cedd586816 662 if( *addrlen == sizeof( sockaddr_in6 ) ) {
dflet 0:50cedd586816 663 ((sockaddr_in6 *)addr)->sin6_port = AsyncRsp.IpV6.port;
dflet 0:50cedd586816 664 memcpy(((sockaddr_in6 *)addr)->sin6_addr._S6_un._S6_u32, AsyncRsp.IpV6.address, 16);
dflet 0:50cedd586816 665 } else {
dflet 0:50cedd586816 666 *addrlen = 0;
dflet 0:50cedd586816 667 }
dflet 0:50cedd586816 668 }
dflet 0:50cedd586816 669 #endif
dflet 0:50cedd586816 670 #endif
dflet 0:50cedd586816 671 }
dflet 0:50cedd586816 672 }
dflet 0:50cedd586816 673
dflet 0:50cedd586816 674 _driver._SlDrvReleasePoolObj(ObjIdx);
dflet 0:50cedd586816 675 return (int16_t)RetVal;
dflet 0:50cedd586816 676 }
dflet 0:50cedd586816 677 #endif
dflet 0:50cedd586816 678
dflet 0:50cedd586816 679
dflet 0:50cedd586816 680 /*******************************************************************************/
dflet 0:50cedd586816 681 /* sl_Htonl */
dflet 0:50cedd586816 682 /*******************************************************************************/
dflet 0:50cedd586816 683 uint32_t cc3100_socket::sl_Htonl( uint32_t val )
dflet 0:50cedd586816 684 {
dflet 0:50cedd586816 685 uint32_t i = 1;
dflet 0:50cedd586816 686 int8_t *p = (int8_t *)&i;
dflet 0:50cedd586816 687 if (p[0] == 1) { /* little endian */
dflet 0:50cedd586816 688 p[0] = ((int8_t* )&val)[3];
dflet 0:50cedd586816 689 p[1] = ((int8_t* )&val)[2];
dflet 0:50cedd586816 690 p[2] = ((int8_t* )&val)[1];
dflet 0:50cedd586816 691 p[3] = ((int8_t* )&val)[0];
dflet 0:50cedd586816 692 return i;
dflet 0:50cedd586816 693 } else { /* big endian */
dflet 0:50cedd586816 694 return val;
dflet 0:50cedd586816 695 }
dflet 0:50cedd586816 696 }
dflet 0:50cedd586816 697
dflet 0:50cedd586816 698 /*******************************************************************************/
dflet 0:50cedd586816 699 /* sl_Htonl */
dflet 0:50cedd586816 700 /*******************************************************************************/
dflet 0:50cedd586816 701 uint16_t cc3100_socket::sl_Htons( uint16_t val )
dflet 0:50cedd586816 702 {
dflet 0:50cedd586816 703 int16_t i = 1;
dflet 0:50cedd586816 704 int8_t *p = (int8_t *)&i;
dflet 0:50cedd586816 705 if (p[0] == 1) { /* little endian */
dflet 0:50cedd586816 706 p[0] = ((int8_t* )&val)[1];
dflet 0:50cedd586816 707 p[1] = ((int8_t* )&val)[0];
dflet 0:50cedd586816 708 return i;
dflet 0:50cedd586816 709 } else { /* big endian */
dflet 0:50cedd586816 710 return val;
dflet 0:50cedd586816 711 }
dflet 0:50cedd586816 712 }
dflet 0:50cedd586816 713
dflet 0:50cedd586816 714 /*******************************************************************************/
dflet 0:50cedd586816 715 /* sl_Recv */
dflet 0:50cedd586816 716 /*******************************************************************************/
dflet 0:50cedd586816 717 typedef union {
dflet 0:50cedd586816 718 _sendRecvCommand_t Cmd;
dflet 0:50cedd586816 719 _SocketResponse_t Rsp;
dflet 0:50cedd586816 720 } _SlRecvMsg_u;
dflet 0:50cedd586816 721
dflet 0:50cedd586816 722 #if _SL_INCLUDE_FUNC(sl_Recv)
dflet 0:50cedd586816 723 const _SlCmdCtrl_t _SlRecvCmdCtrl = {
dflet 0:50cedd586816 724 SL_OPCODE_SOCKET_RECV,
dflet 0:50cedd586816 725 sizeof(_sendRecvCommand_t),
dflet 0:50cedd586816 726 sizeof(_SocketResponse_t)
dflet 0:50cedd586816 727 };
dflet 0:50cedd586816 728
dflet 0:50cedd586816 729 int16_t cc3100_socket::sl_Recv(int16_t sd, void *pBuf, int16_t Len, int16_t flags)
dflet 0:50cedd586816 730 {
dflet 0:50cedd586816 731 _SlRecvMsg_u Msg;
dflet 0:50cedd586816 732 _SlCmdExt_t CmdExt;
dflet 0:50cedd586816 733 _SlReturnVal_t status;
dflet 0:50cedd586816 734
dflet 0:50cedd586816 735 _driver._SlDrvResetCmdExt(&CmdExt);
dflet 0:50cedd586816 736 CmdExt.RxPayloadLen = Len;
dflet 0:50cedd586816 737 CmdExt.pRxPayload = (uint8_t *)pBuf;
dflet 0:50cedd586816 738
dflet 0:50cedd586816 739 Msg.Cmd.sd = (uint8_t)sd;
dflet 0:50cedd586816 740 Msg.Cmd.StatusOrLen = Len;
dflet 0:50cedd586816 741
dflet 0:50cedd586816 742 /* no size truncation in recv path */
dflet 0:50cedd586816 743 CmdExt.RxPayloadLen = Msg.Cmd.StatusOrLen;
dflet 0:50cedd586816 744
dflet 0:50cedd586816 745 Msg.Cmd.FamilyAndFlags = flags & 0x0F;
dflet 0:50cedd586816 746
dflet 0:50cedd586816 747 status = _driver._SlDrvDataReadOp((_SlSd_t)sd, (_SlCmdCtrl_t *)&_SlRecvCmdCtrl, &Msg, &CmdExt);
dflet 0:50cedd586816 748 if( status != SL_OS_RET_CODE_OK ) {
dflet 0:50cedd586816 749 return status;
dflet 0:50cedd586816 750 }
dflet 0:50cedd586816 751
dflet 0:50cedd586816 752 /* if the Device side sends less than expected it is not the Driver's role */
dflet 0:50cedd586816 753 /* the returned value could be smaller than the requested size */
dflet 0:50cedd586816 754 return (int16_t)Msg.Rsp.statusOrLen;
dflet 0:50cedd586816 755 }
dflet 0:50cedd586816 756 #endif
dflet 0:50cedd586816 757
dflet 0:50cedd586816 758 /*******************************************************************************/
dflet 0:50cedd586816 759 /* sl_SetSockOpt */
dflet 0:50cedd586816 760 /*******************************************************************************/
dflet 0:50cedd586816 761 typedef union {
dflet 0:50cedd586816 762 _setSockOptCommand_t Cmd;
dflet 0:50cedd586816 763 _SocketResponse_t Rsp;
dflet 0:50cedd586816 764 } _SlSetSockOptMsg_u;
dflet 0:50cedd586816 765
dflet 0:50cedd586816 766 const _SlCmdCtrl_t _SlSetSockOptCmdCtrl = {
dflet 0:50cedd586816 767 SL_OPCODE_SOCKET_SETSOCKOPT,
dflet 0:50cedd586816 768 sizeof(_setSockOptCommand_t),
dflet 0:50cedd586816 769 sizeof(_SocketResponse_t)
dflet 0:50cedd586816 770 };
dflet 0:50cedd586816 771
dflet 0:50cedd586816 772 #if _SL_INCLUDE_FUNC(sl_SetSockOpt)
dflet 0:50cedd586816 773 int16_t cc3100_socket::sl_SetSockOpt(int16_t sd, int16_t level, int16_t optname, const void *optval, SlSocklen_t optlen)
dflet 0:50cedd586816 774 {
dflet 0:50cedd586816 775 _SlSetSockOptMsg_u Msg;
dflet 0:50cedd586816 776 _SlCmdExt_t CmdExt;
dflet 0:50cedd586816 777
dflet 0:50cedd586816 778 _driver._SlDrvResetCmdExt(&CmdExt);
dflet 0:50cedd586816 779 CmdExt.TxPayloadLen = optlen;
dflet 0:50cedd586816 780 CmdExt.pTxPayload = (uint8_t *)optval;
dflet 0:50cedd586816 781
dflet 0:50cedd586816 782 Msg.Cmd.sd = (uint8_t)sd;
dflet 0:50cedd586816 783 Msg.Cmd.level = (uint8_t)level;
dflet 0:50cedd586816 784 Msg.Cmd.optionLen = (uint8_t)optlen;
dflet 0:50cedd586816 785 Msg.Cmd.optionName = (uint8_t)optname;
dflet 0:50cedd586816 786
dflet 0:50cedd586816 787 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSetSockOptCmdCtrl, &Msg, &CmdExt));
dflet 0:50cedd586816 788
dflet 0:50cedd586816 789 return (int16_t)Msg.Rsp.statusOrLen;
dflet 0:50cedd586816 790 }
dflet 0:50cedd586816 791 #endif
dflet 0:50cedd586816 792
dflet 0:50cedd586816 793 /*******************************************************************************/
dflet 0:50cedd586816 794 /* sl_GetSockOpt */
dflet 0:50cedd586816 795 /*******************************************************************************/
dflet 0:50cedd586816 796 typedef union {
dflet 0:50cedd586816 797 _getSockOptCommand_t Cmd;
dflet 0:50cedd586816 798 _getSockOptResponse_t Rsp;
dflet 0:50cedd586816 799 } _SlGetSockOptMsg_u;
dflet 0:50cedd586816 800
dflet 0:50cedd586816 801 #if _SL_INCLUDE_FUNC(sl_GetSockOpt)
dflet 0:50cedd586816 802 const _SlCmdCtrl_t _SlGetSockOptCmdCtrl = {
dflet 0:50cedd586816 803 SL_OPCODE_SOCKET_GETSOCKOPT,
dflet 0:50cedd586816 804 sizeof(_getSockOptCommand_t),
dflet 0:50cedd586816 805 sizeof(_getSockOptResponse_t)
dflet 0:50cedd586816 806 };
dflet 0:50cedd586816 807
dflet 0:50cedd586816 808 int16_t cc3100_socket::sl_GetSockOpt(int16_t sd, int16_t level, int16_t optname, void *optval, SlSocklen_t *optlen)
dflet 0:50cedd586816 809 {
dflet 0:50cedd586816 810 _SlGetSockOptMsg_u Msg;
dflet 0:50cedd586816 811 _SlCmdExt_t CmdExt;
dflet 0:50cedd586816 812
dflet 0:50cedd586816 813 if (*optlen == 0) {
dflet 0:50cedd586816 814 return SL_EZEROLEN;
dflet 0:50cedd586816 815 }
dflet 0:50cedd586816 816
dflet 0:50cedd586816 817 _driver._SlDrvResetCmdExt(&CmdExt);
dflet 0:50cedd586816 818 CmdExt.RxPayloadLen = *optlen;
dflet 0:50cedd586816 819 CmdExt.pRxPayload = (uint8_t*)optval;
dflet 0:50cedd586816 820
dflet 0:50cedd586816 821 Msg.Cmd.sd = (uint8_t)sd;
dflet 0:50cedd586816 822 Msg.Cmd.level = (uint8_t)level;
dflet 0:50cedd586816 823 Msg.Cmd.optionLen = (uint8_t)(*optlen);
dflet 0:50cedd586816 824 Msg.Cmd.optionName = (uint8_t)optname;
dflet 0:50cedd586816 825
dflet 0:50cedd586816 826 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlGetSockOptCmdCtrl, &Msg, &CmdExt));
dflet 0:50cedd586816 827
dflet 0:50cedd586816 828 if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) {
dflet 0:50cedd586816 829 *optlen = Msg.Rsp.optionLen;
dflet 0:50cedd586816 830 return SL_ESMALLBUF;
dflet 0:50cedd586816 831 } else {
dflet 0:50cedd586816 832 *optlen = (uint8_t)CmdExt.ActualRxPayloadLen;
dflet 0:50cedd586816 833 }
dflet 0:50cedd586816 834 return (int16_t)Msg.Rsp.status;
dflet 0:50cedd586816 835 }
dflet 0:50cedd586816 836 #endif
dflet 0:50cedd586816 837
dflet 0:50cedd586816 838 /*******************************************************************************/
dflet 0:50cedd586816 839 /* sl_Select */
dflet 0:50cedd586816 840 /* ******************************************************************************/
dflet 0:50cedd586816 841 typedef union {
dflet 0:50cedd586816 842 _SelectCommand_t Cmd;
dflet 0:50cedd586816 843 _BasicResponse_t Rsp;
dflet 0:50cedd586816 844 } _SlSelectMsg_u;
dflet 0:50cedd586816 845
dflet 0:50cedd586816 846 #ifndef SL_TINY_EXT
dflet 0:50cedd586816 847 #if _SL_INCLUDE_FUNC(sl_Select)
dflet 0:50cedd586816 848 const _SlCmdCtrl_t _SlSelectCmdCtrl = {
dflet 0:50cedd586816 849 SL_OPCODE_SOCKET_SELECT,
dflet 0:50cedd586816 850 sizeof(_SelectCommand_t),
dflet 0:50cedd586816 851 sizeof(_BasicResponse_t)
dflet 0:50cedd586816 852 };
dflet 0:50cedd586816 853
dflet 0:50cedd586816 854 int16_t cc3100_socket::sl_Select(int16_t nfds, SlFdSet_t *readsds, SlFdSet_t *writesds, SlFdSet_t *exceptsds, SlTimeval_t *timeout)
dflet 0:50cedd586816 855 {
dflet 0:50cedd586816 856 _SlSelectMsg_u Msg;
dflet 0:50cedd586816 857 _SelectAsyncResponse_t AsyncRsp;
dflet 0:50cedd586816 858 uint8_t ObjIdx = MAX_CONCURRENT_ACTIONS;
dflet 0:50cedd586816 859
dflet 0:50cedd586816 860 Msg.Cmd.nfds = (uint8_t)nfds;
dflet 0:50cedd586816 861 Msg.Cmd.readFdsCount = 0;
dflet 0:50cedd586816 862 Msg.Cmd.writeFdsCount = 0;
dflet 0:50cedd586816 863
dflet 0:50cedd586816 864 Msg.Cmd.readFds = 0;
dflet 0:50cedd586816 865 Msg.Cmd.writeFds = 0;
dflet 0:50cedd586816 866
dflet 0:50cedd586816 867 if( readsds ) {
dflet 0:50cedd586816 868 Msg.Cmd.readFds = (uint16_t)readsds->fd_array[0];
dflet 0:50cedd586816 869 }
dflet 0:50cedd586816 870 if( writesds ) {
dflet 0:50cedd586816 871 Msg.Cmd.writeFds = (uint16_t)writesds->fd_array[0];
dflet 0:50cedd586816 872 }
dflet 0:50cedd586816 873 if( NULL == timeout ) {
dflet 0:50cedd586816 874 Msg.Cmd.tv_sec = 0xffff;
dflet 0:50cedd586816 875 Msg.Cmd.tv_usec = 0xffff;
dflet 0:50cedd586816 876 } else {
dflet 0:50cedd586816 877 if( 0xffff <= timeout->tv_sec ) {
dflet 0:50cedd586816 878 Msg.Cmd.tv_sec = 0xffff;
dflet 0:50cedd586816 879 } else {
dflet 0:50cedd586816 880 Msg.Cmd.tv_sec = (uint16_t)timeout->tv_sec;
dflet 0:50cedd586816 881 }
dflet 0:50cedd586816 882 timeout->tv_usec = timeout->tv_usec >> 10; /* convert to milliseconds */
dflet 0:50cedd586816 883 if( 0xffff <= timeout->tv_usec ) {
dflet 0:50cedd586816 884 Msg.Cmd.tv_usec = 0xffff;
dflet 0:50cedd586816 885 } else {
dflet 0:50cedd586816 886 Msg.Cmd.tv_usec = (uint16_t)timeout->tv_usec;
dflet 0:50cedd586816 887 }
dflet 0:50cedd586816 888 }
dflet 0:50cedd586816 889
dflet 0:50cedd586816 890 /* Use Obj to issue the command, if not available try later */
dflet 0:50cedd586816 891 ObjIdx = _driver._SlDrvProtectAsyncRespSetting((uint8_t*)&AsyncRsp, SELECT_ID, SL_MAX_SOCKETS);
dflet 0:50cedd586816 892
dflet 0:50cedd586816 893 if (MAX_CONCURRENT_ACTIONS == ObjIdx)
dflet 0:50cedd586816 894 {
dflet 0:50cedd586816 895 return SL_POOL_IS_EMPTY;
dflet 0:50cedd586816 896 }
dflet 0:50cedd586816 897
dflet 0:50cedd586816 898 /* send the command */
dflet 0:50cedd586816 899 VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSelectCmdCtrl, &Msg, NULL));
dflet 0:50cedd586816 900
dflet 0:50cedd586816 901 if(SL_OS_RET_CODE_OK == (int16_t)Msg.Rsp.status) {
dflet 0:50cedd586816 902 _driver._SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj);
dflet 0:50cedd586816 903 Msg.Rsp.status = AsyncRsp.status;
dflet 0:50cedd586816 904
dflet 0:50cedd586816 905 if( ((int16_t)Msg.Rsp.status) >= 0 ) {
dflet 0:50cedd586816 906 if( readsds ) {
dflet 0:50cedd586816 907 readsds->fd_array[0] = AsyncRsp.readFds;
dflet 0:50cedd586816 908 }
dflet 0:50cedd586816 909 if( writesds ) {
dflet 0:50cedd586816 910 writesds->fd_array[0] = AsyncRsp.writeFds;
dflet 0:50cedd586816 911 }
dflet 0:50cedd586816 912 }
dflet 0:50cedd586816 913 }
dflet 0:50cedd586816 914
dflet 0:50cedd586816 915 _driver._SlDrvReleasePoolObj(ObjIdx);
dflet 0:50cedd586816 916 return (int16_t)Msg.Rsp.status;
dflet 0:50cedd586816 917 }
dflet 0:50cedd586816 918
dflet 0:50cedd586816 919 /* Select helper functions */
dflet 0:50cedd586816 920 /*******************************************************************************/
dflet 0:50cedd586816 921 /* SL_FD_SET */
dflet 0:50cedd586816 922 /* ******************************************************************************/
dflet 0:50cedd586816 923 void cc3100_socket::SL_FD_SET(int16_t fd, SlFdSet_t *fdset)
dflet 0:50cedd586816 924 {
dflet 0:50cedd586816 925 fdset->fd_array[0] |= (1<< (fd & BSD_SOCKET_ID_MASK));
dflet 0:50cedd586816 926 }
dflet 0:50cedd586816 927 /*******************************************************************************/
dflet 0:50cedd586816 928 /* SL_FD_CLR */
dflet 0:50cedd586816 929 /*******************************************************************************/
dflet 0:50cedd586816 930 void cc3100_socket::SL_FD_CLR(int16_t fd, SlFdSet_t *fdset)
dflet 0:50cedd586816 931 {
dflet 0:50cedd586816 932 fdset->fd_array[0] &= ~(1<< (fd & BSD_SOCKET_ID_MASK));
dflet 0:50cedd586816 933 }
dflet 0:50cedd586816 934 /*******************************************************************************/
dflet 0:50cedd586816 935 /* SL_FD_ISSET */
dflet 0:50cedd586816 936 /*******************************************************************************/
dflet 0:50cedd586816 937 int16_t cc3100_socket::SL_FD_ISSET(int16_t fd, SlFdSet_t *fdset)
dflet 0:50cedd586816 938 {
dflet 0:50cedd586816 939 if( fdset->fd_array[0] & (1<< (fd & BSD_SOCKET_ID_MASK)) ) {
dflet 0:50cedd586816 940 return 1;
dflet 0:50cedd586816 941 }
dflet 0:50cedd586816 942 return 0;
dflet 0:50cedd586816 943 }
dflet 0:50cedd586816 944 /*******************************************************************************/
dflet 0:50cedd586816 945 /* SL_FD_ZERO */
dflet 0:50cedd586816 946 /*******************************************************************************/
dflet 0:50cedd586816 947 void cc3100_socket::SL_FD_ZERO(SlFdSet_t *fdset)
dflet 0:50cedd586816 948 {
dflet 0:50cedd586816 949 fdset->fd_array[0] = 0;
dflet 0:50cedd586816 950 }
dflet 0:50cedd586816 951
dflet 0:50cedd586816 952 #endif
dflet 0:50cedd586816 953 #endif
dflet 0:50cedd586816 954
dflet 0:50cedd586816 955 }//namespace mbed_cc3100
dflet 0:50cedd586816 956
dflet 0:50cedd586816 957
dflet 0:50cedd586816 958