Update revision to use TI's mqtt and Freertos.

Dependencies:   mbed client server

Fork of cc3100_Test_mqtt_CM3 by David Fletcher

Committer:
dflet
Date:
Thu Sep 03 14:02:37 2015 +0000
Revision:
3:a8c249046181
SPI Mode change 1 to 0

Who changed what in which revision?

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