The code from https://github.com/vpcola/Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cc3000_socket.cpp Source File

cc3000_socket.cpp

00001 /*****************************************************************************
00002 *
00003 *  C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
00004 *  Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
00005 *  provided help.
00006 *
00007 *  This version of "host driver" uses CC3000 Host Driver Implementation. Thus
00008 *  read the following copyright:
00009 *
00010 *  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
00011 *
00012 *  Redistribution and use in source and binary forms, with or without
00013 *  modification, are permitted provided that the following conditions
00014 *  are met:
00015 *
00016 *    Redistributions of source code must retain the above copyright
00017 *    notice, this list of conditions and the following disclaimer.
00018 *
00019 *    Redistributions in binary form must reproduce the above copyright
00020 *    notice, this list of conditions and the following disclaimer in the
00021 *    documentation and/or other materials provided with the
00022 *    distribution.
00023 *
00024 *    Neither the name of Texas Instruments Incorporated nor the names of
00025 *    its contributors may be used to endorse or promote products derived
00026 *    from this software without specific prior written permission.
00027 *
00028 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00029 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00030 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00031 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00032 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00033 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00034 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00035 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00036 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00037 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00038 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00039 *
00040 *****************************************************************************/
00041 #include "cc3000.h"
00042 #include "cc3000_socket.h"
00043 #include "cc3000_event.h" //TODO - remove this
00044 #include "cc3000_common.h"
00045 
00046 namespace mbed_cc3000 {
00047 
00048 cc3000_socket::cc3000_socket(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_event &event)
00049     : _simple_link(simplelink), _hci(hci), _event(event) {
00050 
00051 }
00052 
00053 cc3000_socket::~cc3000_socket() {
00054 
00055 }
00056 
00057 int32_t cc3000_socket::HostFlowControlConsumeBuff(int32_t sd) {
00058 #ifndef SEND_NON_BLOCKING
00059     /* wait in busy loop */
00060     do {
00061         // When the last transmission failed, return the last failure reason.
00062         // Note that the buffer will not be allocated in this case
00063         if (_simple_link.get_transmit_error() != 0) {
00064             errno = _simple_link.get_transmit_error();
00065             _simple_link.set_transmit_error(0);
00066             return errno;
00067         }
00068 
00069         if(SOCKET_STATUS_ACTIVE != _event.get_socket_active_status(sd))
00070             return -1;
00071     } while (0 == _simple_link.get_number_free_buffers());
00072 
00073     uint16_t free_buffer = _simple_link.get_number_free_buffers();
00074     free_buffer--;
00075     _simple_link.set_number_free_buffers(free_buffer);
00076 
00077     return 0;
00078 #else
00079 
00080     // When the last transmission failed, return the last failure reason.
00081     // Note that the buffer will not be allocated in this case
00082     if (_simple_link.get_transmit_error() != 0) {
00083         errno = _simple_link.get_transmit_error();
00084         _simple_link.set_transmit_error(0);
00085         return errno;
00086     }
00087     if (SOCKET_STATUS_ACTIVE != _event.get_socket_active_status(sd))
00088         return -1;
00089 
00090     // If there are no available buffers, return -2. It is recommended to use
00091     // select or receive to see if there is any buffer occupied with received data
00092     // If so, call receive() to release the buffer.
00093     if (0 == _simple_link.get_number_free_buffers()) {
00094         return -2;
00095     } else {
00096         uint16_t free_buffer = _simple_link.get_number_free_buffers();
00097         free_buffer--;
00098         _simple_link.set_number_free_buffers(free_buffer);
00099         return 0;
00100     }
00101 #endif
00102 }
00103 
00104 int32_t cc3000_socket::socket(int32_t domain, int32_t type, int32_t protocol) {
00105     int32_t ret;
00106     uint8_t *ptr, *args;
00107 
00108     ret = EFAIL;
00109     ptr = _simple_link.get_transmit_buffer();
00110     args = (ptr + HEADERS_SIZE_CMD);
00111 
00112     // Fill in HCI packet structure
00113     args = UINT32_TO_STREAM(args, domain);
00114     args = UINT32_TO_STREAM(args, type);
00115     args = UINT32_TO_STREAM(args, protocol);
00116 
00117     // Initiate a HCI command
00118     _hci.command_send(HCI_CMND_SOCKET, ptr, SOCKET_OPEN_PARAMS_LEN);
00119 
00120     // Since we are in blocking state - wait for event complete
00121     _event.simplelink_wait_event(HCI_CMND_SOCKET, &ret);
00122 
00123     // Process the event
00124     errno = ret;
00125 
00126     _event.set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
00127 
00128     return ret;
00129 }
00130 
00131 int32_t cc3000_socket::closesocket(int32_t sd) {
00132     int32_t ret;
00133     uint8_t *ptr, *args;
00134 
00135     while (_simple_link.get_number_free_buffers() != SOCKET_MAX_FREE_BUFFERS);
00136     ret = EFAIL;
00137     ptr = _simple_link.get_transmit_buffer();
00138     args = (ptr + HEADERS_SIZE_CMD);
00139 
00140     // Fill in HCI packet structure
00141     args = UINT32_TO_STREAM(args, sd);
00142 
00143     // Initiate a HCI command
00144     _hci.command_send(HCI_CMND_CLOSE_SOCKET, ptr, SOCKET_CLOSE_PARAMS_LEN);
00145 
00146     // Since we are in blocking state - wait for event complete
00147     _event.simplelink_wait_event(HCI_CMND_CLOSE_SOCKET, &ret);
00148     errno = ret;
00149 
00150     // since 'close' call may result in either OK (and then it closed) or error, mark this socket as invalid
00151     _event.set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
00152 
00153     return ret;
00154 }
00155 
00156 int32_t cc3000_socket::accept(int32_t sd, sockaddr *addr, socklen_t *addrlen) {
00157     int32_t ret;
00158     uint8_t *ptr, *args;
00159     tBsdReturnParams tAcceptReturnArguments;
00160 
00161     ret = EFAIL;
00162     ptr = _simple_link.get_transmit_buffer();
00163     args = (ptr + HEADERS_SIZE_CMD);
00164 
00165     // Fill in temporary command buffer
00166     args = UINT32_TO_STREAM(args, sd);
00167 
00168     // Initiate a HCI command
00169     _hci.command_send(HCI_CMND_ACCEPT, ptr, SOCKET_ACCEPT_PARAMS_LEN);
00170 
00171     // Since we are in blocking state - wait for event complete
00172     _event.simplelink_wait_event(HCI_CMND_ACCEPT, &tAcceptReturnArguments);
00173 
00174 
00175     // need specify return parameters!!!
00176     memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN);
00177     *addrlen = ASIC_ADDR_LEN;
00178     errno = tAcceptReturnArguments.iStatus;
00179     ret = errno;
00180 
00181     // if succeeded, iStatus = new socket descriptor. otherwise - error number
00182     if(M_IS_VALID_SD(ret)) {
00183         _event.set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
00184     } else {
00185         _event.set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
00186     }
00187 
00188     return ret;
00189 }
00190 
00191 int32_t cc3000_socket::bind(int32_t sd, const sockaddr *addr, int32_t addrlen) {
00192     int32_t ret;
00193     uint8_t *ptr, *args;
00194 
00195     ret = EFAIL;
00196     ptr = _simple_link.get_transmit_buffer();
00197     args = (ptr + HEADERS_SIZE_CMD);
00198 
00199     addrlen = ASIC_ADDR_LEN;
00200 
00201     // Fill in temporary command buffer
00202     args = UINT32_TO_STREAM(args, sd);
00203     args = UINT32_TO_STREAM(args, 0x00000008);
00204     args = UINT32_TO_STREAM(args, addrlen);
00205     ARRAY_TO_STREAM(args, ((uint8_t *)addr), addrlen);
00206 
00207     // Initiate a HCI command
00208     _hci.command_send(HCI_CMND_BIND, ptr, SOCKET_BIND_PARAMS_LEN);
00209 
00210     // Since we are in blocking state - wait for event complete
00211     _event.simplelink_wait_event(HCI_CMND_BIND, &ret);
00212 
00213     errno = ret;
00214 
00215     return ret;
00216 }
00217 
00218 int32_t cc3000_socket::listen(int32_t sd, int32_t backlog) {
00219     int32_t ret;
00220     uint8_t *ptr, *args;
00221 
00222     ret = EFAIL;
00223     ptr = _simple_link.get_transmit_buffer();
00224     args = (ptr + HEADERS_SIZE_CMD);
00225 
00226     // Fill in temporary command buffer
00227     args = UINT32_TO_STREAM(args, sd);
00228     args = UINT32_TO_STREAM(args, backlog);
00229 
00230     // Initiate a HCI command
00231     _hci.command_send(HCI_CMND_LISTEN, ptr, SOCKET_LISTEN_PARAMS_LEN);
00232 
00233     // Since we are in blocking state - wait for event complete
00234     _event.simplelink_wait_event(HCI_CMND_LISTEN, &ret);
00235     errno = ret;
00236 
00237     return(ret);
00238 }
00239 
00240 int32_t cc3000_socket::connect(int32_t sd, const sockaddr *addr, int32_t addrlen) {
00241     int32_t ret;
00242     uint8_t *ptr, *args;
00243 
00244     ret = EFAIL;
00245     ptr = _simple_link.get_transmit_buffer();
00246     args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
00247     addrlen = 8;
00248 
00249     // Fill in temporary command buffer
00250     args = UINT32_TO_STREAM(args, sd);
00251     args = UINT32_TO_STREAM(args, 0x00000008);
00252     args = UINT32_TO_STREAM(args, addrlen);
00253     ARRAY_TO_STREAM(args, ((uint8_t *)addr), addrlen);
00254 
00255     // Initiate a HCI command
00256     _hci.command_send(HCI_CMND_CONNECT, ptr, SOCKET_CONNECT_PARAMS_LEN);
00257 
00258     // Since we are in blocking state - wait for event complete
00259     _event.simplelink_wait_event(HCI_CMND_CONNECT, &ret);
00260 
00261     errno = ret;
00262 
00263     return((int32_t)ret);
00264 }
00265 
00266 int32_t cc3000_socket::select(int32_t nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, struct timeval *timeout) {
00267     uint8_t *ptr, *args;
00268     tBsdSelectRecvParams tParams;
00269     uint32_t is_blocking;
00270 
00271     if (timeout == NULL) {
00272         is_blocking = 1; /* blocking , infinity timeout */
00273     } else {
00274         is_blocking = 0; /* no blocking, timeout */
00275     }
00276 
00277     // Fill in HCI packet structure
00278     ptr = _simple_link.get_transmit_buffer();
00279     args = (ptr + HEADERS_SIZE_CMD);
00280 
00281     // Fill in temporary command buffer
00282     args = UINT32_TO_STREAM(args, nfds);
00283     args = UINT32_TO_STREAM(args, 0x00000014);
00284     args = UINT32_TO_STREAM(args, 0x00000014);
00285     args = UINT32_TO_STREAM(args, 0x00000014);
00286     args = UINT32_TO_STREAM(args, 0x00000014);
00287     args = UINT32_TO_STREAM(args, is_blocking);
00288     args = UINT32_TO_STREAM(args, ((readsds) ? *(uint32_t*)readsds : 0));
00289     args = UINT32_TO_STREAM(args, ((writesds) ? *(uint32_t*)writesds : 0));
00290     args = UINT32_TO_STREAM(args, ((exceptsds) ? *(uint32_t*)exceptsds : 0));
00291 
00292     if (timeout) {
00293         if ( 0 == timeout->tv_sec && timeout->tv_usec < SELECT_TIMEOUT_MIN_MICRO_SECONDS) {
00294             timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS;
00295         }
00296         args = UINT32_TO_STREAM(args, timeout->tv_sec);
00297         args = UINT32_TO_STREAM(args, timeout->tv_usec);
00298     }
00299 
00300     // Initiate a HCI command
00301     _hci.command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN);
00302 
00303     // Since we are in blocking state - wait for event complete
00304     _event.simplelink_wait_event(HCI_EVNT_SELECT, &tParams);
00305 
00306     // Update actually read FD
00307     if (tParams.iStatus >= 0) {
00308         if (readsds) {
00309             memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd));
00310         }
00311 
00312         if (writesds) {
00313             memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd));
00314         }
00315 
00316         if (exceptsds) {
00317             memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd));
00318         }
00319 
00320         return(tParams.iStatus);
00321 
00322     } else {
00323         errno = tParams.iStatus;
00324         return -1;
00325     }
00326 }
00327 
00328 int32_t cc3000_socket::getsockopt (int32_t sd, int32_t level, int32_t optname, void *optval, socklen_t *optlen) {
00329     uint8_t *ptr, *args;
00330     tBsdGetSockOptReturnParams  tRetParams;
00331 
00332     ptr = _simple_link.get_transmit_buffer();
00333     args = (ptr + HEADERS_SIZE_CMD);
00334 
00335     // Fill in temporary command buffer
00336     args = UINT32_TO_STREAM(args, sd);
00337     args = UINT32_TO_STREAM(args, level);
00338     args = UINT32_TO_STREAM(args, optname);
00339 
00340     // Initiate a HCI command
00341     _hci.command_send(HCI_CMND_GETSOCKOPT, ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN);
00342 
00343     // Since we are in blocking state - wait for event complete
00344     _event.simplelink_wait_event(HCI_CMND_GETSOCKOPT, &tRetParams);
00345 
00346     if (((int8_t)tRetParams.iStatus) >= 0) {
00347         *optlen = 4;
00348         memcpy(optval, tRetParams.ucOptValue, 4);
00349         return (0);
00350     } else {
00351         errno = tRetParams.iStatus;
00352         return errno;
00353     }
00354 }
00355 
00356 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) {
00357     uint8_t *ptr, *args;
00358     tBsdReadReturnParams tSocketReadEvent;
00359 
00360     ptr = _simple_link.get_transmit_buffer();
00361     args = (ptr + HEADERS_SIZE_CMD);
00362 
00363     // Fill in HCI packet structure
00364     args = UINT32_TO_STREAM(args, sd);
00365     args = UINT32_TO_STREAM(args, len);
00366     args = UINT32_TO_STREAM(args, flags);
00367 
00368     // Generate the read command, and wait for the
00369     _hci.command_send(opcode,  ptr, SOCKET_RECV_FROM_PARAMS_LEN);
00370 
00371     // Since we are in blocking state - wait for event complete
00372     _event.simplelink_wait_event(opcode, &tSocketReadEvent);
00373 
00374     // In case the number of bytes is more then zero - read data
00375     if (tSocketReadEvent.iNumberOfBytes > 0) {
00376         // Wait for the data in a synchronous way. Here we assume that the bug is
00377         // big enough to store also parameters of receive from too....
00378         _event.simplelink_wait_data((uint8_t *)buf, (uint8_t *)from, (uint8_t *)fromlen);
00379     }
00380 
00381     errno = tSocketReadEvent.iNumberOfBytes;
00382 
00383     return(tSocketReadEvent.iNumberOfBytes);
00384 }
00385 
00386 int32_t cc3000_socket::recv(int32_t sd, void *buf, int32_t len, int32_t flags) {
00387     return(simple_link_recv(sd, buf, len, flags, NULL, NULL, HCI_CMND_RECV));
00388 }
00389 
00390 int32_t cc3000_socket::recvfrom(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen) {
00391     return(simple_link_recv(sd, buf, len, flags, from, fromlen, HCI_CMND_RECVFROM));
00392 }
00393 
00394 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) {
00395     uint8_t uArgSize = 0x00,  addrlen = 0x00;
00396     uint8_t *ptr, *pDataPtr = NULL, *args;
00397     uint32_t addr_offset = 0x00;
00398     int32_t res;
00399     tBsdReadReturnParams tSocketSendEvent;
00400 
00401     // Check the bsd_arguments
00402     if (0 != (res = HostFlowControlConsumeBuff(sd))) {
00403         return res;
00404     }
00405 
00406     //Update the number of sent packets
00407     uint16_t sent_packets = _simple_link.get_sent_packets();
00408     sent_packets++;
00409     _simple_link.set_sent_packets(sent_packets);
00410 
00411     // Allocate a buffer and construct a packet and send it over spi
00412     ptr = _simple_link.get_transmit_buffer();
00413     args = (ptr + HEADERS_SIZE_DATA);
00414 
00415     // Update the offset of data and parameters according to the command
00416     switch(opcode)
00417     {
00418         case HCI_CMND_SENDTO:
00419         {
00420             addr_offset = len + sizeof(len) + sizeof(len);
00421             addrlen = 8;
00422             uArgSize = SOCKET_SENDTO_PARAMS_LEN;
00423             pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN;
00424             break;
00425         }
00426 
00427         case HCI_CMND_SEND:
00428         {
00429             tolen = 0;
00430             to = NULL;
00431             uArgSize = HCI_CMND_SEND_ARG_LENGTH;
00432             pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH;
00433             break;
00434         }
00435 
00436         default:
00437         {
00438             break;
00439         }
00440     }
00441 
00442     // Fill in temporary command buffer
00443     args = UINT32_TO_STREAM(args, sd);
00444     args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd));
00445     args = UINT32_TO_STREAM(args, len);
00446     args = UINT32_TO_STREAM(args, flags);
00447 
00448     if (opcode == HCI_CMND_SENDTO) {
00449         args = UINT32_TO_STREAM(args, addr_offset);
00450         args = UINT32_TO_STREAM(args, addrlen);
00451     }
00452 
00453     // Copy the data received from user into the TX Buffer
00454     ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)buf), len);
00455 
00456     // In case we are using SendTo, copy the to parameters
00457     if (opcode == HCI_CMND_SENDTO) {
00458         ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)to), tolen);
00459     }
00460 
00461     // Initiate a HCI command
00462     _hci.data_send(opcode, ptr, uArgSize, len,(uint8_t*)to, tolen);
00463     if (opcode == HCI_CMND_SENDTO)
00464        _event.simplelink_wait_event(HCI_EVNT_SENDTO, &tSocketSendEvent);
00465     else
00466        _event.simplelink_wait_event(HCI_EVNT_SEND, &tSocketSendEvent);
00467 
00468     return (len);
00469 }
00470 
00471 int32_t cc3000_socket::send(int32_t sd, const void *buf, int32_t len, int32_t flags) {
00472     return(simple_link_send(sd, buf, len, flags, NULL, 0, HCI_CMND_SEND));
00473 }
00474 
00475 int32_t cc3000_socket::sendto(int32_t sd, const void *buf, int32_t len, int32_t flags, const sockaddr *to, socklen_t tolen) {
00476     return(simple_link_send(sd, buf, len, flags, to, tolen, HCI_CMND_SENDTO));
00477 }
00478 
00479 int32_t cc3000_socket::mdns_advertiser(uint16_t mdns_enabled, uint8_t *device_service_name, uint16_t device_service_name_length) {
00480     int32_t ret;
00481      uint8_t *pTxBuffer, *pArgs;
00482 
00483     if (device_service_name_length > MDNS_DEVICE_SERVICE_MAX_LENGTH) {
00484         return EFAIL;
00485     }
00486 
00487     pTxBuffer = _simple_link.get_transmit_buffer();
00488     pArgs = (pTxBuffer + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
00489 
00490     // Fill in HCI packet structure
00491     pArgs = UINT32_TO_STREAM(pArgs, mdns_enabled);
00492     pArgs = UINT32_TO_STREAM(pArgs, 8);
00493     pArgs = UINT32_TO_STREAM(pArgs, device_service_name_length);
00494     ARRAY_TO_STREAM(pArgs, device_service_name, device_service_name_length);
00495 
00496     // Initiate a HCI command
00497     _hci.command_send(HCI_CMND_MDNS_ADVERTISE, pTxBuffer, SOCKET_MDNS_ADVERTISE_PARAMS_LEN + device_service_name_length);
00498 
00499     // Since we are in blocking state - wait for event complete
00500     _event.simplelink_wait_event(HCI_EVNT_MDNS_ADVERTISE, &ret);
00501 
00502     return ret;
00503 }
00504 
00505 
00506 #ifndef CC3000_TINY_DRIVER
00507 int32_t cc3000_socket::gethostbyname(uint8_t *hostname, uint16_t name_length, uint32_t *out_ip_addr) {
00508     tBsdGethostbynameParams ret;
00509     uint8_t *ptr, *args;
00510 
00511     errno = EFAIL;
00512 
00513     if (name_length > HOSTNAME_MAX_LENGTH) {
00514         return errno;
00515     }
00516 
00517     ptr = _simple_link.get_transmit_buffer();
00518     args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
00519 
00520     // Fill in HCI packet structure
00521     args = UINT32_TO_STREAM(args, 8);
00522     args = UINT32_TO_STREAM(args, name_length);
00523     ARRAY_TO_STREAM(args, hostname, name_length);
00524 
00525     // Initiate a HCI command
00526     _hci.command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN + name_length - 1);
00527 
00528     // Since we are in blocking state - wait for event complete
00529     _event.simplelink_wait_event(HCI_EVNT_BSD_GETHOSTBYNAME, &ret);
00530 
00531     errno = ret.retVal;
00532 
00533     (*((int32_t*)out_ip_addr)) = ret.outputAddress;
00534 
00535     return (errno);
00536 }
00537 
00538 int32_t cc3000_socket::setsockopt(int32_t sd, int32_t level, int32_t optname, const void *optval, socklen_t optlen) {
00539     int32_t ret;
00540     uint8_t *ptr, *args;
00541 
00542     ptr = _simple_link.get_transmit_buffer();
00543     args = (ptr + HEADERS_SIZE_CMD);
00544 
00545     // Fill in temporary command buffer
00546     args = UINT32_TO_STREAM(args, sd);
00547     args = UINT32_TO_STREAM(args, level);
00548     args = UINT32_TO_STREAM(args, optname);
00549     args = UINT32_TO_STREAM(args, 0x00000008);
00550     args = UINT32_TO_STREAM(args, optlen);
00551     ARRAY_TO_STREAM(args, ((uint8_t *)optval), optlen);
00552 
00553     // Initiate a HCI command
00554     _hci.command_send(HCI_CMND_SETSOCKOPT, ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN  + optlen);
00555 
00556     // Since we are in blocking state - wait for event complete
00557     _event.simplelink_wait_event(HCI_CMND_SETSOCKOPT, &ret);
00558 
00559     if (ret >= 0) {
00560         return (0);
00561     } else {
00562         errno = ret;
00563         return ret;
00564     }
00565 }
00566 
00567 #endif
00568 
00569 char* cc3000_socket::inet_ntoa_r (uint32_t s_addr, char *buf, int buflen)
00570 {
00571     char inv[3];
00572     char *rp;
00573     uint8_t *ap;
00574     uint8_t rem;
00575     uint8_t n;
00576     uint8_t i;
00577     int len = 0;
00578 
00579     rp = buf;
00580     ap = (uint8_t *)&s_addr;
00581     for (n = 0; n < 4; n++) {
00582         i = 0;
00583         do {
00584             rem = *ap % (uint8_t)10;
00585             *ap /= (uint8_t)10;
00586             inv[i++] = '0' + rem;
00587         } while(*ap);
00588         while(i--) {
00589             if (len++ >= buflen) {
00590                 return NULL;
00591             }
00592             *rp++ = inv[i];
00593         }
00594         if (len++ >= buflen) {
00595             return NULL;
00596         }
00597         *rp++ = '.';
00598         ap++;
00599     }
00600     *--rp = 0;
00601     return buf;
00602 }
00603 
00604 } // mbed_cc3000 namespace
00605