cc3000 hostdriver with the mbed socket interface

Dependents:   cc3000_hello_world_demo cc3000_simple_socket_demo cc3000_ntp_demo cc3000_ping_demo ... more

Committer:
Kojto
Date:
Thu Sep 19 07:55:14 2013 +0000
Revision:
0:615c697c33b0
Child:
4:15b58c119a0a
initial commit

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 0:615c697c33b0 92 if(SOCKET_STATUS_ACTIVE != 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 0:615c697c33b0 104 uint16 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 0:615c697c33b0 143 ret = EFAIL;
Kojto 0:615c697c33b0 144 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 145 args = (ptr + HEADERS_SIZE_CMD);
Kojto 0:615c697c33b0 146
Kojto 0:615c697c33b0 147 // Fill in HCI packet structure
Kojto 0:615c697c33b0 148 args = UINT32_TO_STREAM(args, sd);
Kojto 0:615c697c33b0 149
Kojto 0:615c697c33b0 150 // Initiate a HCI command
Kojto 0:615c697c33b0 151 _hci.command_send(HCI_CMND_CLOSE_SOCKET, ptr, SOCKET_CLOSE_PARAMS_LEN);
Kojto 0:615c697c33b0 152
Kojto 0:615c697c33b0 153 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 154 _event.simplelink_wait_event(HCI_CMND_CLOSE_SOCKET, &ret);
Kojto 0:615c697c33b0 155 errno = ret;
Kojto 0:615c697c33b0 156
Kojto 0:615c697c33b0 157 // since 'close' call may result in either OK (and then it closed) or error, mark this socket as invalid
Kojto 0:615c697c33b0 158 _event.set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
Kojto 0:615c697c33b0 159
Kojto 0:615c697c33b0 160 return(ret);
Kojto 0:615c697c33b0 161 }
Kojto 0:615c697c33b0 162
Kojto 0:615c697c33b0 163 int32_t cc3000_socket::accept(int32_t sd, sockaddr *addr, socklen_t *addrlen) {
Kojto 0:615c697c33b0 164 int32_t ret;
Kojto 0:615c697c33b0 165 uint8_t *ptr, *args;
Kojto 0:615c697c33b0 166 tBsdReturnParams tAcceptReturnArguments;
Kojto 0:615c697c33b0 167
Kojto 0:615c697c33b0 168 ret = EFAIL;
Kojto 0:615c697c33b0 169 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 170 args = (ptr + HEADERS_SIZE_CMD);
Kojto 0:615c697c33b0 171
Kojto 0:615c697c33b0 172 // Fill in temporary command buffer
Kojto 0:615c697c33b0 173 args = UINT32_TO_STREAM(args, sd);
Kojto 0:615c697c33b0 174
Kojto 0:615c697c33b0 175 // Initiate a HCI command
Kojto 0:615c697c33b0 176 _hci.command_send(HCI_CMND_ACCEPT, ptr, SOCKET_ACCEPT_PARAMS_LEN);
Kojto 0:615c697c33b0 177
Kojto 0:615c697c33b0 178 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 179 _event.simplelink_wait_event(HCI_CMND_ACCEPT, &tAcceptReturnArguments);
Kojto 0:615c697c33b0 180
Kojto 0:615c697c33b0 181
Kojto 0:615c697c33b0 182 // need specify return parameters!!!
Kojto 0:615c697c33b0 183 memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN);
Kojto 0:615c697c33b0 184 *addrlen = ASIC_ADDR_LEN;
Kojto 0:615c697c33b0 185 errno = tAcceptReturnArguments.iStatus;
Kojto 0:615c697c33b0 186 ret = errno;
Kojto 0:615c697c33b0 187
Kojto 0:615c697c33b0 188 // if succeeded, iStatus = new socket descriptor. otherwise - error number
Kojto 0:615c697c33b0 189 if(M_IS_VALID_SD(ret))
Kojto 0:615c697c33b0 190 {
Kojto 0:615c697c33b0 191 _event.set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
Kojto 0:615c697c33b0 192 }
Kojto 0:615c697c33b0 193 else
Kojto 0:615c697c33b0 194 {
Kojto 0:615c697c33b0 195 _event.set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
Kojto 0:615c697c33b0 196 }
Kojto 0:615c697c33b0 197
Kojto 0:615c697c33b0 198 return(ret);
Kojto 0:615c697c33b0 199 }
Kojto 0:615c697c33b0 200
Kojto 0:615c697c33b0 201 int32_t cc3000_socket::bind(int32_t sd, const sockaddr *addr, int32_t addrlen) {
Kojto 0:615c697c33b0 202 int32_t ret;
Kojto 0:615c697c33b0 203 uint8_t *ptr, *args;
Kojto 0:615c697c33b0 204
Kojto 0:615c697c33b0 205 ret = EFAIL;
Kojto 0:615c697c33b0 206 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 207 args = (ptr + HEADERS_SIZE_CMD);
Kojto 0:615c697c33b0 208
Kojto 0:615c697c33b0 209 addrlen = ASIC_ADDR_LEN;
Kojto 0:615c697c33b0 210
Kojto 0:615c697c33b0 211 // Fill in temporary command buffer
Kojto 0:615c697c33b0 212 args = UINT32_TO_STREAM(args, sd);
Kojto 0:615c697c33b0 213 args = UINT32_TO_STREAM(args, 0x00000008);
Kojto 0:615c697c33b0 214 args = UINT32_TO_STREAM(args, addrlen);
Kojto 0:615c697c33b0 215 ARRAY_TO_STREAM(args, ((uint8_t *)addr), addrlen);
Kojto 0:615c697c33b0 216
Kojto 0:615c697c33b0 217 // Initiate a HCI command
Kojto 0:615c697c33b0 218 _hci.command_send(HCI_CMND_BIND, ptr, SOCKET_BIND_PARAMS_LEN);
Kojto 0:615c697c33b0 219
Kojto 0:615c697c33b0 220 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 221 _event.simplelink_wait_event(HCI_CMND_BIND, &ret);
Kojto 0:615c697c33b0 222
Kojto 0:615c697c33b0 223 errno = ret;
Kojto 0:615c697c33b0 224
Kojto 0:615c697c33b0 225 return(ret);
Kojto 0:615c697c33b0 226 }
Kojto 0:615c697c33b0 227
Kojto 0:615c697c33b0 228 int32_t cc3000_socket::listen(int32_t sd, int32_t backlog) {
Kojto 0:615c697c33b0 229 int32_t ret;
Kojto 0:615c697c33b0 230 uint8_t *ptr, *args;
Kojto 0:615c697c33b0 231
Kojto 0:615c697c33b0 232 ret = EFAIL;
Kojto 0:615c697c33b0 233 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 234 args = (ptr + HEADERS_SIZE_CMD);
Kojto 0:615c697c33b0 235
Kojto 0:615c697c33b0 236 // Fill in temporary command buffer
Kojto 0:615c697c33b0 237 args = UINT32_TO_STREAM(args, sd);
Kojto 0:615c697c33b0 238 args = UINT32_TO_STREAM(args, backlog);
Kojto 0:615c697c33b0 239
Kojto 0:615c697c33b0 240 // Initiate a HCI command
Kojto 0:615c697c33b0 241 _hci.command_send(HCI_CMND_LISTEN, ptr, SOCKET_LISTEN_PARAMS_LEN);
Kojto 0:615c697c33b0 242
Kojto 0:615c697c33b0 243 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 244 _event.simplelink_wait_event(HCI_CMND_LISTEN, &ret);
Kojto 0:615c697c33b0 245 errno = ret;
Kojto 0:615c697c33b0 246
Kojto 0:615c697c33b0 247 return(ret);
Kojto 0:615c697c33b0 248 }
Kojto 0:615c697c33b0 249
Kojto 0:615c697c33b0 250 int32_t cc3000_socket::connect(int32_t sd, const sockaddr *addr, int32_t addrlen) {
Kojto 0:615c697c33b0 251 int32_t ret;
Kojto 0:615c697c33b0 252 uint8_t *ptr, *args;
Kojto 0:615c697c33b0 253
Kojto 0:615c697c33b0 254 ret = EFAIL;
Kojto 0:615c697c33b0 255 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 256 args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
Kojto 0:615c697c33b0 257 addrlen = 8;
Kojto 0:615c697c33b0 258
Kojto 0:615c697c33b0 259 // Fill in temporary command buffer
Kojto 0:615c697c33b0 260 args = UINT32_TO_STREAM(args, sd);
Kojto 0:615c697c33b0 261 args = UINT32_TO_STREAM(args, 0x00000008);
Kojto 0:615c697c33b0 262 args = UINT32_TO_STREAM(args, addrlen);
Kojto 0:615c697c33b0 263 ARRAY_TO_STREAM(args, ((uint8_t *)addr), addrlen);
Kojto 0:615c697c33b0 264
Kojto 0:615c697c33b0 265 // Initiate a HCI command
Kojto 0:615c697c33b0 266 _hci.command_send(HCI_CMND_CONNECT, ptr, SOCKET_CONNECT_PARAMS_LEN);
Kojto 0:615c697c33b0 267
Kojto 0:615c697c33b0 268 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 269 _event.simplelink_wait_event(HCI_CMND_CONNECT, &ret);
Kojto 0:615c697c33b0 270
Kojto 0:615c697c33b0 271 errno = ret;
Kojto 0:615c697c33b0 272
Kojto 0:615c697c33b0 273 return((int32_t)ret);
Kojto 0:615c697c33b0 274 }
Kojto 0:615c697c33b0 275
Kojto 0:615c697c33b0 276 int32_t cc3000_socket::select(int32_t nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, struct timeval *timeout) {
Kojto 0:615c697c33b0 277 uint8_t *ptr, *args;
Kojto 0:615c697c33b0 278 tBsdSelectRecvParams tParams;
Kojto 0:615c697c33b0 279 uint32_t is_blocking;
Kojto 0:615c697c33b0 280
Kojto 0:615c697c33b0 281 if( timeout == NULL)
Kojto 0:615c697c33b0 282 {
Kojto 0:615c697c33b0 283 is_blocking = 1; /* blocking , infinity timeout */
Kojto 0:615c697c33b0 284 }
Kojto 0:615c697c33b0 285 else
Kojto 0:615c697c33b0 286 {
Kojto 0:615c697c33b0 287 is_blocking = 0; /* no blocking, timeout */
Kojto 0:615c697c33b0 288 }
Kojto 0:615c697c33b0 289
Kojto 0:615c697c33b0 290 // Fill in HCI packet structure
Kojto 0:615c697c33b0 291 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 292 args = (ptr + HEADERS_SIZE_CMD);
Kojto 0:615c697c33b0 293
Kojto 0:615c697c33b0 294 // Fill in temporary command buffer
Kojto 0:615c697c33b0 295 args = UINT32_TO_STREAM(args, nfds);
Kojto 0:615c697c33b0 296 args = UINT32_TO_STREAM(args, 0x00000014);
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, is_blocking);
Kojto 0:615c697c33b0 301 args = UINT32_TO_STREAM(args, ((readsds) ? *(uint32_t*)readsds : 0));
Kojto 0:615c697c33b0 302 args = UINT32_TO_STREAM(args, ((writesds) ? *(uint32_t*)writesds : 0));
Kojto 0:615c697c33b0 303 args = UINT32_TO_STREAM(args, ((exceptsds) ? *(uint32_t*)exceptsds : 0));
Kojto 0:615c697c33b0 304
Kojto 0:615c697c33b0 305 if (timeout)
Kojto 0:615c697c33b0 306 {
Kojto 0:615c697c33b0 307 if ( 0 == timeout->tv_sec && timeout->tv_usec < SELECT_TIMEOUT_MIN_MICRO_SECONDS)
Kojto 0:615c697c33b0 308 {
Kojto 0:615c697c33b0 309 timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS;
Kojto 0:615c697c33b0 310 }
Kojto 0:615c697c33b0 311 args = UINT32_TO_STREAM(args, timeout->tv_sec);
Kojto 0:615c697c33b0 312 args = UINT32_TO_STREAM(args, timeout->tv_usec);
Kojto 0:615c697c33b0 313 }
Kojto 0:615c697c33b0 314
Kojto 0:615c697c33b0 315 // Initiate a HCI command
Kojto 0:615c697c33b0 316 _hci.command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN);
Kojto 0:615c697c33b0 317
Kojto 0:615c697c33b0 318 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 319 _event.simplelink_wait_event(HCI_EVNT_SELECT, &tParams);
Kojto 0:615c697c33b0 320
Kojto 0:615c697c33b0 321 // Update actually read FD
Kojto 0:615c697c33b0 322 if (tParams.iStatus >= 0)
Kojto 0:615c697c33b0 323 {
Kojto 0:615c697c33b0 324 if (readsds)
Kojto 0:615c697c33b0 325 {
Kojto 0:615c697c33b0 326 memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd));
Kojto 0:615c697c33b0 327 }
Kojto 0:615c697c33b0 328
Kojto 0:615c697c33b0 329 if (writesds)
Kojto 0:615c697c33b0 330 {
Kojto 0:615c697c33b0 331 memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd));
Kojto 0:615c697c33b0 332 }
Kojto 0:615c697c33b0 333
Kojto 0:615c697c33b0 334 if (exceptsds)
Kojto 0:615c697c33b0 335 {
Kojto 0:615c697c33b0 336 memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd));
Kojto 0:615c697c33b0 337 }
Kojto 0:615c697c33b0 338
Kojto 0:615c697c33b0 339 return(tParams.iStatus);
Kojto 0:615c697c33b0 340
Kojto 0:615c697c33b0 341 }
Kojto 0:615c697c33b0 342 else
Kojto 0:615c697c33b0 343 {
Kojto 0:615c697c33b0 344 errno = tParams.iStatus;
Kojto 0:615c697c33b0 345 return(-1);
Kojto 0:615c697c33b0 346 }
Kojto 0:615c697c33b0 347 }
Kojto 0:615c697c33b0 348
Kojto 0:615c697c33b0 349 int32_t cc3000_socket::get_sockopt (int32_t sd, int32_t level, int32_t optname, void *optval, socklen_t *optlen) {
Kojto 0:615c697c33b0 350 uint8_t *ptr, *args;
Kojto 0:615c697c33b0 351 tBsdGetSockOptReturnParams tRetParams;
Kojto 0:615c697c33b0 352
Kojto 0:615c697c33b0 353 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 354 args = (ptr + HEADERS_SIZE_CMD);
Kojto 0:615c697c33b0 355
Kojto 0:615c697c33b0 356 // Fill in temporary command buffer
Kojto 0:615c697c33b0 357 args = UINT32_TO_STREAM(args, sd);
Kojto 0:615c697c33b0 358 args = UINT32_TO_STREAM(args, level);
Kojto 0:615c697c33b0 359 args = UINT32_TO_STREAM(args, optname);
Kojto 0:615c697c33b0 360
Kojto 0:615c697c33b0 361 // Initiate a HCI command
Kojto 0:615c697c33b0 362 _hci.command_send(HCI_CMND_GETSOCKOPT, ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN);
Kojto 0:615c697c33b0 363
Kojto 0:615c697c33b0 364 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 365 _event.simplelink_wait_event(HCI_CMND_GETSOCKOPT, &tRetParams);
Kojto 0:615c697c33b0 366
Kojto 0:615c697c33b0 367 if (((int8_t)tRetParams.iStatus) >= 0)
Kojto 0:615c697c33b0 368 {
Kojto 0:615c697c33b0 369 *optlen = 4;
Kojto 0:615c697c33b0 370 memcpy(optval, tRetParams.ucOptValue, 4);
Kojto 0:615c697c33b0 371 return (0);
Kojto 0:615c697c33b0 372 }
Kojto 0:615c697c33b0 373 else
Kojto 0:615c697c33b0 374 {
Kojto 0:615c697c33b0 375 errno = tRetParams.iStatus;
Kojto 0:615c697c33b0 376 return errno;
Kojto 0:615c697c33b0 377 }
Kojto 0:615c697c33b0 378 }
Kojto 0:615c697c33b0 379
Kojto 0:615c697c33b0 380 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 381 uint8_t *ptr, *args;
Kojto 0:615c697c33b0 382 tBsdReadReturnParams tSocketReadEvent;
Kojto 0:615c697c33b0 383
Kojto 0:615c697c33b0 384 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 385 args = (ptr + HEADERS_SIZE_CMD);
Kojto 0:615c697c33b0 386
Kojto 0:615c697c33b0 387 // Fill in HCI packet structure
Kojto 0:615c697c33b0 388 args = UINT32_TO_STREAM(args, sd);
Kojto 0:615c697c33b0 389 args = UINT32_TO_STREAM(args, len);
Kojto 0:615c697c33b0 390 args = UINT32_TO_STREAM(args, flags);
Kojto 0:615c697c33b0 391
Kojto 0:615c697c33b0 392 // Generate the read command, and wait for the
Kojto 0:615c697c33b0 393 _hci.command_send(opcode, ptr, SOCKET_RECV_FROM_PARAMS_LEN);
Kojto 0:615c697c33b0 394
Kojto 0:615c697c33b0 395 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 396 _event.simplelink_wait_event(opcode, &tSocketReadEvent);
Kojto 0:615c697c33b0 397
Kojto 0:615c697c33b0 398 // In case the number of bytes is more then zero - read data
Kojto 0:615c697c33b0 399 if (tSocketReadEvent.iNumberOfBytes > 0)
Kojto 0:615c697c33b0 400 {
Kojto 0:615c697c33b0 401 // Wait for the data in a synchronous way. Here we assume that the bug is
Kojto 0:615c697c33b0 402 // big enough to store also parameters of receive from too....
Kojto 0:615c697c33b0 403 _event.simplelink_wait_data((uint8_t *)buf, (uint8_t *)from, (uint8_t *)fromlen);
Kojto 0:615c697c33b0 404 }
Kojto 0:615c697c33b0 405
Kojto 0:615c697c33b0 406 errno = tSocketReadEvent.iNumberOfBytes;
Kojto 0:615c697c33b0 407
Kojto 0:615c697c33b0 408 return(tSocketReadEvent.iNumberOfBytes);
Kojto 0:615c697c33b0 409 }
Kojto 0:615c697c33b0 410
Kojto 0:615c697c33b0 411 int32_t cc3000_socket::recv(int32_t sd, void *buf, int32_t len, int32_t flags) {
Kojto 0:615c697c33b0 412 return(simple_link_recv(sd, buf, len, flags, NULL, NULL, HCI_CMND_RECV));
Kojto 0:615c697c33b0 413 }
Kojto 0:615c697c33b0 414
Kojto 0:615c697c33b0 415 int32_t cc3000_socket::recvfrom(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen) {
Kojto 0:615c697c33b0 416 return(simple_link_recv(sd, buf, len, flags, from, fromlen, HCI_CMND_RECVFROM));
Kojto 0:615c697c33b0 417 }
Kojto 0:615c697c33b0 418
Kojto 0:615c697c33b0 419 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 420 uint8_t uArgSize = 0x00, addrlen = 0x00;
Kojto 0:615c697c33b0 421 uint8_t *ptr, *pDataPtr = NULL, *args;
Kojto 0:615c697c33b0 422 uint32_t addr_offset = 0x00;
Kojto 0:615c697c33b0 423 int32_t res;
Kojto 0:615c697c33b0 424 tBsdReadReturnParams tSocketSendEvent;
Kojto 0:615c697c33b0 425
Kojto 0:615c697c33b0 426 // Check the bsd_arguments
Kojto 0:615c697c33b0 427 if (0 != (res = HostFlowControlConsumeBuff(sd)))
Kojto 0:615c697c33b0 428 {
Kojto 0:615c697c33b0 429 return res;
Kojto 0:615c697c33b0 430 }
Kojto 0:615c697c33b0 431
Kojto 0:615c697c33b0 432 //Update the number of sent packets
Kojto 0:615c697c33b0 433 uint16_t sent_packets = _simple_link.get_sent_packets();
Kojto 0:615c697c33b0 434 sent_packets++;
Kojto 0:615c697c33b0 435 _simple_link.set_sent_packets(sent_packets);
Kojto 0:615c697c33b0 436
Kojto 0:615c697c33b0 437 // Allocate a buffer and construct a packet and send it over spi
Kojto 0:615c697c33b0 438 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 439 args = (ptr + HEADERS_SIZE_DATA);
Kojto 0:615c697c33b0 440
Kojto 0:615c697c33b0 441 // Update the offset of data and parameters according to the command
Kojto 0:615c697c33b0 442 switch(opcode)
Kojto 0:615c697c33b0 443 {
Kojto 0:615c697c33b0 444 case HCI_CMND_SENDTO:
Kojto 0:615c697c33b0 445 {
Kojto 0:615c697c33b0 446 addr_offset = len + sizeof(len) + sizeof(len);
Kojto 0:615c697c33b0 447 addrlen = 8;
Kojto 0:615c697c33b0 448 uArgSize = SOCKET_SENDTO_PARAMS_LEN;
Kojto 0:615c697c33b0 449 pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN;
Kojto 0:615c697c33b0 450 break;
Kojto 0:615c697c33b0 451 }
Kojto 0:615c697c33b0 452
Kojto 0:615c697c33b0 453 case HCI_CMND_SEND:
Kojto 0:615c697c33b0 454 {
Kojto 0:615c697c33b0 455 tolen = 0;
Kojto 0:615c697c33b0 456 to = NULL;
Kojto 0:615c697c33b0 457 uArgSize = HCI_CMND_SEND_ARG_LENGTH;
Kojto 0:615c697c33b0 458 pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH;
Kojto 0:615c697c33b0 459 break;
Kojto 0:615c697c33b0 460 }
Kojto 0:615c697c33b0 461
Kojto 0:615c697c33b0 462 default:
Kojto 0:615c697c33b0 463 {
Kojto 0:615c697c33b0 464 break;
Kojto 0:615c697c33b0 465 }
Kojto 0:615c697c33b0 466 }
Kojto 0:615c697c33b0 467
Kojto 0:615c697c33b0 468 // Fill in temporary command buffer
Kojto 0:615c697c33b0 469 args = UINT32_TO_STREAM(args, sd);
Kojto 0:615c697c33b0 470 args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd));
Kojto 0:615c697c33b0 471 args = UINT32_TO_STREAM(args, len);
Kojto 0:615c697c33b0 472 args = UINT32_TO_STREAM(args, flags);
Kojto 0:615c697c33b0 473
Kojto 0:615c697c33b0 474 if (opcode == HCI_CMND_SENDTO)
Kojto 0:615c697c33b0 475 {
Kojto 0:615c697c33b0 476 args = UINT32_TO_STREAM(args, addr_offset);
Kojto 0:615c697c33b0 477 args = UINT32_TO_STREAM(args, addrlen);
Kojto 0:615c697c33b0 478 }
Kojto 0:615c697c33b0 479
Kojto 0:615c697c33b0 480 // Copy the data received from user into the TX Buffer
Kojto 0:615c697c33b0 481 ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)buf), len);
Kojto 0:615c697c33b0 482
Kojto 0:615c697c33b0 483 // In case we are using SendTo, copy the to parameters
Kojto 0:615c697c33b0 484 if (opcode == HCI_CMND_SENDTO)
Kojto 0:615c697c33b0 485 {
Kojto 0:615c697c33b0 486 ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)to), tolen);
Kojto 0:615c697c33b0 487 }
Kojto 0:615c697c33b0 488
Kojto 0:615c697c33b0 489 // Initiate a HCI command
Kojto 0:615c697c33b0 490 _hci.data_send(opcode, ptr, uArgSize, len,(uint8_t*)to, tolen);
Kojto 0:615c697c33b0 491 if (opcode == HCI_CMND_SENDTO)
Kojto 0:615c697c33b0 492 _event.simplelink_wait_event(HCI_EVNT_SENDTO, &tSocketSendEvent);
Kojto 0:615c697c33b0 493 else
Kojto 0:615c697c33b0 494 _event.simplelink_wait_event(HCI_EVNT_SEND, &tSocketSendEvent);
Kojto 0:615c697c33b0 495
Kojto 0:615c697c33b0 496 return (len);
Kojto 0:615c697c33b0 497 }
Kojto 0:615c697c33b0 498
Kojto 0:615c697c33b0 499 int32_t cc3000_socket::send(int32_t sd, const void *buf, int32_t len, int32_t flags) {
Kojto 0:615c697c33b0 500 return(simple_link_send(sd, buf, len, flags, NULL, 0, HCI_CMND_SEND));
Kojto 0:615c697c33b0 501 }
Kojto 0:615c697c33b0 502
Kojto 0:615c697c33b0 503 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 504 return(simple_link_send(sd, buf, len, flags, to, tolen, HCI_CMND_SENDTO));
Kojto 0:615c697c33b0 505 }
Kojto 0:615c697c33b0 506
Kojto 0:615c697c33b0 507 int32_t cc3000_socket::mdns_advertiser(uint16_t mdns_enabled, uint8_t *device_service_name, uint16_t device_service_name_length) {
Kojto 0:615c697c33b0 508 int32_t ret;
Kojto 0:615c697c33b0 509 uint8_t *pTxBuffer, *pArgs;
Kojto 0:615c697c33b0 510
Kojto 0:615c697c33b0 511 if (device_service_name_length > MDNS_DEVICE_SERVICE_MAX_LENGTH)
Kojto 0:615c697c33b0 512 {
Kojto 0:615c697c33b0 513 return EFAIL;
Kojto 0:615c697c33b0 514 }
Kojto 0:615c697c33b0 515
Kojto 0:615c697c33b0 516 pTxBuffer = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 517 pArgs = (pTxBuffer + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
Kojto 0:615c697c33b0 518
Kojto 0:615c697c33b0 519 // Fill in HCI packet structure
Kojto 0:615c697c33b0 520 pArgs = UINT32_TO_STREAM(pArgs, mdns_enabled);
Kojto 0:615c697c33b0 521 pArgs = UINT32_TO_STREAM(pArgs, 8);
Kojto 0:615c697c33b0 522 pArgs = UINT32_TO_STREAM(pArgs, device_service_name_length);
Kojto 0:615c697c33b0 523 ARRAY_TO_STREAM(pArgs, device_service_name, device_service_name_length);
Kojto 0:615c697c33b0 524
Kojto 0:615c697c33b0 525 // Initiate a HCI command
Kojto 0:615c697c33b0 526 _hci.command_send(HCI_CMND_MDNS_ADVERTISE, pTxBuffer, SOCKET_MDNS_ADVERTISE_PARAMS_LEN + device_service_name_length);
Kojto 0:615c697c33b0 527
Kojto 0:615c697c33b0 528 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 529 _event.simplelink_wait_event(HCI_EVNT_MDNS_ADVERTISE, &ret);
Kojto 0:615c697c33b0 530
Kojto 0:615c697c33b0 531 return ret;
Kojto 0:615c697c33b0 532 }
Kojto 0:615c697c33b0 533
Kojto 0:615c697c33b0 534
Kojto 0:615c697c33b0 535 #ifndef CC3000_TINY_DRIVER
Kojto 0:615c697c33b0 536 int32_t cc3000_socket::get_host_by_name(uint8_t *hostname, uint16_t name_length, uint32_t *out_ip_addr) {
Kojto 0:615c697c33b0 537 tBsdGethostbynameParams ret;
Kojto 0:615c697c33b0 538 uint8_t *ptr, *args;
Kojto 0:615c697c33b0 539
Kojto 0:615c697c33b0 540 errno = EFAIL;
Kojto 0:615c697c33b0 541
Kojto 0:615c697c33b0 542 if (name_length > HOSTNAME_MAX_LENGTH)
Kojto 0:615c697c33b0 543 {
Kojto 0:615c697c33b0 544 return errno;
Kojto 0:615c697c33b0 545 }
Kojto 0:615c697c33b0 546
Kojto 0:615c697c33b0 547 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 548 args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
Kojto 0:615c697c33b0 549
Kojto 0:615c697c33b0 550 // Fill in HCI packet structure
Kojto 0:615c697c33b0 551 args = UINT32_TO_STREAM(args, 8);
Kojto 0:615c697c33b0 552 args = UINT32_TO_STREAM(args, name_length);
Kojto 0:615c697c33b0 553 ARRAY_TO_STREAM(args, hostname, name_length);
Kojto 0:615c697c33b0 554
Kojto 0:615c697c33b0 555 // Initiate a HCI command
Kojto 0:615c697c33b0 556 _hci.command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN + name_length - 1);
Kojto 0:615c697c33b0 557
Kojto 0:615c697c33b0 558 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 559 _event.simplelink_wait_event(HCI_EVNT_BSD_GETHOSTBYNAME, &ret);
Kojto 0:615c697c33b0 560
Kojto 0:615c697c33b0 561 errno = ret.retVal;
Kojto 0:615c697c33b0 562
Kojto 0:615c697c33b0 563 (*((int32_t*)out_ip_addr)) = ret.outputAddress;
Kojto 0:615c697c33b0 564
Kojto 0:615c697c33b0 565 return (errno);
Kojto 0:615c697c33b0 566 }
Kojto 0:615c697c33b0 567
Kojto 0:615c697c33b0 568 int32_t cc3000_socket::set_sockopt(int32_t sd, int32_t level, int32_t optname, const void *optval, socklen_t optlen) {
Kojto 0:615c697c33b0 569 int32_t ret;
Kojto 0:615c697c33b0 570 uint8_t *ptr, *args;
Kojto 0:615c697c33b0 571
Kojto 0:615c697c33b0 572 ptr = _simple_link.get_transmit_buffer();
Kojto 0:615c697c33b0 573 args = (ptr + HEADERS_SIZE_CMD);
Kojto 0:615c697c33b0 574
Kojto 0:615c697c33b0 575 // Fill in temporary command buffer
Kojto 0:615c697c33b0 576 args = UINT32_TO_STREAM(args, sd);
Kojto 0:615c697c33b0 577 args = UINT32_TO_STREAM(args, level);
Kojto 0:615c697c33b0 578 args = UINT32_TO_STREAM(args, optname);
Kojto 0:615c697c33b0 579 args = UINT32_TO_STREAM(args, 0x00000008);
Kojto 0:615c697c33b0 580 args = UINT32_TO_STREAM(args, optlen);
Kojto 0:615c697c33b0 581 ARRAY_TO_STREAM(args, ((uint8_t *)optval), optlen);
Kojto 0:615c697c33b0 582
Kojto 0:615c697c33b0 583 // Initiate a HCI command
Kojto 0:615c697c33b0 584 _hci.command_send(HCI_CMND_SETSOCKOPT, ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN + optlen);
Kojto 0:615c697c33b0 585
Kojto 0:615c697c33b0 586 // Since we are in blocking state - wait for event complete
Kojto 0:615c697c33b0 587 _event.simplelink_wait_event(HCI_CMND_SETSOCKOPT, &ret);
Kojto 0:615c697c33b0 588
Kojto 0:615c697c33b0 589 if (ret >= 0)
Kojto 0:615c697c33b0 590 {
Kojto 0:615c697c33b0 591 return (0);
Kojto 0:615c697c33b0 592 }
Kojto 0:615c697c33b0 593 else
Kojto 0:615c697c33b0 594 {
Kojto 0:615c697c33b0 595 errno = ret;
Kojto 0:615c697c33b0 596 return ret;
Kojto 0:615c697c33b0 597 }
Kojto 0:615c697c33b0 598 }
Kojto 0:615c697c33b0 599
Kojto 0:615c697c33b0 600 #endif
Kojto 0:615c697c33b0 601
Kojto 0:615c697c33b0 602 } /* end of cc3000 namespace */