CC3000HostDriver for device TI CC3000 some changes were made due to mbed compiler and the use of void*

Dependents:   CC3000Test

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers socket.cpp Source File

socket.cpp

00001 /*****************************************************************************
00002 *
00003 *  socket.c  - CC3000 Host Driver Implementation.
00004 *  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
00005 *
00006 *  Redistribution and use in source and binary forms, with or without
00007 *  modification, are permitted provided that the following conditions
00008 *  are met:
00009 *
00010 *    Redistributions of source code must retain the above copyright
00011 *    notice, this list of conditions and the following disclaimer.
00012 *
00013 *    Redistributions in binary form must reproduce the above copyright
00014 *    notice, this list of conditions and the following disclaimer in the
00015 *    documentation and/or other materials provided with the   
00016 *    distribution.
00017 *
00018 *    Neither the name of Texas Instruments Incorporated nor the names of
00019 *    its contributors may be used to endorse or promote products derived
00020 *    from this software without specific prior written permission.
00021 *
00022 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
00023 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
00024 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00025 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
00026 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
00027 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
00028 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00029 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00030 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
00031 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
00032 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 *
00034 *****************************************************************************/
00035 
00036 //*****************************************************************************
00037 //
00038 //! \addtogroup socket_api
00039 //! @{
00040 //
00041 //*****************************************************************************
00042 
00043 #include <stdio.h>
00044 #include <string.h>
00045 #include <stdlib.h>
00046 #include "hci.h"
00047 #include "socket.h"
00048 #include "evnt_handler.h"
00049 #include "netapp.h"
00050 
00051 
00052 
00053 //Enable this flag if and only if you must comply with BSD socket 
00054 //close() function
00055 #ifdef _API_USE_BSD_CLOSE
00056    #define close(sd) closesocket(sd)
00057 #endif
00058 
00059 //Enable this flag if and only if you must comply with BSD socket read() and 
00060 //write() functions
00061 #ifdef _API_USE_BSD_READ_WRITE
00062               #define read(sd, buf, len, flags) recv(sd, buf, len, flags)
00063               #define write(sd, buf, len, flags) send(sd, buf, len, flags)
00064 #endif
00065 
00066 #define SOCKET_OPEN_PARAMS_LEN                (12)
00067 #define SOCKET_CLOSE_PARAMS_LEN                (4)
00068 #define SOCKET_ACCEPT_PARAMS_LEN            (4)
00069 #define SOCKET_BIND_PARAMS_LEN                (20)
00070 #define SOCKET_LISTEN_PARAMS_LEN            (8)
00071 #define SOCKET_GET_HOST_BY_NAME_PARAMS_LEN    (9)
00072 #define SOCKET_CONNECT_PARAMS_LEN            (20)
00073 #define SOCKET_SELECT_PARAMS_LEN            (44)
00074 #define SOCKET_SET_SOCK_OPT_PARAMS_LEN        (20)
00075 #define SOCKET_GET_SOCK_OPT_PARAMS_LEN        (12)
00076 #define SOCKET_RECV_FROM_PARAMS_LEN            (12)
00077 #define SOCKET_SENDTO_PARAMS_LEN            (24)
00078 #define SOCKET_MDNS_ADVERTISE_PARAMS_LEN    (12)
00079 
00080 
00081 // The legnth of arguments for the SEND command: sd + buff_offset + len + flags, 
00082 // while size of each parameter is 32 bit - so the total length is 16 bytes;
00083 
00084 #define HCI_CMND_SEND_ARG_LENGTH    (16)
00085 
00086 
00087 #define SELECT_TIMEOUT_MIN_MICRO_SECONDS  5000
00088 
00089 #define HEADERS_SIZE_DATA       (SPI_HEADER_SIZE + 5)
00090 
00091 #define SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE  (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE)
00092 
00093 #define MDNS_DEVICE_SERVICE_MAX_LENGTH     (32)
00094 
00095 
00096 //*****************************************************************************
00097 //
00098 //! HostFlowControlConsumeBuff
00099 //!
00100 //!  @param  sd  socket descriptor
00101 //!
00102 //!  @return 0 in case there are buffers available, 
00103 //!          -1 in case of bad socket
00104 //!          -2 if there are no free buffers present (only when 
00105 //!          SEND_NON_BLOCKING is enabled)
00106 //!
00107 //!  @brief  if SEND_NON_BLOCKING not define - block until have free buffer 
00108 //!          becomes available, else return immediately  with correct status 
00109 //!          regarding the buffers available.
00110 //
00111 //*****************************************************************************
00112 int
00113 HostFlowControlConsumeBuff(int sd)
00114 {
00115 #ifndef SEND_NON_BLOCKING
00116     /* wait in busy loop */
00117     do
00118     {
00119         // In case last transmission failed then we will return the last failure 
00120         // reason here.
00121         // Note that the buffer will not be allocated in this case
00122         if (tSLInformation.slTransmitDataError != 0)
00123         {
00124             errno = tSLInformation.slTransmitDataError;
00125             tSLInformation.slTransmitDataError = 0;
00126             return errno;
00127         }
00128         
00129         if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd))
00130             return -1;
00131     } while(0 == tSLInformation.usNumberOfFreeBuffers);
00132     
00133     tSLInformation.usNumberOfFreeBuffers--;
00134     
00135     return 0;
00136 #else
00137     
00138     // In case last transmission failed then we will return the last failure 
00139     // reason here.
00140     // Note that the buffer will not be allocated in this case
00141     if (tSLInformation.slTransmitDataError != 0)
00142     {
00143         errno = tSLInformation.slTransmitDataError;
00144         tSLInformation.slTransmitDataError = 0;
00145         return errno;
00146     }
00147     if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd))
00148         return -1;
00149     
00150     //If there are no available buffers, return -2. It is recommended to use  
00151     // select or receive to see if there is any buffer occupied with received data
00152     // If so, call receive() to release the buffer.
00153     if(0 == tSLInformation.usNumberOfFreeBuffers)
00154     {
00155         return -2;
00156     }
00157     else
00158     {
00159         tSLInformation.usNumberOfFreeBuffers--;
00160         return 0;
00161     }
00162 #endif
00163 }
00164 
00165 //*****************************************************************************
00166 //
00167 //! socket
00168 //!
00169 //!  @param  domain    selects the protocol family which will be used for 
00170 //!                    communication. On this version only AF_INET is supported
00171 //!  @param  type      specifies the communication semantics. On this version 
00172 //!                    only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW are supported
00173 //!  @param  protocol  specifies a particular protocol to be used with the 
00174 //!                    socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are 
00175 //!                    supported.
00176 //!
00177 //!  @return  On success, socket handle that is used for consequent socket 
00178 //!           operations. On error, -1 is returned.
00179 //!
00180 //!  @brief  create an endpoint for communication
00181 //!          The socket function creates a socket that is bound to a specific 
00182 //!          transport service provider. This function is called by the 
00183 //!          application layer to obtain a socket handle.
00184 //
00185 //*****************************************************************************
00186 
00187 int
00188 socket(long domain, long type, long protocol)
00189 {
00190     long ret;
00191     unsigned char *ptr, *args;
00192     
00193     ret = EFAIL;
00194     ptr = tSLInformation.pucTxCommandBuffer;
00195     args = (ptr + HEADERS_SIZE_CMD);
00196     
00197     // Fill in HCI packet structure
00198     args = UINT32_TO_STREAM(args, domain);
00199     args = UINT32_TO_STREAM(args, type);
00200     args = UINT32_TO_STREAM(args, protocol);
00201     
00202     // Initiate a HCI command
00203     hci_command_send(HCI_CMND_SOCKET, ptr, SOCKET_OPEN_PARAMS_LEN);
00204     
00205     // Since we are in blocking state - wait for event complete
00206     SimpleLinkWaitEvent(HCI_CMND_SOCKET, &ret);
00207     
00208     // Process the event 
00209     errno = ret;
00210     
00211     set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
00212     
00213     return(ret);
00214 }
00215 
00216 //*****************************************************************************
00217 //
00218 //! closesocket
00219 //!
00220 //!  @param  sd    socket handle.
00221 //!
00222 //!  @return  On success, zero is returned. On error, -1 is returned.
00223 //!
00224 //!  @brief  The socket function closes a created socket.
00225 //
00226 //*****************************************************************************
00227 
00228 long
00229 closesocket(long sd)
00230 {
00231     long ret;
00232     unsigned char *ptr, *args;
00233     
00234     ret = EFAIL;
00235     ptr = tSLInformation.pucTxCommandBuffer;
00236     args = (ptr + HEADERS_SIZE_CMD);
00237     
00238     // Fill in HCI packet structure
00239     args = UINT32_TO_STREAM(args, sd);
00240     
00241     // Initiate a HCI command
00242     hci_command_send(HCI_CMND_CLOSE_SOCKET,
00243                                      ptr, SOCKET_CLOSE_PARAMS_LEN);
00244     
00245     // Since we are in blocking state - wait for event complete
00246     SimpleLinkWaitEvent(HCI_CMND_CLOSE_SOCKET, &ret);
00247     errno = ret;
00248     
00249     // since 'close' call may result in either OK (and then it closed) or error 
00250     // mark this socket as invalid 
00251     set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
00252     
00253     return(ret);
00254 }
00255 
00256 //*****************************************************************************
00257 //
00258 //! accept
00259 //!
00260 //!  @param[in]   sd      socket descriptor (handle)              
00261 //!  @param[out]  addr    the argument addr is a pointer to a sockaddr structure
00262 //!                       This structure is filled in with the address of the  
00263 //!                       peer socket, as known to the communications layer.        
00264 //!                       determined. The exact format of the address returned             
00265 //!                       addr is by the socket's address sockaddr. 
00266 //!                       On this version only AF_INET is supported.
00267 //!                       This argument returns in network order.
00268 //!  @param[out] addrlen  the addrlen argument is a value-result argument: 
00269 //!                       it should initially contain the size of the structure
00270 //!                       pointed to by addr.
00271 //!
00272 //!  @return  For socket in blocking mode:
00273 //!                      On success, socket handle. on failure negative
00274 //!                  For socket in non-blocking mode:
00275 //!                     - On connection establishment, socket handle
00276 //!                     - On connection pending, SOC_IN_PROGRESS (-2)
00277 //!                   - On failure, SOC_ERROR    (-1)
00278 //!
00279 //!  @brief  accept a connection on a socket:
00280 //!          This function is used with connection-based socket types 
00281 //!          (SOCK_STREAM). It extracts the first connection request on the 
00282 //!          queue of pending connections, creates a new connected socket, and
00283 //!          returns a new file descriptor referring to that socket.
00284 //!          The newly created socket is not in the listening state. 
00285 //!          The original socket sd is unaffected by this call. 
00286 //!          The argument sd is a socket that has been created with socket(),
00287 //!          bound to a local address with bind(), and is  listening for 
00288 //!          connections after a listen(). The argument addr is a pointer 
00289 //!          to a sockaddr structure. This structure is filled in with the 
00290 //!          address of the peer socket, as known to the communications layer.
00291 //!          The exact format of the address returned addr is determined by the 
00292 //!          socket's address family. The addrlen argument is a value-result
00293 //!          argument: it should initially contain the size of the structure
00294 //!          pointed to by addr, on return it will contain the actual 
00295 //!          length (in bytes) of the address returned.
00296 //!
00297 //! @sa     socket ; bind ; listen
00298 //
00299 //*****************************************************************************
00300 
00301 long
00302 accept(long sd, sockaddr *addr, socklen_t *addrlen)
00303 {
00304     long ret;
00305     unsigned char *ptr, *args;
00306     tBsdReturnParams tAcceptReturnArguments;
00307     
00308     ret = EFAIL;
00309     ptr = tSLInformation.pucTxCommandBuffer;
00310     args = (ptr + HEADERS_SIZE_CMD);
00311     
00312     // Fill in temporary command buffer
00313     args = UINT32_TO_STREAM(args, sd);
00314     
00315     // Initiate a HCI command
00316     hci_command_send(HCI_CMND_ACCEPT, ptr, SOCKET_ACCEPT_PARAMS_LEN);
00317     
00318     // Since we are in blocking state - wait for event complete
00319     SimpleLinkWaitEvent(HCI_CMND_ACCEPT, (long*)&tAcceptReturnArguments);
00320     
00321     
00322     // need specify return parameters!!!
00323     memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN);
00324     *addrlen = ASIC_ADDR_LEN;
00325     errno = tAcceptReturnArguments.iStatus; 
00326     ret = errno;
00327     
00328     // if succeeded, iStatus = new socket descriptor. otherwise - error number 
00329     if(M_IS_VALID_SD(ret))
00330     {
00331         set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
00332     }
00333     else
00334     {
00335         set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
00336     }
00337     
00338     return(ret);
00339 }
00340 
00341 //*****************************************************************************
00342 //
00343 //! bind
00344 //!
00345 //!  @param[in]   sd      socket descriptor (handle)              
00346 //!  @param[out]  addr    specifies the destination address. On this version 
00347 //!                       only AF_INET is supported.
00348 //!  @param[out] addrlen  contains the size of the structure pointed to by addr.
00349 //!
00350 //!  @return      On success, zero is returned. On error, -1 is returned.
00351 //!
00352 //!  @brief  assign a name to a socket
00353 //!          This function gives the socket the local address addr.
00354 //!          addr is addrlen bytes long. Traditionally, this is called when a 
00355 //!          socket is created with socket, it exists in a name space (address 
00356 //!          family) but has no name assigned.
00357 //!          It is necessary to assign a local address before a SOCK_STREAM
00358 //!          socket may receive connections.
00359 //!
00360 //! @sa     socket ; accept ; listen
00361 //
00362 //*****************************************************************************
00363 
00364 long
00365 bind(long sd, const sockaddr *addr, long addrlen)
00366 {
00367     long ret;
00368     unsigned char *ptr, *args;
00369     
00370     ret = EFAIL;
00371     ptr = tSLInformation.pucTxCommandBuffer;
00372     args = (ptr + HEADERS_SIZE_CMD);
00373     
00374     addrlen = ASIC_ADDR_LEN;
00375     
00376     // Fill in temporary command buffer
00377     args = UINT32_TO_STREAM(args, sd);
00378     args = UINT32_TO_STREAM(args, 0x00000008);
00379     args = UINT32_TO_STREAM(args, addrlen);
00380     ARRAY_TO_STREAM(args, ((unsigned char *)addr), addrlen);
00381     
00382     // Initiate a HCI command
00383     hci_command_send(HCI_CMND_BIND, ptr, SOCKET_BIND_PARAMS_LEN);
00384     
00385     // Since we are in blocking state - wait for event complete
00386     SimpleLinkWaitEvent(HCI_CMND_BIND, &ret);
00387     
00388     errno = ret;
00389   
00390     return(ret);
00391 }
00392 
00393 //*****************************************************************************
00394 //
00395 //! listen
00396 //!
00397 //!  @param[in]   sd      socket descriptor (handle)              
00398 //!  @param[in]  backlog  specifies the listen queue depth. On this version
00399 //!                       backlog is not supported.
00400 //!  @return      On success, zero is returned. On error, -1 is returned.
00401 //!
00402 //!  @brief  listen for connections on a socket
00403 //!          The willingness to accept incoming connections and a queue
00404 //!          limit for incoming connections are specified with listen(),
00405 //!          and then the connections are accepted with accept.
00406 //!          The listen() call applies only to sockets of type SOCK_STREAM
00407 //!          The backlog parameter defines the maximum length the queue of
00408 //!          pending connections may grow to. 
00409 //!
00410 //! @sa     socket ; accept ; bind
00411 //!
00412 //! @note   On this version, backlog is not supported
00413 //
00414 //*****************************************************************************
00415 
00416 long
00417 listen(long sd, long backlog)
00418 {
00419     long ret;
00420     unsigned char *ptr, *args;
00421     
00422     ret = EFAIL;
00423     ptr = tSLInformation.pucTxCommandBuffer;
00424     args = (ptr + HEADERS_SIZE_CMD);
00425     
00426     // Fill in temporary command buffer
00427     args = UINT32_TO_STREAM(args, sd);
00428     args = UINT32_TO_STREAM(args, backlog);
00429     
00430     // Initiate a HCI command
00431     hci_command_send(HCI_CMND_LISTEN, ptr, SOCKET_LISTEN_PARAMS_LEN);
00432     
00433     // Since we are in blocking state - wait for event complete
00434     SimpleLinkWaitEvent(HCI_CMND_LISTEN, &ret);
00435     errno = ret;
00436     
00437     return(ret);
00438 }
00439 
00440 //*****************************************************************************
00441 //
00442 //! gethostbyname
00443 //!
00444 //!  @param[in]   hostname     host name              
00445 //!  @param[in]   usNameLen    name length 
00446 //!  @param[out]  out_ip_addr  This parameter is filled in with host IP address. 
00447 //!                            In case that host name is not resolved, 
00448 //!                            out_ip_addr is zero.                  
00449 //!  @return      On success, positive is returned. On error, negative is returned
00450 //!
00451 //!  @brief  Get host IP by name. Obtain the IP Address of machine on network, 
00452 //!          by its name.
00453 //!
00454 //!  @note  On this version, only blocking mode is supported. Also note that
00455 //!             the function requires DNS server to be configured prior to its usage.
00456 //
00457 //*****************************************************************************
00458 
00459 #ifndef CC3000_TINY_DRIVER
00460 int 
00461 gethostbyname(char * hostname, unsigned short usNameLen, unsigned long* out_ip_addr)
00462 {
00463     tBsdGethostbynameParams ret;
00464     unsigned char *ptr, *args;
00465     
00466     errno = EFAIL;
00467     
00468     if (usNameLen > HOSTNAME_MAX_LENGTH)
00469     {
00470         return errno;
00471     }
00472     
00473     ptr = tSLInformation.pucTxCommandBuffer;
00474     args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
00475     
00476     // Fill in HCI packet structure
00477     args = UINT32_TO_STREAM(args, 8);
00478     args = UINT32_TO_STREAM(args, usNameLen);
00479     ARRAY_TO_STREAM(args, hostname, usNameLen);
00480     
00481     // Initiate a HCI command
00482     hci_command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN + usNameLen - 1);
00483     
00484     // Since we are in blocking state - wait for event complete
00485     SimpleLinkWaitEvent(HCI_EVNT_BSD_GETHOSTBYNAME, (long*)&ret);
00486     
00487     errno = ret.retVal;
00488     
00489     (*((long*)out_ip_addr)) = ret.outputAddress;
00490     
00491     return (errno);
00492     
00493 }
00494 #endif
00495 
00496 //*****************************************************************************
00497 //
00498 //! connect
00499 //!
00500 //!  @param[in]   sd       socket descriptor (handle)         
00501 //!  @param[in]   addr     specifies the destination addr. On this version
00502 //!                        only AF_INET is supported.
00503 //!  @param[out]  addrlen  contains the size of the structure pointed to by addr    
00504 //!  @return      On success, zero is returned. On error, -1 is returned
00505 //!
00506 //!  @brief  initiate a connection on a socket 
00507 //!          Function connects the socket referred to by the socket descriptor 
00508 //!          sd, to the address specified by addr. The addrlen argument 
00509 //!          specifies the size of addr. The format of the address in addr is 
00510 //!          determined by the address space of the socket. If it is of type 
00511 //!          SOCK_DGRAM, this call specifies the peer with which the socket is 
00512 //!          to be associated; this address is that to which datagrams are to be
00513 //!          sent, and the only address from which datagrams are to be received.  
00514 //!          If the socket is of type SOCK_STREAM, this call attempts to make a 
00515 //!          connection to another socket. The other socket is specified  by 
00516 //!          address, which is an address in the communications space of the
00517 //!          socket. Note that the function implements only blocking behavior 
00518 //!          thus the caller will be waiting either for the connection 
00519 //!          establishment or for the connection establishment failure.
00520 //!
00521 //!  @sa socket
00522 //
00523 //*****************************************************************************
00524 
00525 long
00526 connect(long sd, const sockaddr *addr, long addrlen)
00527 {
00528     long int ret;
00529     unsigned char *ptr, *args;
00530     
00531     ret = EFAIL;
00532     ptr = tSLInformation.pucTxCommandBuffer;
00533     args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
00534     addrlen = 8;
00535     
00536     // Fill in temporary command buffer
00537     args = UINT32_TO_STREAM(args, sd);
00538     args = UINT32_TO_STREAM(args, 0x00000008);
00539     args = UINT32_TO_STREAM(args, addrlen);
00540     ARRAY_TO_STREAM(args, ((unsigned char *)addr), addrlen);
00541     
00542     // Initiate a HCI command
00543     hci_command_send(HCI_CMND_CONNECT,
00544                                      ptr, SOCKET_CONNECT_PARAMS_LEN);
00545     
00546     // Since we are in blocking state - wait for event complete
00547     SimpleLinkWaitEvent(HCI_CMND_CONNECT, &ret);
00548     
00549     errno = ret;
00550     
00551     return((long)ret);
00552 }
00553 
00554 
00555 //*****************************************************************************
00556 //
00557 //! select
00558 //!
00559 //!  @param[in]   nfds       the highest-numbered file descriptor in any of the
00560 //!                           three sets, plus 1.     
00561 //!  @param[out]   writesds   socket descriptors list for write monitoring
00562 //!  @param[out]   readsds    socket descriptors list for read monitoring  
00563 //!  @param[out]   exceptsds  socket descriptors list for exception monitoring
00564 //!  @param[in]   timeout     is an upper bound on the amount of time elapsed
00565 //!                           before select() returns. Null means infinity 
00566 //!                           timeout. The minimum timeout is 5 milliseconds,
00567 //!                          less than 5 milliseconds will be set
00568 //!                           automatically to 5 milliseconds.
00569 //!  @return      On success, select() returns the number of file descriptors
00570 //!             contained in the three returned descriptor sets (that is, the
00571 //!             total number of bits that are set in readfds, writefds,
00572 //!             exceptfds) which may be zero if the timeout expires before
00573 //!             anything interesting  happens.
00574 //!             On error, -1 is returned.
00575 //!                   *readsds - return the sockets on which Read request will
00576 //!                              return without delay with valid data.
00577 //!                   *writesds - return the sockets on which Write request 
00578 //!                                 will return without delay.
00579 //!                   *exceptsds - return the sockets which closed recently.
00580 //!
00581 //!  @brief  Monitor socket activity  
00582 //!          Select allow a program to monitor multiple file descriptors,
00583 //!          waiting until one or more of the file descriptors become 
00584 //!         "ready" for some class of I/O operation 
00585 //!
00586 //!  @Note   If the timeout value set to less than 5ms it will automatically set
00587 //!          to 5ms to prevent overload of the system
00588 //!
00589 //!  @sa socket
00590 //
00591 //*****************************************************************************
00592 
00593 int
00594 select(long nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, 
00595        struct timeval *timeout)
00596 {
00597     unsigned char *ptr, *args;
00598     tBsdSelectRecvParams tParams;
00599     unsigned long is_blocking;
00600     
00601     if( timeout == NULL)
00602     {
00603         is_blocking = 1; /* blocking , infinity timeout */
00604     }
00605     else
00606     {
00607         is_blocking = 0; /* no blocking, timeout */
00608     }
00609     
00610     // Fill in HCI packet structure
00611     ptr = tSLInformation.pucTxCommandBuffer;
00612     args = (ptr + HEADERS_SIZE_CMD);
00613     
00614     // Fill in temporary command buffer
00615     args = UINT32_TO_STREAM(args, nfds);
00616     args = UINT32_TO_STREAM(args, 0x00000014);
00617     args = UINT32_TO_STREAM(args, 0x00000014);
00618     args = UINT32_TO_STREAM(args, 0x00000014);
00619     args = UINT32_TO_STREAM(args, 0x00000014);
00620     args = UINT32_TO_STREAM(args, is_blocking);
00621     args = UINT32_TO_STREAM(args, ((readsds) ? *(unsigned long*)readsds : 0));
00622     args = UINT32_TO_STREAM(args, ((writesds) ? *(unsigned long*)writesds : 0));
00623     args = UINT32_TO_STREAM(args, ((exceptsds) ? *(unsigned long*)exceptsds : 0));
00624     
00625     if (timeout)
00626     {
00627         if ( 0 == timeout->tv_sec && timeout->tv_usec < 
00628                 SELECT_TIMEOUT_MIN_MICRO_SECONDS)
00629         {
00630             timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS;
00631         }
00632         args = UINT32_TO_STREAM(args, timeout->tv_sec);
00633         args = UINT32_TO_STREAM(args, timeout->tv_usec);
00634     }
00635     
00636     // Initiate a HCI command
00637     hci_command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN);
00638     
00639     // Since we are in blocking state - wait for event complete
00640     SimpleLinkWaitEvent(HCI_EVNT_SELECT, (long*)&tParams);
00641     
00642     // Update actually read FD
00643     if (tParams.iStatus >= 0)
00644     {
00645         if (readsds)
00646         {
00647             memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd));
00648         }
00649         
00650         if (writesds)
00651         {
00652             memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd)); 
00653         }
00654         
00655         if (exceptsds)
00656         {
00657             memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd)); 
00658         }
00659         
00660         return(tParams.iStatus);
00661         
00662     }
00663     else
00664     {
00665         errno = tParams.iStatus;
00666         return(-1);
00667     }
00668 }
00669 
00670 //*****************************************************************************
00671 //
00672 //! setsockopt
00673 //!
00674 //!  @param[in]   sd          socket handle
00675 //!  @param[in]   level       defines the protocol level for this option
00676 //!  @param[in]   optname     defines the option name to Interrogate
00677 //!  @param[in]   optval      specifies a value for the option
00678 //!  @param[in]   optlen      specifies the length of the option value
00679 //!  @return      On success, zero is returned. On error, -1 is returned
00680 //!
00681 //!  @brief  set socket options
00682 //!          This function manipulate the options associated with a socket.
00683 //!          Options may exist at multiple protocol levels; they are always
00684 //!          present at the uppermost socket level.
00685 //!          When manipulating socket options the level at which the option 
00686 //!          resides and the name of the option must be specified.  
00687 //!          To manipulate options at the socket level, level is specified as 
00688 //!          SOL_SOCKET. To manipulate options at any other level the protocol 
00689 //!          number of the appropriate protocol controlling the option is 
00690 //!          supplied. For example, to indicate that an option is to be 
00691 //!          interpreted by the TCP protocol, level should be set to the 
00692 //!          protocol number of TCP; 
00693 //!          The parameters optval and optlen are used to access optval - 
00694 //!          use for setsockopt(). For getsockopt() they identify a buffer
00695 //!          in which the value for the requested option(s) are to 
00696 //!          be returned. For getsockopt(), optlen is a value-result 
00697 //!          parameter, initially containing the size of the buffer 
00698 //!          pointed to by option_value, and modified on return to 
00699 //!          indicate the actual size of the value returned. If no option 
00700 //!          value is to be supplied or returned, option_value may be NULL.
00701 //!
00702 //!  @Note   On this version the following two socket options are enabled:
00703 //!                 The only protocol level supported in this version
00704 //!          is SOL_SOCKET (level).
00705 //!               1. SOCKOPT_RECV_TIMEOUT (optname)
00706 //!                  SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout 
00707 //!           in milliseconds.
00708 //!                In that case optval should be pointer to unsigned long.
00709 //!               2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on 
00710 //!           or off.
00711 //!                In that case optval should be SOCK_ON or SOCK_OFF (optval).
00712 //!
00713 //!  @sa getsockopt
00714 //
00715 //*****************************************************************************
00716 
00717 #ifndef CC3000_TINY_DRIVER
00718 int
00719 setsockopt(long sd, long level, long optname, const void *optval,
00720                      socklen_t optlen)
00721 {
00722     int ret;
00723     unsigned char *ptr, *args;
00724     
00725     ptr = tSLInformation.pucTxCommandBuffer;
00726     args = (ptr + HEADERS_SIZE_CMD);
00727     
00728     // Fill in temporary command buffer
00729     args = UINT32_TO_STREAM(args, sd);
00730     args = UINT32_TO_STREAM(args, level);
00731     args = UINT32_TO_STREAM(args, optname);
00732     args = UINT32_TO_STREAM(args, 0x00000008);
00733     args = UINT32_TO_STREAM(args, optlen);
00734     ARRAY_TO_STREAM(args, ((unsigned char *)optval), optlen);
00735     
00736     // Initiate a HCI command
00737     hci_command_send(HCI_CMND_SETSOCKOPT, ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN  + optlen);
00738     
00739     // Since we are in blocking state - wait for event complete
00740     SimpleLinkWaitEvent(HCI_CMND_SETSOCKOPT, (long*)&ret);
00741     
00742     if (ret >= 0)
00743     {
00744         return (0);
00745     }
00746     else
00747     {
00748         errno = ret;
00749         return (errno);
00750     }
00751 }
00752 #endif
00753 
00754 //*****************************************************************************
00755 //
00756 //! getsockopt
00757 //!
00758 //!  @param[in]   sd          socket handle
00759 //!  @param[in]   level       defines the protocol level for this option
00760 //!  @param[in]   optname     defines the option name to Interrogate
00761 //!  @param[out]   optval      specifies a value for the option
00762 //!  @param[out]   optlen      specifies the length of the option value
00763 //!  @return      On success, zero is returned. On error, -1 is returned
00764 //!
00765 //!  @brief  set socket options
00766 //!          This function manipulate the options associated with a socket.
00767 //!          Options may exist at multiple protocol levels; they are always
00768 //!          present at the uppermost socket level.
00769 //!          When manipulating socket options the level at which the option 
00770 //!          resides and the name of the option must be specified.  
00771 //!          To manipulate options at the socket level, level is specified as 
00772 //!          SOL_SOCKET. To manipulate options at any other level the protocol 
00773 //!          number of the appropriate protocol controlling the option is 
00774 //!          supplied. For example, to indicate that an option is to be 
00775 //!          interpreted by the TCP protocol, level should be set to the 
00776 //!          protocol number of TCP; 
00777 //!          The parameters optval and optlen are used to access optval - 
00778 //!          use for setsockopt(). For getsockopt() they identify a buffer
00779 //!          in which the value for the requested option(s) are to 
00780 //!          be returned. For getsockopt(), optlen is a value-result 
00781 //!          parameter, initially containing the size of the buffer 
00782 //!          pointed to by option_value, and modified on return to 
00783 //!          indicate the actual size of the value returned. If no option 
00784 //!          value is to be supplied or returned, option_value may be NULL.
00785 //!
00786 //!  @Note   On this version the following two socket options are enabled:
00787 //!                 The only protocol level supported in this version
00788 //!          is SOL_SOCKET (level).
00789 //!               1. SOCKOPT_RECV_TIMEOUT (optname)
00790 //!                  SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout 
00791 //!           in milliseconds.
00792 //!                In that case optval should be pointer to unsigned long.
00793 //!               2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on 
00794 //!           or off.
00795 //!                In that case optval should be SOCK_ON or SOCK_OFF (optval).
00796 //!
00797 //!  @sa setsockopt
00798 //
00799 //*****************************************************************************
00800 
00801 int
00802 getsockopt (long sd, long level, long optname, void *optval, socklen_t *optlen)
00803 {
00804     unsigned char *ptr, *args;
00805     tBsdGetSockOptReturnParams  tRetParams;
00806     
00807     ptr = tSLInformation.pucTxCommandBuffer;
00808     args = (ptr + HEADERS_SIZE_CMD);
00809     
00810     // Fill in temporary command buffer
00811     args = UINT32_TO_STREAM(args, sd);
00812     args = UINT32_TO_STREAM(args, level);
00813     args = UINT32_TO_STREAM(args, optname);
00814     
00815     // Initiate a HCI command
00816     hci_command_send(HCI_CMND_GETSOCKOPT, ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN);
00817     
00818     // Since we are in blocking state - wait for event complete
00819     SimpleLinkWaitEvent(HCI_CMND_GETSOCKOPT, (long*)&tRetParams);
00820     
00821     if (((signed char)tRetParams.iStatus) >= 0)
00822     {
00823         *optlen = 4;
00824         memcpy(optval, tRetParams.ucOptValue, 4);
00825         return (0);
00826     }
00827     else
00828     {
00829         errno = tRetParams.iStatus;
00830         return (errno);
00831     }
00832 }
00833 
00834 //*****************************************************************************
00835 //
00836 //!  simple_link_recv
00837 //!
00838 //!  @param sd       socket handle
00839 //!  @param buf      read buffer
00840 //!  @param len      buffer length
00841 //!  @param flags    indicates blocking or non-blocking operation
00842 //!  @param from     pointer to an address structure indicating source address
00843 //!  @param fromlen  source address structure size
00844 //!
00845 //!  @return         Return the number of bytes received, or -1 if an error
00846 //!                  occurred
00847 //!
00848 //!  @brief          Read data from socket
00849 //!                  Return the length of the message on successful completion.
00850 //!                  If a message is too long to fit in the supplied buffer,
00851 //!                  excess bytes may be discarded depending on the type of
00852 //!                  socket the message is received from
00853 //
00854 //*****************************************************************************
00855 int
00856 simple_link_recv(long sd, unsigned char *buf, long len, long flags, sockaddr *from, socklen_t *fromlen, long opcode)
00857 {
00858     unsigned char *ptr, *args;
00859     tBsdReadReturnParams tSocketReadEvent;
00860     
00861     ptr = tSLInformation.pucTxCommandBuffer;
00862     args = (ptr + HEADERS_SIZE_CMD);
00863     
00864     // Fill in HCI packet structure
00865     args = UINT32_TO_STREAM(args, sd);
00866     args = UINT32_TO_STREAM(args, len);
00867     args = UINT32_TO_STREAM(args, flags);
00868     
00869     // Generate the read command, and wait for the 
00870     hci_command_send(opcode,  ptr, SOCKET_RECV_FROM_PARAMS_LEN);
00871     
00872     // Since we are in blocking state - wait for event complete
00873     SimpleLinkWaitEvent(opcode, (long*)&tSocketReadEvent);
00874     
00875     // In case the number of bytes is more then zero - read data
00876     if (tSocketReadEvent.iNumberOfBytes > 0)
00877     {
00878         // Wait for the data in a synchronous way. Here we assume that the bug is 
00879         // big enough to store also parameters of receive from too....
00880         SimpleLinkWaitData(buf, (unsigned char *)from, (unsigned char *)fromlen);
00881     }
00882     
00883     errno = tSocketReadEvent.iNumberOfBytes;
00884     
00885     return(tSocketReadEvent.iNumberOfBytes);
00886 }
00887 
00888 //*****************************************************************************
00889 //
00890 //!  recv
00891 //!
00892 //!  @param[in]  sd     socket handle
00893 //!  @param[out] buf    Points to the buffer where the message should be stored
00894 //!  @param[in]  len    Specifies the length in bytes of the buffer pointed to 
00895 //!                     by the buffer argument.
00896 //!  @param[in] flags   Specifies the type of message reception. 
00897 //!                     On this version, this parameter is not supported.
00898 //!
00899 //!  @return         Return the number of bytes received, or -1 if an error
00900 //!                  occurred
00901 //!
00902 //!  @brief          function receives a message from a connection-mode socket
00903 //!
00904 //!  @sa recvfrom
00905 //!
00906 //!  @Note On this version, only blocking mode is supported.
00907 //
00908 //*****************************************************************************
00909 
00910 int
00911 recv(long sd, unsigned char *buf, long len, long flags)
00912 {
00913     return(simple_link_recv(sd, buf, len, flags, NULL, NULL, HCI_CMND_RECV));
00914 }
00915 
00916 //*****************************************************************************
00917 //
00918 //!  recvfrom
00919 //!
00920 //!  @param[in]  sd     socket handle
00921 //!  @param[out] buf    Points to the buffer where the message should be stored
00922 //!  @param[in]  len    Specifies the length in bytes of the buffer pointed to 
00923 //!                     by the buffer argument.
00924 //!  @param[in] flags   Specifies the type of message reception. 
00925 //!                     On this version, this parameter is not supported.
00926 //!  @param[in] from   pointer to an address structure indicating the source
00927 //!                    address: sockaddr. On this version only AF_INET is
00928 //!                    supported.
00929 //!  @param[in] fromlen   source address tructure size
00930 //!
00931 //!  @return         Return the number of bytes received, or -1 if an error
00932 //!                  occurred
00933 //!
00934 //!  @brief         read data from socket
00935 //!                 function receives a message from a connection-mode or
00936 //!                 connectionless-mode socket. Note that raw sockets are not
00937 //!                 supported.
00938 //!
00939 //!  @sa recv
00940 //!
00941 //!  @Note On this version, only blocking mode is supported.
00942 //
00943 //*****************************************************************************
00944 int
00945 recvfrom(long sd, unsigned char *buf, long len, long flags, sockaddr *from, socklen_t *fromlen)
00946 {
00947     return(simple_link_recv(sd, buf, len, flags, from, fromlen, HCI_CMND_RECVFROM));
00948 }
00949 
00950 //*****************************************************************************
00951 //
00952 //!  simple_link_send
00953 //!
00954 //!  @param sd       socket handle
00955 //!  @param buf      write buffer
00956 //!  @param len      buffer length
00957 //!  @param flags    On this version, this parameter is not supported
00958 //!  @param to       pointer to an address structure indicating destination
00959 //!                  address
00960 //!  @param tolen    destination address structure size
00961 //!
00962 //!  @return         Return the number of bytes transmitted, or -1 if an error
00963 //!                  occurred, or -2 in case there are no free buffers available
00964 //!                 (only when SEND_NON_BLOCKING is enabled)
00965 //!
00966 //!  @brief          This function is used to transmit a message to another
00967 //!                  socket
00968 //
00969 //*****************************************************************************
00970 int
00971 simple_link_send(long sd, const void *buf, long len, long flags, const sockaddr *to, long tolen, long opcode)
00972 {    
00973     unsigned char uArgSize,  addrlen;
00974     unsigned char *ptr, *pDataPtr, *args;
00975     unsigned long addr_offset;
00976     int res;
00977         tBsdReadReturnParams tSocketSendEvent;
00978     
00979     // Check the bsd_arguments
00980     if (0 != (res = HostFlowControlConsumeBuff(sd)))
00981     {
00982         return res;
00983     }
00984     
00985     //Update the number of sent packets
00986     tSLInformation.NumberOfSentPackets++;
00987     
00988     // Allocate a buffer and construct a packet and send it over spi
00989     ptr = tSLInformation.pucTxCommandBuffer;
00990     args = (ptr + HEADERS_SIZE_DATA);
00991     
00992     // Update the offset of data and parameters according to the command
00993     switch(opcode)
00994     { 
00995     case HCI_CMND_SENDTO:
00996         {
00997             addr_offset = len + sizeof(len) + sizeof(len);
00998             addrlen = 8;
00999             uArgSize = SOCKET_SENDTO_PARAMS_LEN;
01000             pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN;
01001             break;
01002         }
01003         
01004     case HCI_CMND_SEND:
01005         {
01006             tolen = 0;
01007             to = NULL;
01008             uArgSize = HCI_CMND_SEND_ARG_LENGTH;
01009             pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH;
01010             break;
01011         }
01012         
01013     default:
01014         {
01015             break;
01016         }
01017     }
01018     
01019     // Fill in temporary command buffer
01020     args = UINT32_TO_STREAM(args, sd);
01021     args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd));
01022     args = UINT32_TO_STREAM(args, len);
01023     args = UINT32_TO_STREAM(args, flags);
01024     
01025     if (opcode == HCI_CMND_SENDTO)
01026     {
01027         args = UINT32_TO_STREAM(args, addr_offset);
01028         args = UINT32_TO_STREAM(args, addrlen);
01029     }
01030     
01031     // Copy the data received from user into the TX Buffer
01032     ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)buf), len);
01033     
01034     // In case we are using SendTo, copy the to parameters
01035     if (opcode == HCI_CMND_SENDTO)
01036     {    
01037         ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)to), tolen);
01038     }
01039     
01040     // Initiate a HCI command
01041     hci_data_send(opcode, ptr, uArgSize, len,(unsigned char*)to, tolen);
01042         
01043          if (opcode == HCI_CMND_SENDTO)
01044             SimpleLinkWaitEvent(HCI_EVNT_SENDTO, (long*)&tSocketSendEvent);
01045          else
01046             SimpleLinkWaitEvent(HCI_EVNT_SEND, (long*)&tSocketSendEvent);
01047     
01048     return    (len);
01049 }
01050 
01051 
01052 //*****************************************************************************
01053 //
01054 //!  send
01055 //!
01056 //!  @param sd       socket handle
01057 //!  @param buf      Points to a buffer containing the message to be sent
01058 //!  @param len      message size in bytes
01059 //!  @param flags    On this version, this parameter is not supported
01060 //!
01061 //!  @return         Return the number of bytes transmitted, or -1 if an
01062 //!                  error occurred
01063 //!
01064 //!  @brief          Write data to TCP socket
01065 //!                  This function is used to transmit a message to another 
01066 //!                  socket.
01067 //!
01068 //!  @Note           On this version, only blocking mode is supported.
01069 //!
01070 //!  @sa             sendto
01071 //
01072 //*****************************************************************************
01073 
01074 int
01075 send(long sd, const void *buf, long len, long flags)
01076 {
01077     return(simple_link_send(sd, buf, len, flags, NULL, 0, HCI_CMND_SEND));
01078 }
01079 
01080 //*****************************************************************************
01081 //
01082 //!  sendto
01083 //!
01084 //!  @param sd       socket handle
01085 //!  @param buf      Points to a buffer containing the message to be sent
01086 //!  @param len      message size in bytes
01087 //!  @param flags    On this version, this parameter is not supported
01088 //!  @param to       pointer to an address structure indicating the destination
01089 //!                  address: sockaddr. On this version only AF_INET is
01090 //!                  supported.
01091 //!  @param tolen    destination address structure size
01092 //!
01093 //!  @return         Return the number of bytes transmitted, or -1 if an
01094 //!                  error occurred
01095 //!
01096 //!  @brief          Write data to TCP socket
01097 //!                  This function is used to transmit a message to another 
01098 //!                  socket.
01099 //!
01100 //!  @Note           On this version, only blocking mode is supported.
01101 //!
01102 //!  @sa             send
01103 //
01104 //*****************************************************************************
01105 
01106 int
01107 sendto(long sd, const void *buf, long len, long flags, const sockaddr *to, socklen_t tolen)
01108 {
01109     return(simple_link_send(sd, buf, len, flags, to, tolen, HCI_CMND_SENDTO));
01110 }
01111 
01112 //*****************************************************************************
01113 //
01114 //!  mdnsAdvertiser
01115 //!
01116 //!  @param[in] mdnsEnabled         flag to enable/disable the mDNS feature
01117 //!  @param[in] deviceServiceName   Service name as part of the published
01118 //!                                 canonical domain name
01119 //!  @param[in] deviceServiceNameLength   Length of the service name
01120 //!  
01121 //!
01122 //!  @return   On success, zero is returned, return SOC_ERROR if socket was not 
01123 //!            opened successfully, or if an error occurred.
01124 //!
01125 //!  @brief    Set CC3000 in mDNS advertiser mode in order to advertise itself.
01126 //
01127 //*****************************************************************************
01128 
01129 int
01130 mdnsAdvertiser(unsigned short mdnsEnabled, char * deviceServiceName, unsigned short deviceServiceNameLength)
01131 {
01132     int ret;
01133      unsigned char *pTxBuffer, *pArgs;
01134     
01135     if (deviceServiceNameLength > MDNS_DEVICE_SERVICE_MAX_LENGTH)
01136     {
01137         return EFAIL;
01138     }
01139     
01140     pTxBuffer = tSLInformation.pucTxCommandBuffer;
01141     pArgs = (pTxBuffer + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
01142     
01143     // Fill in HCI packet structure
01144     pArgs = UINT32_TO_STREAM(pArgs, mdnsEnabled);
01145     pArgs = UINT32_TO_STREAM(pArgs, 8);
01146     pArgs = UINT32_TO_STREAM(pArgs, deviceServiceNameLength);
01147     ARRAY_TO_STREAM(pArgs, deviceServiceName, deviceServiceNameLength);
01148     
01149     // Initiate a HCI command
01150     hci_command_send(HCI_CMND_MDNS_ADVERTISE, pTxBuffer, SOCKET_MDNS_ADVERTISE_PARAMS_LEN + deviceServiceNameLength);
01151     
01152     // Since we are in blocking state - wait for event complete
01153     SimpleLinkWaitEvent(HCI_EVNT_MDNS_ADVERTISE, (long*)&ret);
01154     
01155     return ret;
01156     
01157 }
01158