cc3000 hostdriver with the mbed socket interface

Dependents:   cc3000_hello_world_demo cc3000_simple_socket_demo cc3000_ntp_demo cc3000_ping_demo ... more

Committer:
SolderSplashLabs
Date:
Tue Oct 01 21:17:44 2013 +0000
Revision:
11:5e3771b29385
Parent:
5:245ac5b73132
Child:
12:1c2a856c618a
Child:
13:5e36c267e62f
Added \r\n to all debug messages; Fixed debug message displaying the port no incorrectly

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Kojto 0:615c697c33b0 1 /*****************************************************************************
Kojto 0:615c697c33b0 2 *
Kojto 0:615c697c33b0 3 * C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
Kojto 0:615c697c33b0 4 * Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
Kojto 0:615c697c33b0 5 * provided help.
Kojto 0:615c697c33b0 6 *
Kojto 0:615c697c33b0 7 * This version of "host driver" uses CC3000 Host Driver Implementation. Thus
Kojto 0:615c697c33b0 8 * read the following copyright:
Kojto 0:615c697c33b0 9 *
Kojto 0:615c697c33b0 10 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
Kojto 0:615c697c33b0 11 *
Kojto 0:615c697c33b0 12 * Redistribution and use in source and binary forms, with or without
Kojto 0:615c697c33b0 13 * modification, are permitted provided that the following conditions
Kojto 0:615c697c33b0 14 * are met:
Kojto 0:615c697c33b0 15 *
Kojto 0:615c697c33b0 16 * Redistributions of source code must retain the above copyright
Kojto 0:615c697c33b0 17 * notice, this list of conditions and the following disclaimer.
Kojto 0:615c697c33b0 18 *
Kojto 0:615c697c33b0 19 * Redistributions in binary form must reproduce the above copyright
Kojto 0:615c697c33b0 20 * notice, this list of conditions and the following disclaimer in the
Kojto 0:615c697c33b0 21 * documentation and/or other materials provided with the
Kojto 0:615c697c33b0 22 * distribution.
Kojto 0:615c697c33b0 23 *
Kojto 0:615c697c33b0 24 * Neither the name of Texas Instruments Incorporated nor the names of
Kojto 0:615c697c33b0 25 * its contributors may be used to endorse or promote products derived
Kojto 0:615c697c33b0 26 * from this software without specific prior written permission.
Kojto 0:615c697c33b0 27 *
Kojto 0:615c697c33b0 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Kojto 0:615c697c33b0 29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Kojto 0:615c697c33b0 30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Kojto 0:615c697c33b0 31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
Kojto 0:615c697c33b0 32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
Kojto 0:615c697c33b0 33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
Kojto 0:615c697c33b0 34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Kojto 0:615c697c33b0 35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Kojto 0:615c697c33b0 36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Kojto 0:615c697c33b0 37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Kojto 0:615c697c33b0 38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Kojto 0:615c697c33b0 39 *
Kojto 0:615c697c33b0 40 *****************************************************************************/
Kojto 0:615c697c33b0 41 #include "cc3000.h"
Kojto 0:615c697c33b0 42 #include "cc3000_socket.h"
Kojto 0:615c697c33b0 43 #include "cc3000_event.h" //TODO - remove this
Kojto 0:615c697c33b0 44 #include "cc3000_common.h"
Kojto 0:615c697c33b0 45
Kojto 0:615c697c33b0 46 namespace mbed_cc3000 {
Kojto 0:615c697c33b0 47
Kojto 0:615c697c33b0 48 cc3000_socket::cc3000_socket(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_event &event)
Kojto 0:615c697c33b0 49 : _simple_link(simplelink), _hci(hci), _event(event)
Kojto 0:615c697c33b0 50 {
Kojto 0:615c697c33b0 51
Kojto 0:615c697c33b0 52 }
Kojto 0:615c697c33b0 53
Kojto 0:615c697c33b0 54 cc3000_socket::~cc3000_socket()
Kojto 0:615c697c33b0 55 {
Kojto 0:615c697c33b0 56
Kojto 0:615c697c33b0 57 }
Kojto 0:615c697c33b0 58
Kojto 0:615c697c33b0 59 int32_t cc3000_socket::HostFlowControlConsumeBuff(int32_t sd) {
Kojto 0:615c697c33b0 60 #ifndef SEND_NON_BLOCKING
Kojto 0:615c697c33b0 61 /* wait in busy loop */
Kojto 0:615c697c33b0 62 do
Kojto 0:615c697c33b0 63 {
Kojto 0:615c697c33b0 64 // When the last transmission failed, return the last failure reason.
Kojto 0:615c697c33b0 65 // Note that the buffer will not be allocated in this case
Kojto 0:615c697c33b0 66 if (_simple_link.get_transmit_error() != 0)
Kojto 0:615c697c33b0 67 {
Kojto 0:615c697c33b0 68 errno = _simple_link.get_transmit_error();
Kojto 0:615c697c33b0 69 _simple_link.set_transmit_error(0);
Kojto 0:615c697c33b0 70 return errno;
Kojto 0:615c697c33b0 71 }
Kojto 0:615c697c33b0 72
Kojto 0:615c697c33b0 73 if(SOCKET_STATUS_ACTIVE != _event.get_socket_active_status(sd))
Kojto 0:615c697c33b0 74 return -1;
Kojto 0:615c697c33b0 75 } while(0 == _simple_link.get_number_free_buffers());
Kojto 0:615c697c33b0 76
Kojto 0:615c697c33b0 77 uint16_t free_buffer = _simple_link.get_number_free_buffers();
Kojto 0:615c697c33b0 78 free_buffer--;
Kojto 0:615c697c33b0 79 _simple_link.set_number_free_buffers(free_buffer);
Kojto 0:615c697c33b0 80
Kojto 0:615c697c33b0 81 return 0;
Kojto 0:615c697c33b0 82 #else
Kojto 0:615c697c33b0 83
Kojto 0:615c697c33b0 84 // When the last transmission failed, return the last failure reason.
Kojto 0:615c697c33b0 85 // Note that the buffer will not be allocated in this case
Kojto 0:615c697c33b0 86 if (_simple_link.get_transmit_error() != 0)
Kojto 0:615c697c33b0 87 {
Kojto 0:615c697c33b0 88 errno = _simple_link.get_transmit_error();
Kojto 0:615c697c33b0 89 _simple_link.set_transmit_error(0);
Kojto 0:615c697c33b0 90 return errno;
Kojto 0:615c697c33b0 91 }
Kojto 5:245ac5b73132 92 if(SOCKET_STATUS_ACTIVE != _event.get_socket_active_status(sd))
Kojto 0:615c697c33b0 93 return -1;
Kojto 0:615c697c33b0 94
Kojto 0:615c697c33b0 95 // If there are no available buffers, return -2. It is recommended to use
Kojto 0:615c697c33b0 96 // select or receive to see if there is any buffer occupied with received data
Kojto 0:615c697c33b0 97 // If so, call receive() to release the buffer.
Kojto 0:615c697c33b0 98 if(0 == _simple_link.get_number_free_buffers())
Kojto 0:615c697c33b0 99 {
Kojto 0:615c697c33b0 100 return -2;
Kojto 0:615c697c33b0 101 }
Kojto 0:615c697c33b0 102 else
Kojto 0:615c697c33b0 103 {
Kojto 4:15b58c119a0a 104 uint16_t free_buffer = _simple_link.get_number_free_buffers();
Kojto 0:615c697c33b0 105 free_buffer--;
Kojto 0:615c697c33b0 106 _simple_link.set_number_free_buffers(free_buffer);
Kojto 0:615c697c33b0 107 return 0;
Kojto 0:615c697c33b0 108 }
Kojto 0:615c697c33b0 109 #endif
Kojto 0:615c697c33b0 110 }
Kojto 0:615c697c33b0 111
Kojto 0:615c697c33b0 112 int32_t cc3000_socket::socket(int32_t domain, int32_t type, int32_t protocol) {
Kojto 0:615c697c33b0 113 int32_t ret;
Kojto 0:615c697c33b0 114 uint8_t *ptr, *args;
Kojto 0:615c697c33b0 115
Kojto 0:615c697c33b0 116 ret = EFAIL;
Kojto 0:615c697c33b0 117 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 118 args = (ptr + HEADERS_SIZE_CMD);
Kojto 0:615c697c33b0 119
Kojto 0:615c697c33b0 120 // Fill in HCI packet structure
Kojto 0:615c697c33b0 121 args = UINT32_TO_STREAM(args, domain);
Kojto 0:615c697c33b0 122 args = UINT32_TO_STREAM(args, type);
Kojto 0:615c697c33b0 123 args = UINT32_TO_STREAM(args, protocol);
Kojto 0:615c697c33b0 124
Kojto 0:615c697c33b0 125 // Initiate a HCI command
Kojto 0:615c697c33b0 126 _hci.command_send(HCI_CMND_SOCKET, ptr, SOCKET_OPEN_PARAMS_LEN);
Kojto 0:615c697c33b0 127
Kojto 0:615c697c33b0 128 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 129 _event.simplelink_wait_event(HCI_CMND_SOCKET, &ret);
Kojto 0:615c697c33b0 130
Kojto 0:615c697c33b0 131 // Process the event
Kojto 0:615c697c33b0 132 errno = ret;
Kojto 0:615c697c33b0 133
Kojto 0:615c697c33b0 134 _event.set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
Kojto 0:615c697c33b0 135
Kojto 0:615c697c33b0 136 return(ret);
Kojto 0:615c697c33b0 137 }
Kojto 0:615c697c33b0 138
Kojto 0:615c697c33b0 139 int32_t cc3000_socket::closesocket(int32_t sd) {
Kojto 0:615c697c33b0 140 int32_t ret;
Kojto 0:615c697c33b0 141 uint8_t *ptr, *args;
Kojto 0:615c697c33b0 142
Kojto 4:15b58c119a0a 143 while(_simple_link.get_number_free_buffers() != SOCKET_MAX_FREE_BUFFERS);
Kojto 0:615c697c33b0 144 ret = EFAIL;
Kojto 0:615c697c33b0 145 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 146 args = (ptr + HEADERS_SIZE_CMD);
Kojto 0:615c697c33b0 147
Kojto 0:615c697c33b0 148 // Fill in HCI packet structure
Kojto 0:615c697c33b0 149 args = UINT32_TO_STREAM(args, sd);
Kojto 0:615c697c33b0 150
Kojto 0:615c697c33b0 151 // Initiate a HCI command
Kojto 0:615c697c33b0 152 _hci.command_send(HCI_CMND_CLOSE_SOCKET, ptr, SOCKET_CLOSE_PARAMS_LEN);
Kojto 0:615c697c33b0 153
Kojto 0:615c697c33b0 154 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 155 _event.simplelink_wait_event(HCI_CMND_CLOSE_SOCKET, &ret);
Kojto 0:615c697c33b0 156 errno = ret;
Kojto 0:615c697c33b0 157
Kojto 0:615c697c33b0 158 // since 'close' call may result in either OK (and then it closed) or error, mark this socket as invalid
Kojto 0:615c697c33b0 159 _event.set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
Kojto 0:615c697c33b0 160
Kojto 0:615c697c33b0 161 return(ret);
Kojto 0:615c697c33b0 162 }
Kojto 0:615c697c33b0 163
Kojto 0:615c697c33b0 164 int32_t cc3000_socket::accept(int32_t sd, sockaddr *addr, socklen_t *addrlen) {
Kojto 0:615c697c33b0 165 int32_t ret;
Kojto 0:615c697c33b0 166 uint8_t *ptr, *args;
Kojto 0:615c697c33b0 167 tBsdReturnParams tAcceptReturnArguments;
Kojto 0:615c697c33b0 168
Kojto 0:615c697c33b0 169 ret = EFAIL;
Kojto 0:615c697c33b0 170 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 171 args = (ptr + HEADERS_SIZE_CMD);
Kojto 0:615c697c33b0 172
Kojto 0:615c697c33b0 173 // Fill in temporary command buffer
Kojto 0:615c697c33b0 174 args = UINT32_TO_STREAM(args, sd);
Kojto 0:615c697c33b0 175
Kojto 0:615c697c33b0 176 // Initiate a HCI command
Kojto 0:615c697c33b0 177 _hci.command_send(HCI_CMND_ACCEPT, ptr, SOCKET_ACCEPT_PARAMS_LEN);
Kojto 0:615c697c33b0 178
Kojto 0:615c697c33b0 179 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 180 _event.simplelink_wait_event(HCI_CMND_ACCEPT, &tAcceptReturnArguments);
Kojto 0:615c697c33b0 181
Kojto 0:615c697c33b0 182
Kojto 0:615c697c33b0 183 // need specify return parameters!!!
Kojto 0:615c697c33b0 184 memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN);
Kojto 0:615c697c33b0 185 *addrlen = ASIC_ADDR_LEN;
Kojto 0:615c697c33b0 186 errno = tAcceptReturnArguments.iStatus;
Kojto 0:615c697c33b0 187 ret = errno;
Kojto 0:615c697c33b0 188
Kojto 0:615c697c33b0 189 // if succeeded, iStatus = new socket descriptor. otherwise - error number
Kojto 0:615c697c33b0 190 if(M_IS_VALID_SD(ret))
Kojto 0:615c697c33b0 191 {
Kojto 0:615c697c33b0 192 _event.set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
Kojto 0:615c697c33b0 193 }
Kojto 0:615c697c33b0 194 else
Kojto 0:615c697c33b0 195 {
Kojto 0:615c697c33b0 196 _event.set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
Kojto 0:615c697c33b0 197 }
Kojto 0:615c697c33b0 198
Kojto 0:615c697c33b0 199 return(ret);
Kojto 0:615c697c33b0 200 }
Kojto 0:615c697c33b0 201
Kojto 0:615c697c33b0 202 int32_t cc3000_socket::bind(int32_t sd, const sockaddr *addr, int32_t addrlen) {
Kojto 0:615c697c33b0 203 int32_t ret;
Kojto 0:615c697c33b0 204 uint8_t *ptr, *args;
Kojto 0:615c697c33b0 205
Kojto 0:615c697c33b0 206 ret = EFAIL;
Kojto 0:615c697c33b0 207 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 208 args = (ptr + HEADERS_SIZE_CMD);
Kojto 0:615c697c33b0 209
Kojto 0:615c697c33b0 210 addrlen = ASIC_ADDR_LEN;
Kojto 0:615c697c33b0 211
Kojto 0:615c697c33b0 212 // Fill in temporary command buffer
Kojto 0:615c697c33b0 213 args = UINT32_TO_STREAM(args, sd);
Kojto 0:615c697c33b0 214 args = UINT32_TO_STREAM(args, 0x00000008);
Kojto 0:615c697c33b0 215 args = UINT32_TO_STREAM(args, addrlen);
Kojto 0:615c697c33b0 216 ARRAY_TO_STREAM(args, ((uint8_t *)addr), addrlen);
Kojto 0:615c697c33b0 217
Kojto 0:615c697c33b0 218 // Initiate a HCI command
Kojto 0:615c697c33b0 219 _hci.command_send(HCI_CMND_BIND, ptr, SOCKET_BIND_PARAMS_LEN);
Kojto 0:615c697c33b0 220
Kojto 0:615c697c33b0 221 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 222 _event.simplelink_wait_event(HCI_CMND_BIND, &ret);
Kojto 0:615c697c33b0 223
Kojto 0:615c697c33b0 224 errno = ret;
Kojto 0:615c697c33b0 225
Kojto 0:615c697c33b0 226 return(ret);
Kojto 0:615c697c33b0 227 }
Kojto 0:615c697c33b0 228
Kojto 0:615c697c33b0 229 int32_t cc3000_socket::listen(int32_t sd, int32_t backlog) {
Kojto 0:615c697c33b0 230 int32_t ret;
Kojto 0:615c697c33b0 231 uint8_t *ptr, *args;
Kojto 0:615c697c33b0 232
Kojto 0:615c697c33b0 233 ret = EFAIL;
Kojto 0:615c697c33b0 234 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 235 args = (ptr + HEADERS_SIZE_CMD);
Kojto 0:615c697c33b0 236
Kojto 0:615c697c33b0 237 // Fill in temporary command buffer
Kojto 0:615c697c33b0 238 args = UINT32_TO_STREAM(args, sd);
Kojto 0:615c697c33b0 239 args = UINT32_TO_STREAM(args, backlog);
Kojto 0:615c697c33b0 240
Kojto 0:615c697c33b0 241 // Initiate a HCI command
Kojto 0:615c697c33b0 242 _hci.command_send(HCI_CMND_LISTEN, ptr, SOCKET_LISTEN_PARAMS_LEN);
Kojto 0:615c697c33b0 243
Kojto 0:615c697c33b0 244 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 245 _event.simplelink_wait_event(HCI_CMND_LISTEN, &ret);
Kojto 0:615c697c33b0 246 errno = ret;
Kojto 0:615c697c33b0 247
Kojto 0:615c697c33b0 248 return(ret);
Kojto 0:615c697c33b0 249 }
Kojto 0:615c697c33b0 250
Kojto 0:615c697c33b0 251 int32_t cc3000_socket::connect(int32_t sd, const sockaddr *addr, int32_t addrlen) {
Kojto 0:615c697c33b0 252 int32_t ret;
Kojto 0:615c697c33b0 253 uint8_t *ptr, *args;
Kojto 0:615c697c33b0 254
Kojto 0:615c697c33b0 255 ret = EFAIL;
Kojto 0:615c697c33b0 256 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 257 args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
Kojto 0:615c697c33b0 258 addrlen = 8;
Kojto 0:615c697c33b0 259
Kojto 0:615c697c33b0 260 // Fill in temporary command buffer
Kojto 0:615c697c33b0 261 args = UINT32_TO_STREAM(args, sd);
Kojto 0:615c697c33b0 262 args = UINT32_TO_STREAM(args, 0x00000008);
Kojto 0:615c697c33b0 263 args = UINT32_TO_STREAM(args, addrlen);
Kojto 0:615c697c33b0 264 ARRAY_TO_STREAM(args, ((uint8_t *)addr), addrlen);
Kojto 0:615c697c33b0 265
Kojto 0:615c697c33b0 266 // Initiate a HCI command
Kojto 0:615c697c33b0 267 _hci.command_send(HCI_CMND_CONNECT, ptr, SOCKET_CONNECT_PARAMS_LEN);
Kojto 0:615c697c33b0 268
Kojto 0:615c697c33b0 269 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 270 _event.simplelink_wait_event(HCI_CMND_CONNECT, &ret);
Kojto 0:615c697c33b0 271
Kojto 0:615c697c33b0 272 errno = ret;
Kojto 0:615c697c33b0 273
Kojto 0:615c697c33b0 274 return((int32_t)ret);
Kojto 0:615c697c33b0 275 }
Kojto 0:615c697c33b0 276
Kojto 0:615c697c33b0 277 int32_t cc3000_socket::select(int32_t nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, struct timeval *timeout) {
Kojto 0:615c697c33b0 278 uint8_t *ptr, *args;
Kojto 0:615c697c33b0 279 tBsdSelectRecvParams tParams;
Kojto 0:615c697c33b0 280 uint32_t is_blocking;
Kojto 0:615c697c33b0 281
Kojto 0:615c697c33b0 282 if( timeout == NULL)
Kojto 0:615c697c33b0 283 {
Kojto 0:615c697c33b0 284 is_blocking = 1; /* blocking , infinity timeout */
Kojto 0:615c697c33b0 285 }
Kojto 0:615c697c33b0 286 else
Kojto 0:615c697c33b0 287 {
Kojto 0:615c697c33b0 288 is_blocking = 0; /* no blocking, timeout */
Kojto 0:615c697c33b0 289 }
Kojto 0:615c697c33b0 290
Kojto 0:615c697c33b0 291 // Fill in HCI packet structure
Kojto 0:615c697c33b0 292 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 293 args = (ptr + HEADERS_SIZE_CMD);
Kojto 0:615c697c33b0 294
Kojto 0:615c697c33b0 295 // Fill in temporary command buffer
Kojto 0:615c697c33b0 296 args = UINT32_TO_STREAM(args, nfds);
Kojto 0:615c697c33b0 297 args = UINT32_TO_STREAM(args, 0x00000014);
Kojto 0:615c697c33b0 298 args = UINT32_TO_STREAM(args, 0x00000014);
Kojto 0:615c697c33b0 299 args = UINT32_TO_STREAM(args, 0x00000014);
Kojto 0:615c697c33b0 300 args = UINT32_TO_STREAM(args, 0x00000014);
Kojto 0:615c697c33b0 301 args = UINT32_TO_STREAM(args, is_blocking);
Kojto 0:615c697c33b0 302 args = UINT32_TO_STREAM(args, ((readsds) ? *(uint32_t*)readsds : 0));
Kojto 0:615c697c33b0 303 args = UINT32_TO_STREAM(args, ((writesds) ? *(uint32_t*)writesds : 0));
Kojto 0:615c697c33b0 304 args = UINT32_TO_STREAM(args, ((exceptsds) ? *(uint32_t*)exceptsds : 0));
Kojto 0:615c697c33b0 305
Kojto 0:615c697c33b0 306 if (timeout)
Kojto 0:615c697c33b0 307 {
Kojto 0:615c697c33b0 308 if ( 0 == timeout->tv_sec && timeout->tv_usec < SELECT_TIMEOUT_MIN_MICRO_SECONDS)
Kojto 0:615c697c33b0 309 {
Kojto 0:615c697c33b0 310 timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS;
Kojto 0:615c697c33b0 311 }
Kojto 0:615c697c33b0 312 args = UINT32_TO_STREAM(args, timeout->tv_sec);
Kojto 0:615c697c33b0 313 args = UINT32_TO_STREAM(args, timeout->tv_usec);
Kojto 0:615c697c33b0 314 }
Kojto 0:615c697c33b0 315
Kojto 0:615c697c33b0 316 // Initiate a HCI command
Kojto 0:615c697c33b0 317 _hci.command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN);
Kojto 0:615c697c33b0 318
Kojto 0:615c697c33b0 319 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 320 _event.simplelink_wait_event(HCI_EVNT_SELECT, &tParams);
Kojto 0:615c697c33b0 321
Kojto 0:615c697c33b0 322 // Update actually read FD
Kojto 0:615c697c33b0 323 if (tParams.iStatus >= 0)
Kojto 0:615c697c33b0 324 {
Kojto 0:615c697c33b0 325 if (readsds)
Kojto 0:615c697c33b0 326 {
Kojto 0:615c697c33b0 327 memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd));
Kojto 0:615c697c33b0 328 }
Kojto 0:615c697c33b0 329
Kojto 0:615c697c33b0 330 if (writesds)
Kojto 0:615c697c33b0 331 {
Kojto 0:615c697c33b0 332 memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd));
Kojto 0:615c697c33b0 333 }
Kojto 0:615c697c33b0 334
Kojto 0:615c697c33b0 335 if (exceptsds)
Kojto 0:615c697c33b0 336 {
Kojto 0:615c697c33b0 337 memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd));
Kojto 0:615c697c33b0 338 }
Kojto 0:615c697c33b0 339
Kojto 0:615c697c33b0 340 return(tParams.iStatus);
Kojto 0:615c697c33b0 341
Kojto 0:615c697c33b0 342 }
Kojto 0:615c697c33b0 343 else
Kojto 0:615c697c33b0 344 {
Kojto 0:615c697c33b0 345 errno = tParams.iStatus;
Kojto 0:615c697c33b0 346 return(-1);
Kojto 0:615c697c33b0 347 }
Kojto 0:615c697c33b0 348 }
Kojto 0:615c697c33b0 349
Kojto 0:615c697c33b0 350 int32_t cc3000_socket::get_sockopt (int32_t sd, int32_t level, int32_t optname, void *optval, socklen_t *optlen) {
Kojto 0:615c697c33b0 351 uint8_t *ptr, *args;
Kojto 0:615c697c33b0 352 tBsdGetSockOptReturnParams tRetParams;
Kojto 0:615c697c33b0 353
Kojto 0:615c697c33b0 354 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 355 args = (ptr + HEADERS_SIZE_CMD);
Kojto 0:615c697c33b0 356
Kojto 0:615c697c33b0 357 // Fill in temporary command buffer
Kojto 0:615c697c33b0 358 args = UINT32_TO_STREAM(args, sd);
Kojto 0:615c697c33b0 359 args = UINT32_TO_STREAM(args, level);
Kojto 0:615c697c33b0 360 args = UINT32_TO_STREAM(args, optname);
Kojto 0:615c697c33b0 361
Kojto 0:615c697c33b0 362 // Initiate a HCI command
Kojto 0:615c697c33b0 363 _hci.command_send(HCI_CMND_GETSOCKOPT, ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN);
Kojto 0:615c697c33b0 364
Kojto 0:615c697c33b0 365 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 366 _event.simplelink_wait_event(HCI_CMND_GETSOCKOPT, &tRetParams);
Kojto 0:615c697c33b0 367
Kojto 0:615c697c33b0 368 if (((int8_t)tRetParams.iStatus) >= 0)
Kojto 0:615c697c33b0 369 {
Kojto 0:615c697c33b0 370 *optlen = 4;
Kojto 0:615c697c33b0 371 memcpy(optval, tRetParams.ucOptValue, 4);
Kojto 0:615c697c33b0 372 return (0);
Kojto 0:615c697c33b0 373 }
Kojto 0:615c697c33b0 374 else
Kojto 0:615c697c33b0 375 {
Kojto 0:615c697c33b0 376 errno = tRetParams.iStatus;
Kojto 0:615c697c33b0 377 return errno;
Kojto 0:615c697c33b0 378 }
Kojto 0:615c697c33b0 379 }
Kojto 0:615c697c33b0 380
Kojto 0:615c697c33b0 381 int32_t cc3000_socket::simple_link_recv(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen, int32_t opcode) {
Kojto 0:615c697c33b0 382 uint8_t *ptr, *args;
Kojto 0:615c697c33b0 383 tBsdReadReturnParams tSocketReadEvent;
Kojto 0:615c697c33b0 384
Kojto 0:615c697c33b0 385 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 386 args = (ptr + HEADERS_SIZE_CMD);
Kojto 0:615c697c33b0 387
Kojto 0:615c697c33b0 388 // Fill in HCI packet structure
Kojto 0:615c697c33b0 389 args = UINT32_TO_STREAM(args, sd);
Kojto 0:615c697c33b0 390 args = UINT32_TO_STREAM(args, len);
Kojto 0:615c697c33b0 391 args = UINT32_TO_STREAM(args, flags);
Kojto 0:615c697c33b0 392
Kojto 0:615c697c33b0 393 // Generate the read command, and wait for the
Kojto 0:615c697c33b0 394 _hci.command_send(opcode, ptr, SOCKET_RECV_FROM_PARAMS_LEN);
Kojto 0:615c697c33b0 395
Kojto 0:615c697c33b0 396 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 397 _event.simplelink_wait_event(opcode, &tSocketReadEvent);
Kojto 0:615c697c33b0 398
Kojto 0:615c697c33b0 399 // In case the number of bytes is more then zero - read data
Kojto 0:615c697c33b0 400 if (tSocketReadEvent.iNumberOfBytes > 0)
Kojto 0:615c697c33b0 401 {
Kojto 0:615c697c33b0 402 // Wait for the data in a synchronous way. Here we assume that the bug is
Kojto 0:615c697c33b0 403 // big enough to store also parameters of receive from too....
Kojto 0:615c697c33b0 404 _event.simplelink_wait_data((uint8_t *)buf, (uint8_t *)from, (uint8_t *)fromlen);
Kojto 0:615c697c33b0 405 }
Kojto 0:615c697c33b0 406
Kojto 0:615c697c33b0 407 errno = tSocketReadEvent.iNumberOfBytes;
Kojto 0:615c697c33b0 408
Kojto 0:615c697c33b0 409 return(tSocketReadEvent.iNumberOfBytes);
Kojto 0:615c697c33b0 410 }
Kojto 0:615c697c33b0 411
Kojto 0:615c697c33b0 412 int32_t cc3000_socket::recv(int32_t sd, void *buf, int32_t len, int32_t flags) {
Kojto 0:615c697c33b0 413 return(simple_link_recv(sd, buf, len, flags, NULL, NULL, HCI_CMND_RECV));
Kojto 0:615c697c33b0 414 }
Kojto 0:615c697c33b0 415
Kojto 0:615c697c33b0 416 int32_t cc3000_socket::recvfrom(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen) {
Kojto 0:615c697c33b0 417 return(simple_link_recv(sd, buf, len, flags, from, fromlen, HCI_CMND_RECVFROM));
Kojto 0:615c697c33b0 418 }
Kojto 0:615c697c33b0 419
Kojto 0:615c697c33b0 420 int32_t cc3000_socket::simple_link_send(int32_t sd, const void *buf, int32_t len, int32_t flags, const sockaddr *to, int32_t tolen, int32_t opcode) {
Kojto 0:615c697c33b0 421 uint8_t uArgSize = 0x00, addrlen = 0x00;
Kojto 0:615c697c33b0 422 uint8_t *ptr, *pDataPtr = NULL, *args;
Kojto 0:615c697c33b0 423 uint32_t addr_offset = 0x00;
Kojto 0:615c697c33b0 424 int32_t res;
Kojto 0:615c697c33b0 425 tBsdReadReturnParams tSocketSendEvent;
Kojto 0:615c697c33b0 426
Kojto 0:615c697c33b0 427 // Check the bsd_arguments
Kojto 0:615c697c33b0 428 if (0 != (res = HostFlowControlConsumeBuff(sd)))
Kojto 0:615c697c33b0 429 {
Kojto 0:615c697c33b0 430 return res;
Kojto 0:615c697c33b0 431 }
Kojto 0:615c697c33b0 432
Kojto 0:615c697c33b0 433 //Update the number of sent packets
Kojto 0:615c697c33b0 434 uint16_t sent_packets = _simple_link.get_sent_packets();
Kojto 0:615c697c33b0 435 sent_packets++;
Kojto 0:615c697c33b0 436 _simple_link.set_sent_packets(sent_packets);
Kojto 0:615c697c33b0 437
Kojto 0:615c697c33b0 438 // Allocate a buffer and construct a packet and send it over spi
Kojto 0:615c697c33b0 439 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 440 args = (ptr + HEADERS_SIZE_DATA);
Kojto 0:615c697c33b0 441
Kojto 0:615c697c33b0 442 // Update the offset of data and parameters according to the command
Kojto 0:615c697c33b0 443 switch(opcode)
Kojto 0:615c697c33b0 444 {
Kojto 0:615c697c33b0 445 case HCI_CMND_SENDTO:
Kojto 0:615c697c33b0 446 {
Kojto 0:615c697c33b0 447 addr_offset = len + sizeof(len) + sizeof(len);
Kojto 0:615c697c33b0 448 addrlen = 8;
Kojto 0:615c697c33b0 449 uArgSize = SOCKET_SENDTO_PARAMS_LEN;
Kojto 0:615c697c33b0 450 pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN;
Kojto 0:615c697c33b0 451 break;
Kojto 0:615c697c33b0 452 }
Kojto 0:615c697c33b0 453
Kojto 0:615c697c33b0 454 case HCI_CMND_SEND:
Kojto 0:615c697c33b0 455 {
Kojto 0:615c697c33b0 456 tolen = 0;
Kojto 0:615c697c33b0 457 to = NULL;
Kojto 0:615c697c33b0 458 uArgSize = HCI_CMND_SEND_ARG_LENGTH;
Kojto 0:615c697c33b0 459 pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH;
Kojto 0:615c697c33b0 460 break;
Kojto 0:615c697c33b0 461 }
Kojto 0:615c697c33b0 462
Kojto 0:615c697c33b0 463 default:
Kojto 0:615c697c33b0 464 {
Kojto 0:615c697c33b0 465 break;
Kojto 0:615c697c33b0 466 }
Kojto 0:615c697c33b0 467 }
Kojto 0:615c697c33b0 468
Kojto 0:615c697c33b0 469 // Fill in temporary command buffer
Kojto 0:615c697c33b0 470 args = UINT32_TO_STREAM(args, sd);
Kojto 0:615c697c33b0 471 args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd));
Kojto 0:615c697c33b0 472 args = UINT32_TO_STREAM(args, len);
Kojto 0:615c697c33b0 473 args = UINT32_TO_STREAM(args, flags);
Kojto 0:615c697c33b0 474
Kojto 0:615c697c33b0 475 if (opcode == HCI_CMND_SENDTO)
Kojto 0:615c697c33b0 476 {
Kojto 0:615c697c33b0 477 args = UINT32_TO_STREAM(args, addr_offset);
Kojto 0:615c697c33b0 478 args = UINT32_TO_STREAM(args, addrlen);
Kojto 0:615c697c33b0 479 }
Kojto 0:615c697c33b0 480
Kojto 0:615c697c33b0 481 // Copy the data received from user into the TX Buffer
Kojto 0:615c697c33b0 482 ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)buf), len);
Kojto 0:615c697c33b0 483
Kojto 0:615c697c33b0 484 // In case we are using SendTo, copy the to parameters
Kojto 0:615c697c33b0 485 if (opcode == HCI_CMND_SENDTO)
Kojto 0:615c697c33b0 486 {
Kojto 0:615c697c33b0 487 ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)to), tolen);
Kojto 0:615c697c33b0 488 }
Kojto 0:615c697c33b0 489
Kojto 0:615c697c33b0 490 // Initiate a HCI command
Kojto 0:615c697c33b0 491 _hci.data_send(opcode, ptr, uArgSize, len,(uint8_t*)to, tolen);
Kojto 0:615c697c33b0 492 if (opcode == HCI_CMND_SENDTO)
Kojto 0:615c697c33b0 493 _event.simplelink_wait_event(HCI_EVNT_SENDTO, &tSocketSendEvent);
Kojto 0:615c697c33b0 494 else
Kojto 0:615c697c33b0 495 _event.simplelink_wait_event(HCI_EVNT_SEND, &tSocketSendEvent);
Kojto 0:615c697c33b0 496
Kojto 0:615c697c33b0 497 return (len);
Kojto 0:615c697c33b0 498 }
Kojto 0:615c697c33b0 499
Kojto 0:615c697c33b0 500 int32_t cc3000_socket::send(int32_t sd, const void *buf, int32_t len, int32_t flags) {
Kojto 0:615c697c33b0 501 return(simple_link_send(sd, buf, len, flags, NULL, 0, HCI_CMND_SEND));
Kojto 0:615c697c33b0 502 }
Kojto 0:615c697c33b0 503
Kojto 0:615c697c33b0 504 int32_t cc3000_socket::sendto(int32_t sd, const void *buf, int32_t len, int32_t flags, const sockaddr *to, socklen_t tolen) {
Kojto 0:615c697c33b0 505 return(simple_link_send(sd, buf, len, flags, to, tolen, HCI_CMND_SENDTO));
Kojto 0:615c697c33b0 506 }
Kojto 0:615c697c33b0 507
Kojto 0:615c697c33b0 508 int32_t cc3000_socket::mdns_advertiser(uint16_t mdns_enabled, uint8_t *device_service_name, uint16_t device_service_name_length) {
Kojto 0:615c697c33b0 509 int32_t ret;
Kojto 0:615c697c33b0 510 uint8_t *pTxBuffer, *pArgs;
Kojto 0:615c697c33b0 511
Kojto 0:615c697c33b0 512 if (device_service_name_length > MDNS_DEVICE_SERVICE_MAX_LENGTH)
Kojto 0:615c697c33b0 513 {
Kojto 0:615c697c33b0 514 return EFAIL;
Kojto 0:615c697c33b0 515 }
Kojto 0:615c697c33b0 516
Kojto 0:615c697c33b0 517 pTxBuffer = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 518 pArgs = (pTxBuffer + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
Kojto 0:615c697c33b0 519
Kojto 0:615c697c33b0 520 // Fill in HCI packet structure
Kojto 0:615c697c33b0 521 pArgs = UINT32_TO_STREAM(pArgs, mdns_enabled);
Kojto 0:615c697c33b0 522 pArgs = UINT32_TO_STREAM(pArgs, 8);
Kojto 0:615c697c33b0 523 pArgs = UINT32_TO_STREAM(pArgs, device_service_name_length);
Kojto 0:615c697c33b0 524 ARRAY_TO_STREAM(pArgs, device_service_name, device_service_name_length);
Kojto 0:615c697c33b0 525
Kojto 0:615c697c33b0 526 // Initiate a HCI command
Kojto 0:615c697c33b0 527 _hci.command_send(HCI_CMND_MDNS_ADVERTISE, pTxBuffer, SOCKET_MDNS_ADVERTISE_PARAMS_LEN + device_service_name_length);
Kojto 0:615c697c33b0 528
Kojto 0:615c697c33b0 529 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 530 _event.simplelink_wait_event(HCI_EVNT_MDNS_ADVERTISE, &ret);
Kojto 0:615c697c33b0 531
Kojto 0:615c697c33b0 532 return ret;
Kojto 0:615c697c33b0 533 }
Kojto 0:615c697c33b0 534
Kojto 0:615c697c33b0 535
Kojto 0:615c697c33b0 536 #ifndef CC3000_TINY_DRIVER
SolderSplashLabs 11:5e3771b29385 537
SolderSplashLabs 11:5e3771b29385 538 int32_t cc3000_socket::gethostbyname(uint8_t *hostname, uint16_t name_length, uint32_t *out_ip_addr) {
SolderSplashLabs 11:5e3771b29385 539 get_host_by_name(hostname, name_length, out_ip_addr);
SolderSplashLabs 11:5e3771b29385 540 }
SolderSplashLabs 11:5e3771b29385 541
Kojto 0:615c697c33b0 542 int32_t cc3000_socket::get_host_by_name(uint8_t *hostname, uint16_t name_length, uint32_t *out_ip_addr) {
Kojto 0:615c697c33b0 543 tBsdGethostbynameParams ret;
Kojto 0:615c697c33b0 544 uint8_t *ptr, *args;
Kojto 0:615c697c33b0 545
Kojto 0:615c697c33b0 546 errno = EFAIL;
Kojto 0:615c697c33b0 547
Kojto 0:615c697c33b0 548 if (name_length > HOSTNAME_MAX_LENGTH)
Kojto 0:615c697c33b0 549 {
Kojto 0:615c697c33b0 550 return errno;
Kojto 0:615c697c33b0 551 }
Kojto 0:615c697c33b0 552
Kojto 0:615c697c33b0 553 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 554 args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
Kojto 0:615c697c33b0 555
Kojto 0:615c697c33b0 556 // Fill in HCI packet structure
Kojto 0:615c697c33b0 557 args = UINT32_TO_STREAM(args, 8);
Kojto 0:615c697c33b0 558 args = UINT32_TO_STREAM(args, name_length);
Kojto 0:615c697c33b0 559 ARRAY_TO_STREAM(args, hostname, name_length);
Kojto 0:615c697c33b0 560
Kojto 0:615c697c33b0 561 // Initiate a HCI command
Kojto 0:615c697c33b0 562 _hci.command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN + name_length - 1);
Kojto 0:615c697c33b0 563
Kojto 0:615c697c33b0 564 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 565 _event.simplelink_wait_event(HCI_EVNT_BSD_GETHOSTBYNAME, &ret);
Kojto 0:615c697c33b0 566
Kojto 0:615c697c33b0 567 errno = ret.retVal;
Kojto 0:615c697c33b0 568
Kojto 0:615c697c33b0 569 (*((int32_t*)out_ip_addr)) = ret.outputAddress;
Kojto 0:615c697c33b0 570
Kojto 0:615c697c33b0 571 return (errno);
Kojto 0:615c697c33b0 572 }
Kojto 0:615c697c33b0 573
Kojto 0:615c697c33b0 574 int32_t cc3000_socket::set_sockopt(int32_t sd, int32_t level, int32_t optname, const void *optval, socklen_t optlen) {
Kojto 0:615c697c33b0 575 int32_t ret;
Kojto 0:615c697c33b0 576 uint8_t *ptr, *args;
Kojto 0:615c697c33b0 577
Kojto 0:615c697c33b0 578 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 579 args = (ptr + HEADERS_SIZE_CMD);
Kojto 0:615c697c33b0 580
Kojto 0:615c697c33b0 581 // Fill in temporary command buffer
Kojto 0:615c697c33b0 582 args = UINT32_TO_STREAM(args, sd);
Kojto 0:615c697c33b0 583 args = UINT32_TO_STREAM(args, level);
Kojto 0:615c697c33b0 584 args = UINT32_TO_STREAM(args, optname);
Kojto 0:615c697c33b0 585 args = UINT32_TO_STREAM(args, 0x00000008);
Kojto 0:615c697c33b0 586 args = UINT32_TO_STREAM(args, optlen);
Kojto 0:615c697c33b0 587 ARRAY_TO_STREAM(args, ((uint8_t *)optval), optlen);
Kojto 0:615c697c33b0 588
Kojto 0:615c697c33b0 589 // Initiate a HCI command
Kojto 0:615c697c33b0 590 _hci.command_send(HCI_CMND_SETSOCKOPT, ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN + optlen);
Kojto 0:615c697c33b0 591
Kojto 0:615c697c33b0 592 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 593 _event.simplelink_wait_event(HCI_CMND_SETSOCKOPT, &ret);
Kojto 0:615c697c33b0 594
Kojto 0:615c697c33b0 595 if (ret >= 0)
Kojto 0:615c697c33b0 596 {
Kojto 0:615c697c33b0 597 return (0);
Kojto 0:615c697c33b0 598 }
Kojto 0:615c697c33b0 599 else
Kojto 0:615c697c33b0 600 {
Kojto 0:615c697c33b0 601 errno = ret;
Kojto 0:615c697c33b0 602 return ret;
Kojto 0:615c697c33b0 603 }
Kojto 0:615c697c33b0 604 }
Kojto 0:615c697c33b0 605
Kojto 0:615c697c33b0 606 #endif
Kojto 0:615c697c33b0 607
Kojto 0:615c697c33b0 608 } /* end of cc3000 namespace */