summaryrefslogtreecommitdiff
path: root/nuttx/drivers/wireless/cc3000/socket.c
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-09-04 09:45:59 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-09-04 09:45:59 -0600
commita2ffe6b068f3975e7574feabff0d20b368bd2f49 (patch)
tree25e2a3ee86c34dd3953b7f6b8f8feeafa62962bb /nuttx/drivers/wireless/cc3000/socket.c
parent87069eb35cb10aa7bea564a12d7bb5075fdd31e3 (diff)
downloadpx4-nuttx-a2ffe6b068f3975e7574feabff0d20b368bd2f49.tar.gz
px4-nuttx-a2ffe6b068f3975e7574feabff0d20b368bd2f49.tar.bz2
px4-nuttx-a2ffe6b068f3975e7574feabff0d20b368bd2f49.zip
CC3000 driver updates from Alan Carvalho de Assis
Diffstat (limited to 'nuttx/drivers/wireless/cc3000/socket.c')
-rw-r--r--nuttx/drivers/wireless/cc3000/socket.c2338
1 files changed, 1169 insertions, 1169 deletions
diff --git a/nuttx/drivers/wireless/cc3000/socket.c b/nuttx/drivers/wireless/cc3000/socket.c
index 20bbd5017..5b810f231 100644
--- a/nuttx/drivers/wireless/cc3000/socket.c
+++ b/nuttx/drivers/wireless/cc3000/socket.c
@@ -1,1169 +1,1169 @@
-/*****************************************************************************
-*
-* socket.c - CC3000 Host Driver Implementation.
-* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions
-* are met:
-*
-* Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-*
-* Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the
-* distribution.
-*
-* Neither the name of Texas Instruments Incorporated nor the names of
-* its contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-*****************************************************************************/
-
-//*****************************************************************************
-//
-//! \addtogroup socket_api
-//! @{
-//
-//*****************************************************************************
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <nuttx/cc3000/hci.h>
-#include <nuttx/cc3000/socket.h>
-#include <nuttx/cc3000/evnt_handler.h>
-#include <nuttx/cc3000/netapp.h>
-
-
-
-//Enable this flag if and only if you must comply with BSD socket
-//close() function
-#ifdef _API_USE_BSD_CLOSE
- #define close(sd) closesocket(sd)
-#endif
-
-//Enable this flag if and only if you must comply with BSD socket read() and
-//write() functions
-#ifdef _API_USE_BSD_READ_WRITE
- #define read(sd, buf, len, flags) recv(sd, buf, len, flags)
- #define write(sd, buf, len, flags) send(sd, buf, len, flags)
-#endif
-
-#define SOCKET_OPEN_PARAMS_LEN (12)
-#define SOCKET_CLOSE_PARAMS_LEN (4)
-#define SOCKET_ACCEPT_PARAMS_LEN (4)
-#define SOCKET_BIND_PARAMS_LEN (20)
-#define SOCKET_LISTEN_PARAMS_LEN (8)
-#define SOCKET_GET_HOST_BY_NAME_PARAMS_LEN (9)
-#define SOCKET_CONNECT_PARAMS_LEN (20)
-#define SOCKET_SELECT_PARAMS_LEN (44)
-#define SOCKET_SET_SOCK_OPT_PARAMS_LEN (20)
-#define SOCKET_GET_SOCK_OPT_PARAMS_LEN (12)
-#define SOCKET_RECV_FROM_PARAMS_LEN (12)
-#define SOCKET_SENDTO_PARAMS_LEN (24)
-#define SOCKET_MDNS_ADVERTISE_PARAMS_LEN (12)
-
-
-// The legnth of arguments for the SEND command: sd + buff_offset + len + flags,
-// while size of each parameter is 32 bit - so the total length is 16 bytes;
-
-#define HCI_CMND_SEND_ARG_LENGTH (16)
-
-
-#define SELECT_TIMEOUT_MIN_MICRO_SECONDS 5000
-
-#define HEADERS_SIZE_DATA (SPI_HEADER_SIZE + 5)
-
-#define SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE)
-
-#define MDNS_DEVICE_SERVICE_MAX_LENGTH (32)
-
-
-//*****************************************************************************
-//
-//! HostFlowControlConsumeBuff
-//!
-//! @param sd socket descriptor
-//!
-//! @return 0 in case there are buffers available,
-//! -1 in case of bad socket
-//! -2 if there are no free buffers present (only when
-//! SEND_NON_BLOCKING is enabled)
-//!
-//! @brief if SEND_NON_BLOCKING not define - block until have free buffer
-//! becomes available, else return immediately with correct status
-//! regarding the buffers available.
-//
-//*****************************************************************************
-int
-HostFlowControlConsumeBuff(int sd)
-{
-#ifndef SEND_NON_BLOCKING
- /* wait in busy loop */
- do
- {
- // In case last transmission failed then we will return the last failure
- // reason here.
- // Note that the buffer will not be allocated in this case
- if (tSLInformation.slTransmitDataError != 0)
- {
- errno = tSLInformation.slTransmitDataError;
- tSLInformation.slTransmitDataError = 0;
- return errno;
- }
-
- if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd))
- return -1;
- } while(0 == tSLInformation.usNumberOfFreeBuffers);
-
- tSLInformation.usNumberOfFreeBuffers--;
-
- return 0;
-#else
-
- // In case last transmission failed then we will return the last failure
- // reason here.
- // Note that the buffer will not be allocated in this case
- if (tSLInformation.slTransmitDataError != 0)
- {
- errno = tSLInformation.slTransmitDataError;
- tSLInformation.slTransmitDataError = 0;
- return errno;
- }
- if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd))
- return -1;
-
- //If there are no available buffers, return -2. It is recommended to use
- // select or receive to see if there is any buffer occupied with received data
- // If so, call receive() to release the buffer.
- if(0 == tSLInformation.usNumberOfFreeBuffers)
- {
- return -2;
- }
- else
- {
- tSLInformation.usNumberOfFreeBuffers--;
- return 0;
- }
-#endif
-}
-
-//*****************************************************************************
-//
-//! socket
-//!
-//! @param domain selects the protocol family which will be used for
-//! communication. On this version only AF_INET is supported
-//! @param type specifies the communication semantics. On this version
-//! only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW are supported
-//! @param protocol specifies a particular protocol to be used with the
-//! socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are
-//! supported.
-//!
-//! @return On success, socket handle that is used for consequent socket
-//! operations. On error, -1 is returned.
-//!
-//! @brief create an endpoint for communication
-//! The socket function creates a socket that is bound to a specific
-//! transport service provider. This function is called by the
-//! application layer to obtain a socket handle.
-//
-//*****************************************************************************
-
-int
-socket(long domain, long type, long protocol)
-{
- long ret;
- unsigned char *ptr, *args;
-
- ret = EFAIL;
- ptr = tSLInformation.pucTxCommandBuffer;
- args = (ptr + HEADERS_SIZE_CMD);
-
- // Fill in HCI packet structure
- args = UINT32_TO_STREAM(args, domain);
- args = UINT32_TO_STREAM(args, type);
- args = UINT32_TO_STREAM(args, protocol);
-
- // Initiate a HCI command
- hci_command_send(HCI_CMND_SOCKET, ptr, SOCKET_OPEN_PARAMS_LEN);
-
- // Since we are in blocking state - wait for event complete
- SimpleLinkWaitEvent(HCI_CMND_SOCKET, &ret);
-
- // Process the event
- errno = ret;
-
- set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
-
- return(ret);
-}
-
-//*****************************************************************************
-//
-//! closesocket
-//!
-//! @param sd socket handle.
-//!
-//! @return On success, zero is returned. On error, -1 is returned.
-//!
-//! @brief The socket function closes a created socket.
-//
-//*****************************************************************************
-
-long
-closesocket(long sd)
-{
- long ret;
- unsigned char *ptr, *args;
-
- ret = EFAIL;
- ptr = tSLInformation.pucTxCommandBuffer;
- args = (ptr + HEADERS_SIZE_CMD);
-
- // Fill in HCI packet structure
- args = UINT32_TO_STREAM(args, sd);
-
- // Initiate a HCI command
- hci_command_send(HCI_CMND_CLOSE_SOCKET,
- ptr, SOCKET_CLOSE_PARAMS_LEN);
-
- // Since we are in blocking state - wait for event complete
- SimpleLinkWaitEvent(HCI_CMND_CLOSE_SOCKET, &ret);
- errno = ret;
-
- // since 'close' call may result in either OK (and then it closed) or error
- // mark this socket as invalid
- set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
-
- return(ret);
-}
-
-//*****************************************************************************
-//
-//! accept
-//!
-//! @param[in] sd socket descriptor (handle)
-//! @param[out] addr the argument addr is a pointer to a sockaddr structure
-//! This structure is filled in with the address of the
-//! peer socket, as known to the communications layer.
-//! determined. The exact format of the address returned
-//! addr is by the socket's address sockaddr.
-//! On this version only AF_INET is supported.
-//! This argument returns in network order.
-//! @param[out] addrlen the addrlen argument is a value-result argument:
-//! it should initially contain the size of the structure
-//! pointed to by addr.
-//!
-//! @return For socket in blocking mode:
-//! On success, socket handle. on failure negative
-//! For socket in non-blocking mode:
-//! - On connection establishment, socket handle
-//! - On connection pending, SOC_IN_PROGRESS (-2)
-//! - On failure, SOC_ERROR (-1)
-//!
-//! @brief accept a connection on a socket:
-//! This function is used with connection-based socket types
-//! (SOCK_STREAM). It extracts the first connection request on the
-//! queue of pending connections, creates a new connected socket, and
-//! returns a new file descriptor referring to that socket.
-//! The newly created socket is not in the listening state.
-//! The original socket sd is unaffected by this call.
-//! The argument sd is a socket that has been created with socket(),
-//! bound to a local address with bind(), and is listening for
-//! connections after a listen(). The argument addr is a pointer
-//! to a sockaddr structure. This structure is filled in with the
-//! address of the peer socket, as known to the communications layer.
-//! The exact format of the address returned addr is determined by the
-//! socket's address family. The addrlen argument is a value-result
-//! argument: it should initially contain the size of the structure
-//! pointed to by addr, on return it will contain the actual
-//! length (in bytes) of the address returned.
-//!
-//! @sa socket ; bind ; listen
-//
-//*****************************************************************************
-
-long
-accept(long sd, sockaddr *addr, socklen_t *addrlen)
-{
- long ret;
- unsigned char *ptr, *args;
- tBsdReturnParams tAcceptReturnArguments;
-
- ret = EFAIL;
- ptr = tSLInformation.pucTxCommandBuffer;
- args = (ptr + HEADERS_SIZE_CMD);
-
- // Fill in temporary command buffer
- args = UINT32_TO_STREAM(args, sd);
-
- // Initiate a HCI command
- hci_command_send(HCI_CMND_ACCEPT,
- ptr, SOCKET_ACCEPT_PARAMS_LEN);
-
- // Since we are in blocking state - wait for event complete
- SimpleLinkWaitEvent(HCI_CMND_ACCEPT, &tAcceptReturnArguments);
-
-
- // need specify return parameters!!!
- memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN);
- *addrlen = ASIC_ADDR_LEN;
- errno = tAcceptReturnArguments.iStatus;
- ret = errno;
-
- // if succeeded, iStatus = new socket descriptor. otherwise - error number
- if(M_IS_VALID_SD(ret))
- {
- set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
- }
- else
- {
- set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
- }
-
- return(ret);
-}
-
-//*****************************************************************************
-//
-//! bind
-//!
-//! @param[in] sd socket descriptor (handle)
-//! @param[out] addr specifies the destination address. On this version
-//! only AF_INET is supported.
-//! @param[out] addrlen contains the size of the structure pointed to by addr.
-//!
-//! @return On success, zero is returned. On error, -1 is returned.
-//!
-//! @brief assign a name to a socket
-//! This function gives the socket the local address addr.
-//! addr is addrlen bytes long. Traditionally, this is called when a
-//! socket is created with socket, it exists in a name space (address
-//! family) but has no name assigned.
-//! It is necessary to assign a local address before a SOCK_STREAM
-//! socket may receive connections.
-//!
-//! @sa socket ; accept ; listen
-//
-//*****************************************************************************
-
-long
-bind(long sd, const sockaddr *addr, long addrlen)
-{
- long ret;
- unsigned char *ptr, *args;
-
- ret = EFAIL;
- ptr = tSLInformation.pucTxCommandBuffer;
- args = (ptr + HEADERS_SIZE_CMD);
-
- addrlen = ASIC_ADDR_LEN;
-
- // Fill in temporary command buffer
- args = UINT32_TO_STREAM(args, sd);
- args = UINT32_TO_STREAM(args, 0x00000008);
- args = UINT32_TO_STREAM(args, addrlen);
- ARRAY_TO_STREAM(args, ((unsigned char *)addr), addrlen);
-
- // Initiate a HCI command
- hci_command_send(HCI_CMND_BIND,
- ptr, SOCKET_BIND_PARAMS_LEN);
-
- // Since we are in blocking state - wait for event complete
- SimpleLinkWaitEvent(HCI_CMND_BIND, &ret);
-
- errno = ret;
-
- return(ret);
-}
-
-//*****************************************************************************
-//
-//! listen
-//!
-//! @param[in] sd socket descriptor (handle)
-//! @param[in] backlog specifies the listen queue depth. On this version
-//! backlog is not supported.
-//! @return On success, zero is returned. On error, -1 is returned.
-//!
-//! @brief listen for connections on a socket
-//! The willingness to accept incoming connections and a queue
-//! limit for incoming connections are specified with listen(),
-//! and then the connections are accepted with accept.
-//! The listen() call applies only to sockets of type SOCK_STREAM
-//! The backlog parameter defines the maximum length the queue of
-//! pending connections may grow to.
-//!
-//! @sa socket ; accept ; bind
-//!
-//! @note On this version, backlog is not supported
-//
-//*****************************************************************************
-
-long
-listen(long sd, long backlog)
-{
- long ret;
- unsigned char *ptr, *args;
-
- ret = EFAIL;
- ptr = tSLInformation.pucTxCommandBuffer;
- args = (ptr + HEADERS_SIZE_CMD);
-
- // Fill in temporary command buffer
- args = UINT32_TO_STREAM(args, sd);
- args = UINT32_TO_STREAM(args, backlog);
-
- // Initiate a HCI command
- hci_command_send(HCI_CMND_LISTEN,
- ptr, SOCKET_LISTEN_PARAMS_LEN);
-
- // Since we are in blocking state - wait for event complete
- SimpleLinkWaitEvent(HCI_CMND_LISTEN, &ret);
- errno = ret;
-
- return(ret);
-}
-
-//*****************************************************************************
-//
-//! gethostbyname
-//!
-//! @param[in] hostname host name
-//! @param[in] usNameLen name length
-//! @param[out] out_ip_addr This parameter is filled in with host IP address.
-//! In case that host name is not resolved,
-//! out_ip_addr is zero.
-//! @return On success, positive is returned. On error, negative is returned
-//!
-//! @brief Get host IP by name. Obtain the IP Address of machine on network,
-//! by its name.
-//!
-//! @note On this version, only blocking mode is supported. Also note that
-//! the function requires DNS server to be configured prior to its usage.
-//
-//*****************************************************************************
-
-#ifndef CC3000_TINY_DRIVER
-int
-gethostbyname(char * hostname, unsigned short usNameLen,
- unsigned long* out_ip_addr)
-{
- tBsdGethostbynameParams ret;
- unsigned char *ptr, *args;
-
- errno = EFAIL;
-
- if (usNameLen > HOSTNAME_MAX_LENGTH)
- {
- return errno;
- }
-
- ptr = tSLInformation.pucTxCommandBuffer;
- args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
-
- // Fill in HCI packet structure
- args = UINT32_TO_STREAM(args, 8);
- args = UINT32_TO_STREAM(args, usNameLen);
- ARRAY_TO_STREAM(args, hostname, usNameLen);
-
- // Initiate a HCI command
- hci_command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN
- + usNameLen - 1);
-
- // Since we are in blocking state - wait for event complete
- SimpleLinkWaitEvent(HCI_EVNT_BSD_GETHOSTBYNAME, &ret);
-
- errno = ret.retVal;
-
- (*((long*)out_ip_addr)) = ret.outputAddress;
-
- return (errno);
-
-}
-#endif
-
-//*****************************************************************************
-//
-//! connect
-//!
-//! @param[in] sd socket descriptor (handle)
-//! @param[in] addr specifies the destination addr. On this version
-//! only AF_INET is supported.
-//! @param[out] addrlen contains the size of the structure pointed to by addr
-//! @return On success, zero is returned. On error, -1 is returned
-//!
-//! @brief initiate a connection on a socket
-//! Function connects the socket referred to by the socket descriptor
-//! sd, to the address specified by addr. The addrlen argument
-//! specifies the size of addr. The format of the address in addr is
-//! determined by the address space of the socket. If it is of type
-//! SOCK_DGRAM, this call specifies the peer with which the socket is
-//! to be associated; this address is that to which datagrams are to be
-//! sent, and the only address from which datagrams are to be received.
-//! If the socket is of type SOCK_STREAM, this call attempts to make a
-//! connection to another socket. The other socket is specified by
-//! address, which is an address in the communications space of the
-//! socket. Note that the function implements only blocking behavior
-//! thus the caller will be waiting either for the connection
-//! establishment or for the connection establishment failure.
-//!
-//! @sa socket
-//
-//*****************************************************************************
-
-long
-connect(long sd, const sockaddr *addr, long addrlen)
-{
- long int ret;
- unsigned char *ptr, *args;
-
- ret = EFAIL;
- ptr = tSLInformation.pucTxCommandBuffer;
- args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
- addrlen = 8;
-
- // Fill in temporary command buffer
- args = UINT32_TO_STREAM(args, sd);
- args = UINT32_TO_STREAM(args, 0x00000008);
- args = UINT32_TO_STREAM(args, addrlen);
- ARRAY_TO_STREAM(args, ((unsigned char *)addr), addrlen);
-
- // Initiate a HCI command
- hci_command_send(HCI_CMND_CONNECT,
- ptr, SOCKET_CONNECT_PARAMS_LEN);
-
- // Since we are in blocking state - wait for event complete
- SimpleLinkWaitEvent(HCI_CMND_CONNECT, &ret);
-
- errno = ret;
-
- return((long)ret);
-}
-
-
-//*****************************************************************************
-//
-//! select
-//!
-//! @param[in] nfds the highest-numbered file descriptor in any of the
-//! three sets, plus 1.
-//! @param[out] writesds socket descriptors list for write monitoring
-//! @param[out] readsds socket descriptors list for read monitoring
-//! @param[out] exceptsds socket descriptors list for exception monitoring
-//! @param[in] timeout is an upper bound on the amount of time elapsed
-//! before select() returns. Null means infinity
-//! timeout. The minimum timeout is 5 milliseconds,
-//! less than 5 milliseconds will be set
-//! automatically to 5 milliseconds.
-//! @return On success, select() returns the number of file descriptors
-//! contained in the three returned descriptor sets (that is, the
-//! total number of bits that are set in readfds, writefds,
-//! exceptfds) which may be zero if the timeout expires before
-//! anything interesting happens.
-//! On error, -1 is returned.
-//! *readsds - return the sockets on which Read request will
-//! return without delay with valid data.
-//! *writesds - return the sockets on which Write request
-//! will return without delay.
-//! *exceptsds - return the sockets which closed recently.
-//!
-//! @brief Monitor socket activity
-//! Select allow a program to monitor multiple file descriptors,
-//! waiting until one or more of the file descriptors become
-//! "ready" for some class of I/O operation
-//!
-//! @Note If the timeout value set to less than 5ms it will automatically set
-//! to 5ms to prevent overload of the system
-//!
-//! @sa socket
-//
-//*****************************************************************************
-
-int
-select(long nfds, TICC3000fd_set *readsds, TICC3000fd_set *writesds, TICC3000fd_set *exceptsds,
- struct timeval *timeout)
-{
- unsigned char *ptr, *args;
- tBsdSelectRecvParams tParams;
- unsigned long is_blocking;
-
- if( timeout == NULL)
- {
- is_blocking = 1; /* blocking , infinity timeout */
- }
- else
- {
- is_blocking = 0; /* no blocking, timeout */
- }
-
- // Fill in HCI packet structure
- ptr = tSLInformation.pucTxCommandBuffer;
- args = (ptr + HEADERS_SIZE_CMD);
-
- // Fill in temporary command buffer
- args = UINT32_TO_STREAM(args, nfds);
- args = UINT32_TO_STREAM(args, 0x00000014);
- args = UINT32_TO_STREAM(args, 0x00000014);
- args = UINT32_TO_STREAM(args, 0x00000014);
- args = UINT32_TO_STREAM(args, 0x00000014);
- args = UINT32_TO_STREAM(args, is_blocking);
- args = UINT32_TO_STREAM(args, ((readsds) ? *(unsigned long*)readsds : 0));
- args = UINT32_TO_STREAM(args, ((writesds) ? *(unsigned long*)writesds : 0));
- args = UINT32_TO_STREAM(args, ((exceptsds) ? *(unsigned long*)exceptsds : 0));
-
- if (timeout)
- {
- if ( 0 == timeout->tv_sec && timeout->tv_usec <
- SELECT_TIMEOUT_MIN_MICRO_SECONDS)
- {
- timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS;
- }
- args = UINT32_TO_STREAM(args, timeout->tv_sec);
- args = UINT32_TO_STREAM(args, timeout->tv_usec);
- }
-
- // Initiate a HCI command
- hci_command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN);
-
- // Since we are in blocking state - wait for event complete
- SimpleLinkWaitEvent(HCI_EVNT_SELECT, &tParams);
-
- // Update actually read FD
- if (tParams.iStatus >= 0)
- {
- if (readsds)
- {
- memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd));
- }
-
- if (writesds)
- {
- memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd));
- }
-
- if (exceptsds)
- {
- memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd));
- }
-
- return(tParams.iStatus);
-
- }
- else
- {
- errno = tParams.iStatus;
- return(-1);
- }
-}
-
-//*****************************************************************************
-//
-//! setsockopt
-//!
-//! @param[in] sd socket handle
-//! @param[in] level defines the protocol level for this option
-//! @param[in] optname defines the option name to Interrogate
-//! @param[in] optval specifies a value for the option
-//! @param[in] optlen specifies the length of the option value
-//! @return On success, zero is returned. On error, -1 is returned
-//!
-//! @brief set socket options
-//! This function manipulate the options associated with a socket.
-//! Options may exist at multiple protocol levels; they are always
-//! present at the uppermost socket level.
-//! When manipulating socket options the level at which the option
-//! resides and the name of the option must be specified.
-//! To manipulate options at the socket level, level is specified as
-//! SOL_SOCKET. To manipulate options at any other level the protocol
-//! number of the appropriate protocol controlling the option is
-//! supplied. For example, to indicate that an option is to be
-//! interpreted by the TCP protocol, level should be set to the
-//! protocol number of TCP;
-//! The parameters optval and optlen are used to access optval -
-//! use for setsockopt(). For getsockopt() they identify a buffer
-//! in which the value for the requested option(s) are to
-//! be returned. For getsockopt(), optlen is a value-result
-//! parameter, initially containing the size of the buffer
-//! pointed to by option_value, and modified on return to
-//! indicate the actual size of the value returned. If no option
-//! value is to be supplied or returned, option_value may be NULL.
-//!
-//! @Note On this version the following two socket options are enabled:
-//! The only protocol level supported in this version
-//! is SOL_SOCKET (level).
-//! 1. SOCKOPT_RECV_TIMEOUT (optname)
-//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout
-//! in milliseconds.
-//! In that case optval should be pointer to unsigned long.
-//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on
-//! or off.
-//! In that case optval should be SOCK_ON or SOCK_OFF (optval).
-//!
-//! @sa getsockopt
-//
-//*****************************************************************************
-
-#ifndef CC3000_TINY_DRIVER
-int
-setsockopt(long sd, long level, long optname, const void *optval,
- socklen_t optlen)
-{
- int ret;
- unsigned char *ptr, *args;
-
- ptr = tSLInformation.pucTxCommandBuffer;
- args = (ptr + HEADERS_SIZE_CMD);
-
- // Fill in temporary command buffer
- args = UINT32_TO_STREAM(args, sd);
- args = UINT32_TO_STREAM(args, level);
- args = UINT32_TO_STREAM(args, optname);
- args = UINT32_TO_STREAM(args, 0x00000008);
- args = UINT32_TO_STREAM(args, optlen);
- ARRAY_TO_STREAM(args, ((unsigned char *)optval), optlen);
-
- // Initiate a HCI command
- hci_command_send(HCI_CMND_SETSOCKOPT,
- ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN + optlen);
-
- // Since we are in blocking state - wait for event complete
- SimpleLinkWaitEvent(HCI_CMND_SETSOCKOPT, &ret);
-
- if (ret >= 0)
- {
- return (0);
- }
- else
- {
- errno = ret;
- return ret;
- }
-}
-#endif
-
-//*****************************************************************************
-//
-//! getsockopt
-//!
-//! @param[in] sd socket handle
-//! @param[in] level defines the protocol level for this option
-//! @param[in] optname defines the option name to Interrogate
-//! @param[out] optval specifies a value for the option
-//! @param[out] optlen specifies the length of the option value
-//! @return On success, zero is returned. On error, -1 is returned
-//!
-//! @brief set socket options
-//! This function manipulate the options associated with a socket.
-//! Options may exist at multiple protocol levels; they are always
-//! present at the uppermost socket level.
-//! When manipulating socket options the level at which the option
-//! resides and the name of the option must be specified.
-//! To manipulate options at the socket level, level is specified as
-//! SOL_SOCKET. To manipulate options at any other level the protocol
-//! number of the appropriate protocol controlling the option is
-//! supplied. For example, to indicate that an option is to be
-//! interpreted by the TCP protocol, level should be set to the
-//! protocol number of TCP;
-//! The parameters optval and optlen are used to access optval -
-//! use for setsockopt(). For getsockopt() they identify a buffer
-//! in which the value for the requested option(s) are to
-//! be returned. For getsockopt(), optlen is a value-result
-//! parameter, initially containing the size of the buffer
-//! pointed to by option_value, and modified on return to
-//! indicate the actual size of the value returned. If no option
-//! value is to be supplied or returned, option_value may be NULL.
-//!
-//! @Note On this version the following two socket options are enabled:
-//! The only protocol level supported in this version
-//! is SOL_SOCKET (level).
-//! 1. SOCKOPT_RECV_TIMEOUT (optname)
-//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout
-//! in milliseconds.
-//! In that case optval should be pointer to unsigned long.
-//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on
-//! or off.
-//! In that case optval should be SOCK_ON or SOCK_OFF (optval).
-//!
-//! @sa setsockopt
-//
-//*****************************************************************************
-
-int
-getsockopt (long sd, long level, long optname, void *optval, socklen_t *optlen)
-{
- unsigned char *ptr, *args;
- tBsdGetSockOptReturnParams tRetParams;
-
- ptr = tSLInformation.pucTxCommandBuffer;
- args = (ptr + HEADERS_SIZE_CMD);
-
- // Fill in temporary command buffer
- args = UINT32_TO_STREAM(args, sd);
- args = UINT32_TO_STREAM(args, level);
- args = UINT32_TO_STREAM(args, optname);
-
- // Initiate a HCI command
- hci_command_send(HCI_CMND_GETSOCKOPT,
- ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN);
-
- // Since we are in blocking state - wait for event complete
- SimpleLinkWaitEvent(HCI_CMND_GETSOCKOPT, &tRetParams);
-
- if (((signed char)tRetParams.iStatus) >= 0)
- {
- *optlen = 4;
- memcpy(optval, tRetParams.ucOptValue, 4);
- return (0);
- }
- else
- {
- errno = tRetParams.iStatus;
- return errno;
- }
-}
-
-//*****************************************************************************
-//
-//! simple_link_recv
-//!
-//! @param sd socket handle
-//! @param buf read buffer
-//! @param len buffer length
-//! @param flags indicates blocking or non-blocking operation
-//! @param from pointer to an address structure indicating source address
-//! @param fromlen source address structure size
-//!
-//! @return Return the number of bytes received, or -1 if an error
-//! occurred
-//!
-//! @brief Read data from socket
-//! Return the length of the message on successful completion.
-//! If a message is too long to fit in the supplied buffer,
-//! excess bytes may be discarded depending on the type of
-//! socket the message is received from
-//
-//*****************************************************************************
-int
-simple_link_recv(long sd, void *buf, long len, long flags, sockaddr *from,
- socklen_t *fromlen, long opcode)
-{
- unsigned char *ptr, *args;
- tBsdReadReturnParams tSocketReadEvent;
-
- ptr = tSLInformation.pucTxCommandBuffer;
- args = (ptr + HEADERS_SIZE_CMD);
-
- // Fill in HCI packet structure
- args = UINT32_TO_STREAM(args, sd);
- args = UINT32_TO_STREAM(args, len);
- args = UINT32_TO_STREAM(args, flags);
-
- // Generate the read command, and wait for the
- hci_command_send(opcode, ptr, SOCKET_RECV_FROM_PARAMS_LEN);
-
- // Since we are in blocking state - wait for event complete
- SimpleLinkWaitEvent(opcode, &tSocketReadEvent);
-
- // In case the number of bytes is more then zero - read data
- if (tSocketReadEvent.iNumberOfBytes > 0)
- {
- // Wait for the data in a synchronous way. Here we assume that the bug is
- // big enough to store also parameters of receive from too....
- SimpleLinkWaitData((unsigned char *)buf, (unsigned char *)from, (unsigned char *)fromlen);
- }
-
- errno = tSocketReadEvent.iNumberOfBytes;
-
- return(tSocketReadEvent.iNumberOfBytes);
-}
-
-//*****************************************************************************
-//
-//! recv
-//!
-//! @param[in] sd socket handle
-//! @param[out] buf Points to the buffer where the message should be stored
-//! @param[in] len Specifies the length in bytes of the buffer pointed to
-//! by the buffer argument.
-//! @param[in] flags Specifies the type of message reception.
-//! On this version, this parameter is not supported.
-//!
-//! @return Return the number of bytes received, or -1 if an error
-//! occurred
-//!
-//! @brief function receives a message from a connection-mode socket
-//!
-//! @sa recvfrom
-//!
-//! @Note On this version, only blocking mode is supported.
-//
-//*****************************************************************************
-
-int
-recv(long sd, void *buf, long len, long flags)
-{
- return(simple_link_recv(sd, buf, len, flags, NULL, NULL, HCI_CMND_RECV));
-}
-
-//*****************************************************************************
-//
-//! recvfrom
-//!
-//! @param[in] sd socket handle
-//! @param[out] buf Points to the buffer where the message should be stored
-//! @param[in] len Specifies the length in bytes of the buffer pointed to
-//! by the buffer argument.
-//! @param[in] flags Specifies the type of message reception.
-//! On this version, this parameter is not supported.
-//! @param[in] from pointer to an address structure indicating the source
-//! address: sockaddr. On this version only AF_INET is
-//! supported.
-//! @param[in] fromlen source address tructure size
-//!
-//! @return Return the number of bytes received, or -1 if an error
-//! occurred
-//!
-//! @brief read data from socket
-//! function receives a message from a connection-mode or
-//! connectionless-mode socket. Note that raw sockets are not
-//! supported.
-//!
-//! @sa recv
-//!
-//! @Note On this version, only blocking mode is supported.
-//
-//*****************************************************************************
-int
-recvfrom(long sd, void *buf, long len, long flags, sockaddr *from,
- socklen_t *fromlen)
-{
- return(simple_link_recv(sd, buf, len, flags, from, fromlen,
- HCI_CMND_RECVFROM));
-}
-
-//*****************************************************************************
-//
-//! simple_link_send
-//!
-//! @param sd socket handle
-//! @param buf write buffer
-//! @param len buffer length
-//! @param flags On this version, this parameter is not supported
-//! @param to pointer to an address structure indicating destination
-//! address
-//! @param tolen destination address structure size
-//!
-//! @return Return the number of bytes transmitted, or -1 if an error
-//! occurred, or -2 in case there are no free buffers available
-//! (only when SEND_NON_BLOCKING is enabled)
-//!
-//! @brief This function is used to transmit a message to another
-//! socket
-//
-//*****************************************************************************
-int
-simple_link_send(long sd, const void *buf, long len, long flags,
- const sockaddr *to, long tolen, long opcode)
-{
- unsigned char uArgSize = 0, addrlen;
- unsigned char *ptr, *pDataPtr = NULL, *args;
- unsigned long addr_offset = 0;
- int res;
- tBsdReadReturnParams tSocketSendEvent;
-
- // Check the bsd_arguments
- if (0 != (res = HostFlowControlConsumeBuff(sd)))
- {
- return res;
- }
-
- //Update the number of sent packets
- tSLInformation.NumberOfSentPackets++;
-
- // Allocate a buffer and construct a packet and send it over spi
- ptr = tSLInformation.pucTxCommandBuffer;
- args = (ptr + HEADERS_SIZE_DATA);
-
- // Update the offset of data and parameters according to the command
- switch(opcode)
- {
- case HCI_CMND_SENDTO:
- {
- addr_offset = len + sizeof(len) + sizeof(len);
- addrlen = 8;
- uArgSize = SOCKET_SENDTO_PARAMS_LEN;
- pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN;
- break;
- }
-
- case HCI_CMND_SEND:
- {
- tolen = 0;
- to = NULL;
- uArgSize = HCI_CMND_SEND_ARG_LENGTH;
- pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH;
- break;
- }
-
- default:
- {
- break;
- }
- }
-
- // Fill in temporary command buffer
- args = UINT32_TO_STREAM(args, sd);
- args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd));
- args = UINT32_TO_STREAM(args, len);
- args = UINT32_TO_STREAM(args, flags);
-
- if (opcode == HCI_CMND_SENDTO)
- {
- args = UINT32_TO_STREAM(args, addr_offset);
- args = UINT32_TO_STREAM(args, addrlen);
- }
-
- // Copy the data received from user into the TX Buffer
- ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)buf), len);
-
- // In case we are using SendTo, copy the to parameters
- if (opcode == HCI_CMND_SENDTO)
- {
- ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)to), tolen);
- }
-
- // Initiate a HCI command
- hci_data_send(opcode, ptr, uArgSize, len,(unsigned char*)to, tolen);
-
- if (opcode == HCI_CMND_SENDTO)
- SimpleLinkWaitEvent(HCI_EVNT_SENDTO, &tSocketSendEvent);
- else
- SimpleLinkWaitEvent(HCI_EVNT_SEND, &tSocketSendEvent);
-
- return (len);
-}
-
-
-//*****************************************************************************
-//
-//! send
-//!
-//! @param sd socket handle
-//! @param buf Points to a buffer containing the message to be sent
-//! @param len message size in bytes
-//! @param flags On this version, this parameter is not supported
-//!
-//! @return Return the number of bytes transmitted, or -1 if an
-//! error occurred
-//!
-//! @brief Write data to TCP socket
-//! This function is used to transmit a message to another
-//! socket.
-//!
-//! @Note On this version, only blocking mode is supported.
-//!
-//! @sa sendto
-//
-//*****************************************************************************
-
-int
-send(long sd, const void *buf, long len, long flags)
-{
- return(simple_link_send(sd, buf, len, flags, NULL, 0, HCI_CMND_SEND));
-}
-
-//*****************************************************************************
-//
-//! sendto
-//!
-//! @param sd socket handle
-//! @param buf Points to a buffer containing the message to be sent
-//! @param len message size in bytes
-//! @param flags On this version, this parameter is not supported
-//! @param to pointer to an address structure indicating the destination
-//! address: sockaddr. On this version only AF_INET is
-//! supported.
-//! @param tolen destination address structure size
-//!
-//! @return Return the number of bytes transmitted, or -1 if an
-//! error occurred
-//!
-//! @brief Write data to TCP socket
-//! This function is used to transmit a message to another
-//! socket.
-//!
-//! @Note On this version, only blocking mode is supported.
-//!
-//! @sa send
-//
-//*****************************************************************************
-
-int
-sendto(long sd, const void *buf, long len, long flags, const sockaddr *to,
- socklen_t tolen)
-{
- return(simple_link_send(sd, buf, len, flags, to, tolen, HCI_CMND_SENDTO));
-}
-
-//*****************************************************************************
-//
-//! mdnsAdvertiser
-//!
-//! @param[in] mdnsEnabled flag to enable/disable the mDNS feature
-//! @param[in] deviceServiceName Service name as part of the published
-//! canonical domain name
-//! @param[in] deviceServiceNameLength Length of the service name
-//!
-//!
-//! @return On success, zero is returned, return SOC_ERROR if socket was not
-//! opened successfully, or if an error occurred.
-//!
-//! @brief Set CC3000 in mDNS advertiser mode in order to advertise itself.
-//
-//*****************************************************************************
-
-int
-mdnsAdvertiser(unsigned short mdnsEnabled, char * deviceServiceName, unsigned short deviceServiceNameLength)
-{
- int ret;
- unsigned char *pTxBuffer, *pArgs;
-
- if (deviceServiceNameLength > MDNS_DEVICE_SERVICE_MAX_LENGTH)
- {
- return EFAIL;
- }
-
- pTxBuffer = tSLInformation.pucTxCommandBuffer;
- pArgs = (pTxBuffer + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
-
- // Fill in HCI packet structure
- pArgs = UINT32_TO_STREAM(pArgs, mdnsEnabled);
- pArgs = UINT32_TO_STREAM(pArgs, 8);
- pArgs = UINT32_TO_STREAM(pArgs, deviceServiceNameLength);
- ARRAY_TO_STREAM(pArgs, deviceServiceName, deviceServiceNameLength);
-
- // Initiate a HCI command
- hci_command_send(HCI_CMND_MDNS_ADVERTISE, pTxBuffer, SOCKET_MDNS_ADVERTISE_PARAMS_LEN + deviceServiceNameLength);
-
- // Since we are in blocking state - wait for event complete
- SimpleLinkWaitEvent(HCI_EVNT_MDNS_ADVERTISE, &ret);
-
- return ret;
-
-}
+/*****************************************************************************
+*
+* socket.c - CC3000 Host Driver Implementation.
+* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+
+//*****************************************************************************
+//
+//! \addtogroup socket_api
+//! @{
+//
+//*****************************************************************************
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <nuttx/cc3000/hci.h>
+#include <nuttx/cc3000/socket.h>
+#include <nuttx/cc3000/evnt_handler.h>
+#include <nuttx/cc3000/netapp.h>
+
+
+
+//Enable this flag if and only if you must comply with BSD socket
+//close() function
+#ifdef _API_USE_BSD_CLOSE
+ #define close(sd) closesocket(sd)
+#endif
+
+//Enable this flag if and only if you must comply with BSD socket read() and
+//write() functions
+#ifdef _API_USE_BSD_READ_WRITE
+ #define read(sd, buf, len, flags) recv(sd, buf, len, flags)
+ #define write(sd, buf, len, flags) send(sd, buf, len, flags)
+#endif
+
+#define SOCKET_OPEN_PARAMS_LEN (12)
+#define SOCKET_CLOSE_PARAMS_LEN (4)
+#define SOCKET_ACCEPT_PARAMS_LEN (4)
+#define SOCKET_BIND_PARAMS_LEN (20)
+#define SOCKET_LISTEN_PARAMS_LEN (8)
+#define SOCKET_GET_HOST_BY_NAME_PARAMS_LEN (9)
+#define SOCKET_CONNECT_PARAMS_LEN (20)
+#define SOCKET_SELECT_PARAMS_LEN (44)
+#define SOCKET_SET_SOCK_OPT_PARAMS_LEN (20)
+#define SOCKET_GET_SOCK_OPT_PARAMS_LEN (12)
+#define SOCKET_RECV_FROM_PARAMS_LEN (12)
+#define SOCKET_SENDTO_PARAMS_LEN (24)
+#define SOCKET_MDNS_ADVERTISE_PARAMS_LEN (12)
+
+
+// The legnth of arguments for the SEND command: sd + buff_offset + len + flags,
+// while size of each parameter is 32 bit - so the total length is 16 bytes;
+
+#define HCI_CMND_SEND_ARG_LENGTH (16)
+
+
+#define SELECT_TIMEOUT_MIN_MICRO_SECONDS 5000
+
+#define HEADERS_SIZE_DATA (SPI_HEADER_SIZE + 5)
+
+#define SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE)
+
+#define MDNS_DEVICE_SERVICE_MAX_LENGTH (32)
+
+
+//*****************************************************************************
+//
+//! HostFlowControlConsumeBuff
+//!
+//! @param sd socket descriptor
+//!
+//! @return 0 in case there are buffers available,
+//! -1 in case of bad socket
+//! -2 if there are no free buffers present (only when
+//! SEND_NON_BLOCKING is enabled)
+//!
+//! @brief if SEND_NON_BLOCKING not define - block until have free buffer
+//! becomes available, else return immediately with correct status
+//! regarding the buffers available.
+//
+//*****************************************************************************
+int
+HostFlowControlConsumeBuff(int sd)
+{
+#ifndef SEND_NON_BLOCKING
+ /* wait in busy loop */
+ do
+ {
+ // In case last transmission failed then we will return the last failure
+ // reason here.
+ // Note that the buffer will not be allocated in this case
+ if (tSLInformation.slTransmitDataError != 0)
+ {
+ errno = tSLInformation.slTransmitDataError;
+ tSLInformation.slTransmitDataError = 0;
+ return errno;
+ }
+
+ if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd))
+ return -1;
+ } while(0 == tSLInformation.usNumberOfFreeBuffers);
+
+ tSLInformation.usNumberOfFreeBuffers--;
+
+ return 0;
+#else
+
+ // In case last transmission failed then we will return the last failure
+ // reason here.
+ // Note that the buffer will not be allocated in this case
+ if (tSLInformation.slTransmitDataError != 0)
+ {
+ errno = tSLInformation.slTransmitDataError;
+ tSLInformation.slTransmitDataError = 0;
+ return errno;
+ }
+ if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd))
+ return -1;
+
+ //If there are no available buffers, return -2. It is recommended to use
+ // select or receive to see if there is any buffer occupied with received data
+ // If so, call receive() to release the buffer.
+ if(0 == tSLInformation.usNumberOfFreeBuffers)
+ {
+ return -2;
+ }
+ else
+ {
+ tSLInformation.usNumberOfFreeBuffers--;
+ return 0;
+ }
+#endif
+}
+
+//*****************************************************************************
+//
+//! socket
+//!
+//! @param domain selects the protocol family which will be used for
+//! communication. On this version only AF_INET is supported
+//! @param type specifies the communication semantics. On this version
+//! only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW are supported
+//! @param protocol specifies a particular protocol to be used with the
+//! socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are
+//! supported.
+//!
+//! @return On success, socket handle that is used for consequent socket
+//! operations. On error, -1 is returned.
+//!
+//! @brief create an endpoint for communication
+//! The socket function creates a socket that is bound to a specific
+//! transport service provider. This function is called by the
+//! application layer to obtain a socket handle.
+//
+//*****************************************************************************
+
+int
+socket(long domain, long type, long protocol)
+{
+ long ret;
+ uint8_t *ptr, *args;
+
+ ret = EFAIL;
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in HCI packet structure
+ args = UINT32_TO_STREAM(args, domain);
+ args = UINT32_TO_STREAM(args, type);
+ args = UINT32_TO_STREAM(args, protocol);
+
+ // Initiate a HCI command
+ hci_command_send(HCI_CMND_SOCKET, ptr, SOCKET_OPEN_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(HCI_CMND_SOCKET, &ret);
+
+ // Process the event
+ errno = ret;
+
+ set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
+
+ return(ret);
+}
+
+//*****************************************************************************
+//
+//! closesocket
+//!
+//! @param sd socket handle.
+//!
+//! @return On success, zero is returned. On error, -1 is returned.
+//!
+//! @brief The socket function closes a created socket.
+//
+//*****************************************************************************
+
+long
+closesocket(long sd)
+{
+ long ret;
+ uint8_t *ptr, *args;
+
+ ret = EFAIL;
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in HCI packet structure
+ args = UINT32_TO_STREAM(args, sd);
+
+ // Initiate a HCI command
+ hci_command_send(HCI_CMND_CLOSE_SOCKET,
+ ptr, SOCKET_CLOSE_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(HCI_CMND_CLOSE_SOCKET, &ret);
+ errno = ret;
+
+ // since 'close' call may result in either OK (and then it closed) or error
+ // mark this socket as invalid
+ set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
+
+ return(ret);
+}
+
+//*****************************************************************************
+//
+//! accept
+//!
+//! @param[in] sd socket descriptor (handle)
+//! @param[out] addr the argument addr is a pointer to a sockaddr structure
+//! This structure is filled in with the address of the
+//! peer socket, as known to the communications layer.
+//! determined. The exact format of the address returned
+//! addr is by the socket's address sockaddr.
+//! On this version only AF_INET is supported.
+//! This argument returns in network order.
+//! @param[out] addrlen the addrlen argument is a value-result argument:
+//! it should initially contain the size of the structure
+//! pointed to by addr.
+//!
+//! @return For socket in blocking mode:
+//! On success, socket handle. on failure negative
+//! For socket in non-blocking mode:
+//! - On connection establishment, socket handle
+//! - On connection pending, SOC_IN_PROGRESS (-2)
+//! - On failure, SOC_ERROR (-1)
+//!
+//! @brief accept a connection on a socket:
+//! This function is used with connection-based socket types
+//! (SOCK_STREAM). It extracts the first connection request on the
+//! queue of pending connections, creates a new connected socket, and
+//! returns a new file descriptor referring to that socket.
+//! The newly created socket is not in the listening state.
+//! The original socket sd is unaffected by this call.
+//! The argument sd is a socket that has been created with socket(),
+//! bound to a local address with bind(), and is listening for
+//! connections after a listen(). The argument addr is a pointer
+//! to a sockaddr structure. This structure is filled in with the
+//! address of the peer socket, as known to the communications layer.
+//! The exact format of the address returned addr is determined by the
+//! socket's address family. The addrlen argument is a value-result
+//! argument: it should initially contain the size of the structure
+//! pointed to by addr, on return it will contain the actual
+//! length (in bytes) of the address returned.
+//!
+//! @sa socket ; bind ; listen
+//
+//*****************************************************************************
+
+long
+accept(long sd, sockaddr *addr, socklen_t *addrlen)
+{
+ long ret;
+ uint8_t *ptr, *args;
+ tBsdReturnParams tAcceptReturnArguments;
+
+ ret = EFAIL;
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, sd);
+
+ // Initiate a HCI command
+ hci_command_send(HCI_CMND_ACCEPT,
+ ptr, SOCKET_ACCEPT_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(HCI_CMND_ACCEPT, &tAcceptReturnArguments);
+
+
+ // need specify return parameters!!!
+ memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN);
+ *addrlen = ASIC_ADDR_LEN;
+ errno = tAcceptReturnArguments.iStatus;
+ ret = errno;
+
+ // if succeeded, iStatus = new socket descriptor. otherwise - error number
+ if(M_IS_VALID_SD(ret))
+ {
+ set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
+ }
+ else
+ {
+ set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
+ }
+
+ return(ret);
+}
+
+//*****************************************************************************
+//
+//! bind
+//!
+//! @param[in] sd socket descriptor (handle)
+//! @param[out] addr specifies the destination address. On this version
+//! only AF_INET is supported.
+//! @param[out] addrlen contains the size of the structure pointed to by addr.
+//!
+//! @return On success, zero is returned. On error, -1 is returned.
+//!
+//! @brief assign a name to a socket
+//! This function gives the socket the local address addr.
+//! addr is addrlen bytes long. Traditionally, this is called when a
+//! socket is created with socket, it exists in a name space (address
+//! family) but has no name assigned.
+//! It is necessary to assign a local address before a SOCK_STREAM
+//! socket may receive connections.
+//!
+//! @sa socket ; accept ; listen
+//
+//*****************************************************************************
+
+long
+bind(long sd, const sockaddr *addr, long addrlen)
+{
+ long ret;
+ uint8_t *ptr, *args;
+
+ ret = EFAIL;
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ addrlen = ASIC_ADDR_LEN;
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, sd);
+ args = UINT32_TO_STREAM(args, 0x00000008);
+ args = UINT32_TO_STREAM(args, addrlen);
+ ARRAY_TO_STREAM(args, ((uint8_t *)addr), addrlen);
+
+ // Initiate a HCI command
+ hci_command_send(HCI_CMND_BIND,
+ ptr, SOCKET_BIND_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(HCI_CMND_BIND, &ret);
+
+ errno = ret;
+
+ return(ret);
+}
+
+//*****************************************************************************
+//
+//! listen
+//!
+//! @param[in] sd socket descriptor (handle)
+//! @param[in] backlog specifies the listen queue depth. On this version
+//! backlog is not supported.
+//! @return On success, zero is returned. On error, -1 is returned.
+//!
+//! @brief listen for connections on a socket
+//! The willingness to accept incoming connections and a queue
+//! limit for incoming connections are specified with listen(),
+//! and then the connections are accepted with accept.
+//! The listen() call applies only to sockets of type SOCK_STREAM
+//! The backlog parameter defines the maximum length the queue of
+//! pending connections may grow to.
+//!
+//! @sa socket ; accept ; bind
+//!
+//! @note On this version, backlog is not supported
+//
+//*****************************************************************************
+
+long
+listen(long sd, long backlog)
+{
+ long ret;
+ uint8_t *ptr, *args;
+
+ ret = EFAIL;
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, sd);
+ args = UINT32_TO_STREAM(args, backlog);
+
+ // Initiate a HCI command
+ hci_command_send(HCI_CMND_LISTEN,
+ ptr, SOCKET_LISTEN_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(HCI_CMND_LISTEN, &ret);
+ errno = ret;
+
+ return(ret);
+}
+
+//*****************************************************************************
+//
+//! gethostbyname
+//!
+//! @param[in] hostname host name
+//! @param[in] usNameLen name length
+//! @param[out] out_ip_addr This parameter is filled in with host IP address.
+//! In case that host name is not resolved,
+//! out_ip_addr is zero.
+//! @return On success, positive is returned. On error, negative is returned
+//!
+//! @brief Get host IP by name. Obtain the IP Address of machine on network,
+//! by its name.
+//!
+//! @note On this version, only blocking mode is supported. Also note that
+//! the function requires DNS server to be configured prior to its usage.
+//
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+int
+gethostbyname(char * hostname, uint16_t usNameLen,
+ unsigned long* out_ip_addr)
+{
+ tBsdGethostbynameParams ret;
+ uint8_t *ptr, *args;
+
+ errno = EFAIL;
+
+ if (usNameLen > HOSTNAME_MAX_LENGTH)
+ {
+ return errno;
+ }
+
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
+
+ // Fill in HCI packet structure
+ args = UINT32_TO_STREAM(args, 8);
+ args = UINT32_TO_STREAM(args, usNameLen);
+ ARRAY_TO_STREAM(args, hostname, usNameLen);
+
+ // Initiate a HCI command
+ hci_command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN
+ + usNameLen - 1);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(HCI_EVNT_BSD_GETHOSTBYNAME, &ret);
+
+ errno = ret.retVal;
+
+ (*((long*)out_ip_addr)) = ret.outputAddress;
+
+ return (errno);
+
+}
+#endif
+
+//*****************************************************************************
+//
+//! connect
+//!
+//! @param[in] sd socket descriptor (handle)
+//! @param[in] addr specifies the destination addr. On this version
+//! only AF_INET is supported.
+//! @param[out] addrlen contains the size of the structure pointed to by addr
+//! @return On success, zero is returned. On error, -1 is returned
+//!
+//! @brief initiate a connection on a socket
+//! Function connects the socket referred to by the socket descriptor
+//! sd, to the address specified by addr. The addrlen argument
+//! specifies the size of addr. The format of the address in addr is
+//! determined by the address space of the socket. If it is of type
+//! SOCK_DGRAM, this call specifies the peer with which the socket is
+//! to be associated; this address is that to which datagrams are to be
+//! sent, and the only address from which datagrams are to be received.
+//! If the socket is of type SOCK_STREAM, this call attempts to make a
+//! connection to another socket. The other socket is specified by
+//! address, which is an address in the communications space of the
+//! socket. Note that the function implements only blocking behavior
+//! thus the caller will be waiting either for the connection
+//! establishment or for the connection establishment failure.
+//!
+//! @sa socket
+//
+//*****************************************************************************
+
+long
+connect(long sd, const sockaddr *addr, long addrlen)
+{
+ long int ret;
+ uint8_t *ptr, *args;
+
+ ret = EFAIL;
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
+ addrlen = 8;
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, sd);
+ args = UINT32_TO_STREAM(args, 0x00000008);
+ args = UINT32_TO_STREAM(args, addrlen);
+ ARRAY_TO_STREAM(args, ((uint8_t *)addr), addrlen);
+
+ // Initiate a HCI command
+ hci_command_send(HCI_CMND_CONNECT,
+ ptr, SOCKET_CONNECT_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(HCI_CMND_CONNECT, &ret);
+
+ errno = ret;
+
+ return((long)ret);
+}
+
+
+//*****************************************************************************
+//
+//! select
+//!
+//! @param[in] nfds the highest-numbered file descriptor in any of the
+//! three sets, plus 1.
+//! @param[out] writesds socket descriptors list for write monitoring
+//! @param[out] readsds socket descriptors list for read monitoring
+//! @param[out] exceptsds socket descriptors list for exception monitoring
+//! @param[in] timeout is an upper bound on the amount of time elapsed
+//! before select() returns. Null means infinity
+//! timeout. The minimum timeout is 5 milliseconds,
+//! less than 5 milliseconds will be set
+//! automatically to 5 milliseconds.
+//! @return On success, select() returns the number of file descriptors
+//! contained in the three returned descriptor sets (that is, the
+//! total number of bits that are set in readfds, writefds,
+//! exceptfds) which may be zero if the timeout expires before
+//! anything interesting happens.
+//! On error, -1 is returned.
+//! *readsds - return the sockets on which Read request will
+//! return without delay with valid data.
+//! *writesds - return the sockets on which Write request
+//! will return without delay.
+//! *exceptsds - return the sockets which closed recently.
+//!
+//! @brief Monitor socket activity
+//! Select allow a program to monitor multiple file descriptors,
+//! waiting until one or more of the file descriptors become
+//! "ready" for some class of I/O operation
+//!
+//! @Note If the timeout value set to less than 5ms it will automatically set
+//! to 5ms to prevent overload of the system
+//!
+//! @sa socket
+//
+//*****************************************************************************
+
+int
+select(long nfds, TICC3000fd_set *readsds, TICC3000fd_set *writesds, TICC3000fd_set *exceptsds,
+ struct timeval *timeout)
+{
+ uint8_t *ptr, *args;
+ tBsdSelectRecvParams tParams;
+ unsigned long is_blocking;
+
+ if( timeout == NULL)
+ {
+ is_blocking = 1; /* blocking , infinity timeout */
+ }
+ else
+ {
+ is_blocking = 0; /* no blocking, timeout */
+ }
+
+ // Fill in HCI packet structure
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, nfds);
+ args = UINT32_TO_STREAM(args, 0x00000014);
+ args = UINT32_TO_STREAM(args, 0x00000014);
+ args = UINT32_TO_STREAM(args, 0x00000014);
+ args = UINT32_TO_STREAM(args, 0x00000014);
+ args = UINT32_TO_STREAM(args, is_blocking);
+ args = UINT32_TO_STREAM(args, ((readsds) ? *(unsigned long*)readsds : 0));
+ args = UINT32_TO_STREAM(args, ((writesds) ? *(unsigned long*)writesds : 0));
+ args = UINT32_TO_STREAM(args, ((exceptsds) ? *(unsigned long*)exceptsds : 0));
+
+ if (timeout)
+ {
+ if ( 0 == timeout->tv_sec && timeout->tv_usec <
+ SELECT_TIMEOUT_MIN_MICRO_SECONDS)
+ {
+ timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS;
+ }
+ args = UINT32_TO_STREAM(args, timeout->tv_sec);
+ args = UINT32_TO_STREAM(args, timeout->tv_usec);
+ }
+
+ // Initiate a HCI command
+ hci_command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(HCI_EVNT_SELECT, &tParams);
+
+ // Update actually read FD
+ if (tParams.iStatus >= 0)
+ {
+ if (readsds)
+ {
+ memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd));
+ }
+
+ if (writesds)
+ {
+ memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd));
+ }
+
+ if (exceptsds)
+ {
+ memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd));
+ }
+
+ return(tParams.iStatus);
+
+ }
+ else
+ {
+ errno = tParams.iStatus;
+ return(-1);
+ }
+}
+
+//*****************************************************************************
+//
+//! setsockopt
+//!
+//! @param[in] sd socket handle
+//! @param[in] level defines the protocol level for this option
+//! @param[in] optname defines the option name to Interrogate
+//! @param[in] optval specifies a value for the option
+//! @param[in] optlen specifies the length of the option value
+//! @return On success, zero is returned. On error, -1 is returned
+//!
+//! @brief set socket options
+//! This function manipulate the options associated with a socket.
+//! Options may exist at multiple protocol levels; they are always
+//! present at the uppermost socket level.
+//! When manipulating socket options the level at which the option
+//! resides and the name of the option must be specified.
+//! To manipulate options at the socket level, level is specified as
+//! SOL_SOCKET. To manipulate options at any other level the protocol
+//! number of the appropriate protocol controlling the option is
+//! supplied. For example, to indicate that an option is to be
+//! interpreted by the TCP protocol, level should be set to the
+//! protocol number of TCP;
+//! The parameters optval and optlen are used to access optval -
+//! use for setsockopt(). For getsockopt() they identify a buffer
+//! in which the value for the requested option(s) are to
+//! be returned. For getsockopt(), optlen is a value-result
+//! parameter, initially containing the size of the buffer
+//! pointed to by option_value, and modified on return to
+//! indicate the actual size of the value returned. If no option
+//! value is to be supplied or returned, option_value may be NULL.
+//!
+//! @Note On this version the following two socket options are enabled:
+//! The only protocol level supported in this version
+//! is SOL_SOCKET (level).
+//! 1. SOCKOPT_RECV_TIMEOUT (optname)
+//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout
+//! in milliseconds.
+//! In that case optval should be pointer to unsigned long.
+//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on
+//! or off.
+//! In that case optval should be SOCK_ON or SOCK_OFF (optval).
+//!
+//! @sa getsockopt
+//
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+int
+setsockopt(long sd, long level, long optname, const void *optval,
+ socklen_t optlen)
+{
+ int ret;
+ uint8_t *ptr, *args;
+
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, sd);
+ args = UINT32_TO_STREAM(args, level);
+ args = UINT32_TO_STREAM(args, optname);
+ args = UINT32_TO_STREAM(args, 0x00000008);
+ args = UINT32_TO_STREAM(args, optlen);
+ ARRAY_TO_STREAM(args, ((uint8_t *)optval), optlen);
+
+ // Initiate a HCI command
+ hci_command_send(HCI_CMND_SETSOCKOPT,
+ ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN + optlen);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(HCI_CMND_SETSOCKOPT, &ret);
+
+ if (ret >= 0)
+ {
+ return (0);
+ }
+ else
+ {
+ errno = ret;
+ return ret;
+ }
+}
+#endif
+
+//*****************************************************************************
+//
+//! getsockopt
+//!
+//! @param[in] sd socket handle
+//! @param[in] level defines the protocol level for this option
+//! @param[in] optname defines the option name to Interrogate
+//! @param[out] optval specifies a value for the option
+//! @param[out] optlen specifies the length of the option value
+//! @return On success, zero is returned. On error, -1 is returned
+//!
+//! @brief set socket options
+//! This function manipulate the options associated with a socket.
+//! Options may exist at multiple protocol levels; they are always
+//! present at the uppermost socket level.
+//! When manipulating socket options the level at which the option
+//! resides and the name of the option must be specified.
+//! To manipulate options at the socket level, level is specified as
+//! SOL_SOCKET. To manipulate options at any other level the protocol
+//! number of the appropriate protocol controlling the option is
+//! supplied. For example, to indicate that an option is to be
+//! interpreted by the TCP protocol, level should be set to the
+//! protocol number of TCP;
+//! The parameters optval and optlen are used to access optval -
+//! use for setsockopt(). For getsockopt() they identify a buffer
+//! in which the value for the requested option(s) are to
+//! be returned. For getsockopt(), optlen is a value-result
+//! parameter, initially containing the size of the buffer
+//! pointed to by option_value, and modified on return to
+//! indicate the actual size of the value returned. If no option
+//! value is to be supplied or returned, option_value may be NULL.
+//!
+//! @Note On this version the following two socket options are enabled:
+//! The only protocol level supported in this version
+//! is SOL_SOCKET (level).
+//! 1. SOCKOPT_RECV_TIMEOUT (optname)
+//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout
+//! in milliseconds.
+//! In that case optval should be pointer to unsigned long.
+//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on
+//! or off.
+//! In that case optval should be SOCK_ON or SOCK_OFF (optval).
+//!
+//! @sa setsockopt
+//
+//*****************************************************************************
+
+int
+getsockopt (long sd, long level, long optname, void *optval, socklen_t *optlen)
+{
+ uint8_t *ptr, *args;
+ tBsdGetSockOptReturnParams tRetParams;
+
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, sd);
+ args = UINT32_TO_STREAM(args, level);
+ args = UINT32_TO_STREAM(args, optname);
+
+ // Initiate a HCI command
+ hci_command_send(HCI_CMND_GETSOCKOPT,
+ ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(HCI_CMND_GETSOCKOPT, &tRetParams);
+
+ if (((int8_t)tRetParams.iStatus) >= 0)
+ {
+ *optlen = 4;
+ memcpy(optval, tRetParams.ucOptValue, 4);
+ return (0);
+ }
+ else
+ {
+ errno = tRetParams.iStatus;
+ return errno;
+ }
+}
+
+//*****************************************************************************
+//
+//! simple_link_recv
+//!
+//! @param sd socket handle
+//! @param buf read buffer
+//! @param len buffer length
+//! @param flags indicates blocking or non-blocking operation
+//! @param from pointer to an address structure indicating source address
+//! @param fromlen source address structure size
+//!
+//! @return Return the number of bytes received, or -1 if an error
+//! occurred
+//!
+//! @brief Read data from socket
+//! Return the length of the message on successful completion.
+//! If a message is too long to fit in the supplied buffer,
+//! excess bytes may be discarded depending on the type of
+//! socket the message is received from
+//
+//*****************************************************************************
+int
+simple_link_recv(long sd, void *buf, long len, long flags, sockaddr *from,
+ socklen_t *fromlen, long opcode)
+{
+ uint8_t *ptr, *args;
+ tBsdReadReturnParams tSocketReadEvent;
+
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in HCI packet structure
+ args = UINT32_TO_STREAM(args, sd);
+ args = UINT32_TO_STREAM(args, len);
+ args = UINT32_TO_STREAM(args, flags);
+
+ // Generate the read command, and wait for the
+ hci_command_send(opcode, ptr, SOCKET_RECV_FROM_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(opcode, &tSocketReadEvent);
+
+ // In case the number of bytes is more then zero - read data
+ if (tSocketReadEvent.iNumberOfBytes > 0)
+ {
+ // Wait for the data in a synchronous way. Here we assume that the bug is
+ // big enough to store also parameters of receive from too....
+ SimpleLinkWaitData((uint8_t *)buf, (uint8_t *)from, (uint8_t *)fromlen);
+ }
+
+ errno = tSocketReadEvent.iNumberOfBytes;
+
+ return(tSocketReadEvent.iNumberOfBytes);
+}
+
+//*****************************************************************************
+//
+//! recv
+//!
+//! @param[in] sd socket handle
+//! @param[out] buf Points to the buffer where the message should be stored
+//! @param[in] len Specifies the length in bytes of the buffer pointed to
+//! by the buffer argument.
+//! @param[in] flags Specifies the type of message reception.
+//! On this version, this parameter is not supported.
+//!
+//! @return Return the number of bytes received, or -1 if an error
+//! occurred
+//!
+//! @brief function receives a message from a connection-mode socket
+//!
+//! @sa recvfrom
+//!
+//! @Note On this version, only blocking mode is supported.
+//
+//*****************************************************************************
+
+int
+recv(long sd, void *buf, long len, long flags)
+{
+ return(simple_link_recv(sd, buf, len, flags, NULL, NULL, HCI_CMND_RECV));
+}
+
+//*****************************************************************************
+//
+//! recvfrom
+//!
+//! @param[in] sd socket handle
+//! @param[out] buf Points to the buffer where the message should be stored
+//! @param[in] len Specifies the length in bytes of the buffer pointed to
+//! by the buffer argument.
+//! @param[in] flags Specifies the type of message reception.
+//! On this version, this parameter is not supported.
+//! @param[in] from pointer to an address structure indicating the source
+//! address: sockaddr. On this version only AF_INET is
+//! supported.
+//! @param[in] fromlen source address tructure size
+//!
+//! @return Return the number of bytes received, or -1 if an error
+//! occurred
+//!
+//! @brief read data from socket
+//! function receives a message from a connection-mode or
+//! connectionless-mode socket. Note that raw sockets are not
+//! supported.
+//!
+//! @sa recv
+//!
+//! @Note On this version, only blocking mode is supported.
+//
+//*****************************************************************************
+int
+recvfrom(long sd, void *buf, long len, long flags, sockaddr *from,
+ socklen_t *fromlen)
+{
+ return(simple_link_recv(sd, buf, len, flags, from, fromlen,
+ HCI_CMND_RECVFROM));
+}
+
+//*****************************************************************************
+//
+//! simple_link_send
+//!
+//! @param sd socket handle
+//! @param buf write buffer
+//! @param len buffer length
+//! @param flags On this version, this parameter is not supported
+//! @param to pointer to an address structure indicating destination
+//! address
+//! @param tolen destination address structure size
+//!
+//! @return Return the number of bytes transmitted, or -1 if an error
+//! occurred, or -2 in case there are no free buffers available
+//! (only when SEND_NON_BLOCKING is enabled)
+//!
+//! @brief This function is used to transmit a message to another
+//! socket
+//
+//*****************************************************************************
+int
+simple_link_send(long sd, const void *buf, long len, long flags,
+ const sockaddr *to, long tolen, long opcode)
+{
+ uint8_t uArgSize = 0, addrlen;
+ uint8_t *ptr, *pDataPtr = NULL, *args;
+ unsigned long addr_offset = 0;
+ int res;
+ tBsdReadReturnParams tSocketSendEvent;
+
+ // Check the bsd_arguments
+ if (0 != (res = HostFlowControlConsumeBuff(sd)))
+ {
+ return res;
+ }
+
+ //Update the number of sent packets
+ tSLInformation.NumberOfSentPackets++;
+
+ // Allocate a buffer and construct a packet and send it over spi
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + HEADERS_SIZE_DATA);
+
+ // Update the offset of data and parameters according to the command
+ switch(opcode)
+ {
+ case HCI_CMND_SENDTO:
+ {
+ addr_offset = len + sizeof(len) + sizeof(len);
+ addrlen = 8;
+ uArgSize = SOCKET_SENDTO_PARAMS_LEN;
+ pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN;
+ break;
+ }
+
+ case HCI_CMND_SEND:
+ {
+ tolen = 0;
+ to = NULL;
+ uArgSize = HCI_CMND_SEND_ARG_LENGTH;
+ pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH;
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, sd);
+ args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd));
+ args = UINT32_TO_STREAM(args, len);
+ args = UINT32_TO_STREAM(args, flags);
+
+ if (opcode == HCI_CMND_SENDTO)
+ {
+ args = UINT32_TO_STREAM(args, addr_offset);
+ args = UINT32_TO_STREAM(args, addrlen);
+ }
+
+ // Copy the data received from user into the TX Buffer
+ ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)buf), len);
+
+ // In case we are using SendTo, copy the to parameters
+ if (opcode == HCI_CMND_SENDTO)
+ {
+ ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)to), tolen);
+ }
+
+ // Initiate a HCI command
+ hci_data_send(opcode, ptr, uArgSize, len,(uint8_t*)to, tolen);
+
+ if (opcode == HCI_CMND_SENDTO)
+ SimpleLinkWaitEvent(HCI_EVNT_SENDTO, &tSocketSendEvent);
+ else
+ SimpleLinkWaitEvent(HCI_EVNT_SEND, &tSocketSendEvent);
+
+ return (len);
+}
+
+
+//*****************************************************************************
+//
+//! send
+//!
+//! @param sd socket handle
+//! @param buf Points to a buffer containing the message to be sent
+//! @param len message size in bytes
+//! @param flags On this version, this parameter is not supported
+//!
+//! @return Return the number of bytes transmitted, or -1 if an
+//! error occurred
+//!
+//! @brief Write data to TCP socket
+//! This function is used to transmit a message to another
+//! socket.
+//!
+//! @Note On this version, only blocking mode is supported.
+//!
+//! @sa sendto
+//
+//*****************************************************************************
+
+int
+send(long sd, const void *buf, long len, long flags)
+{
+ return(simple_link_send(sd, buf, len, flags, NULL, 0, HCI_CMND_SEND));
+}
+
+//*****************************************************************************
+//
+//! sendto
+//!
+//! @param sd socket handle
+//! @param buf Points to a buffer containing the message to be sent
+//! @param len message size in bytes
+//! @param flags On this version, this parameter is not supported
+//! @param to pointer to an address structure indicating the destination
+//! address: sockaddr. On this version only AF_INET is
+//! supported.
+//! @param tolen destination address structure size
+//!
+//! @return Return the number of bytes transmitted, or -1 if an
+//! error occurred
+//!
+//! @brief Write data to TCP socket
+//! This function is used to transmit a message to another
+//! socket.
+//!
+//! @Note On this version, only blocking mode is supported.
+//!
+//! @sa send
+//
+//*****************************************************************************
+
+int
+sendto(long sd, const void *buf, long len, long flags, const sockaddr *to,
+ socklen_t tolen)
+{
+ return(simple_link_send(sd, buf, len, flags, to, tolen, HCI_CMND_SENDTO));
+}
+
+//*****************************************************************************
+//
+//! mdnsAdvertiser
+//!
+//! @param[in] mdnsEnabled flag to enable/disable the mDNS feature
+//! @param[in] deviceServiceName Service name as part of the published
+//! canonical domain name
+//! @param[in] deviceServiceNameLength Length of the service name
+//!
+//!
+//! @return On success, zero is returned, return SOC_ERROR if socket was not
+//! opened successfully, or if an error occurred.
+//!
+//! @brief Set CC3000 in mDNS advertiser mode in order to advertise itself.
+//
+//*****************************************************************************
+
+int
+mdnsAdvertiser(uint16_t mdnsEnabled, char * deviceServiceName, uint16_t deviceServiceNameLength)
+{
+ int ret;
+ uint8_t *pTxBuffer, *pArgs;
+
+ if (deviceServiceNameLength > MDNS_DEVICE_SERVICE_MAX_LENGTH)
+ {
+ return EFAIL;
+ }
+
+ pTxBuffer = tSLInformation.pucTxCommandBuffer;
+ pArgs = (pTxBuffer + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
+
+ // Fill in HCI packet structure
+ pArgs = UINT32_TO_STREAM(pArgs, mdnsEnabled);
+ pArgs = UINT32_TO_STREAM(pArgs, 8);
+ pArgs = UINT32_TO_STREAM(pArgs, deviceServiceNameLength);
+ ARRAY_TO_STREAM(pArgs, deviceServiceName, deviceServiceNameLength);
+
+ // Initiate a HCI command
+ hci_command_send(HCI_CMND_MDNS_ADVERTISE, pTxBuffer, SOCKET_MDNS_ADVERTISE_PARAMS_LEN + deviceServiceNameLength);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(HCI_EVNT_MDNS_ADVERTISE, &ret);
+
+ return ret;
+
+}