Driver for CC3000 Wi-Fi module

Dependencies:   NVIC_set_all_priorities

Dependents:   CC3000_Simple_Socket Wi-Go_IOT_Demo

Information

The current code has been reworked to a full object oriented application and contains an mbed socket compatible API.

CC3000 Wi-Fi module library

Info

This is the low level driver for TI's SimpleLink CC3000 device.
Port from Avnet's Wi-Go KEIL code (based on TI's CC3000 code).
Special thanks to Jim Carver from Avnet for providing the Wi-Go board and for his assistance.

Differences with TI's original code

The code functionality stays exactly the same.
In order to make it easier to use the code, following changes were made :

  • Addition of a tool to shift all IRQ priorities to a lower level since it is very important to keep the SPI handler at the highest system priority, the WLAN interrupt the second highest and all other system interrupts at a lower priority, so their handlers can be preempted by the CC3000 interrupts.
  • Addition of low level I/O controls and conditional compiler controls in cc3000_common.h.
  • CC3000 initialisation, pin declarations, SPI and WLAN irq priorities are set in Init_HostDriver , we need to call this function at the start of the main function.
  • The SPI and HCI code are joined into one file.
  • The include list has been rearranged - Only #include "wlan.h" is needed in the user API.
  • Part of the CC3000's user eeprom memory is used to store additional info (52 bytes in NVMEM_USER_FILE_1):
# bytesDescriptionInfo
1First time config parameterUseful when connecting
2Firmware updater versionused with the Firmware update tool
2Service Pack versionused with the Firmware update tool
3Driver Versionused with the Firmware update tool
3Firmware Versionused with the Firmware update tool
1CIK validation (Client Interface Key)
40CIK data (Client Interface Key)used with the exosite

Using the Library

A user API is needed to access the CC3000 functions.
Examples:

Using the library with other processors

cc3000_common.cpp loads the irq tool for all targets:
All current mbed targets are supported by this library.

#include "NVIC_set_all_priorities.h"


All low level settings that need to change are available in cc3000_common.h

//*****************************************************************************
//              PIN CONTROLS & COMPILE CONTROLS
//*****************************************************************************
// Compiler control
#define CC3000_UNENCRYPTED_SMART_CONFIG   // No encryption
//#define CC3000_TINY_DRIVER                // Driver for small memory model CPUs

//Interrupt controls
#define NVIC_ALL_IRQ        NVIC_set_all_irq_priorities(3);         // Set ALL interrupt priorities to level 3
#define NVIC_SPI_IRQ        NVIC_SetPriority(SPI0_IRQn, 0x0);       // Wi-Fi SPI interrupt must be higher priority than SysTick
#define NVIC_PORT_IRQ       NVIC_SetPriority(PORTA_IRQn, 0x1);
#define NVIC_SYSTICK_IRQ    NVIC_SetPriority(SysTick_IRQn, 0x2);    // SysTick set to lower priority than Wi-Fi SPI bus interrupt
//#define NVIC_ADC_IRQ        NVIC_SetPriority(ADC0_IRQn, 0x3);       // ADC is the lowest of all

// Wlan controls
#define WLAN_ISF_PCR        PORTA->PCR[16]
#define WLAN_ISF_ISFR       PORTA->ISFR
#define WLAN_ISF_MASK       (1<<16)

#define WLAN_ASSERT_CS      wlan_cs = 0;   //CS : active low
#define WLAN_DEASSERT_CS    wlan_cs = 1;

#define WLAN_ASSERT_EN      wlan_en = 1;   //EN : active high
#define WLAN_DEASSERT_EN    wlan_en = 0;

#define WLAN_READ_IRQ       wlan_int

#define WLAN_ENABLE_IRQ     wlan_int.fall(&WLAN_IRQHandler);
#define WLAN_DISABLE_IRQ    wlan_int.fall(NULL);

#define WLAN_IRQ_PIN_CREATE         InterruptIn wlan_int (PTA16);
#define WLAN_EN_PIN_CREATE          DigitalOut  wlan_en  (PTA13);
#define WLAN_CS_PIN_CREATE          DigitalOut  wlan_cs  (PTD0);
#define WLAN_SPI_PORT_CREATE        SPI wlan(PTD2, PTD3, PTC5); // mosi, miso, sclk

#define WLAN_SPI_PORT_INIT          wlan.format(8,1);
#define WLAN_SPI_SET_FREQ           wlan.frequency(12000000);
#define WLAN_SPI_SET_IRQ_HANDLER    wlan_int.fall(&WLAN_IRQHandler);

#define WLAN_SPI_WRITE              wlan.write(*data++);
#define WLAN_SPI_READ               wlan.write(0x03);          // !! DO NOT MODIFY the 0x03 parameter (CC3000 will not respond).

API documentation

Due to a little problem with the links on the mbed site, the API documentation is not directly accessible (will be solved in a next release).
Currently, it is only accessible by adding modules.html to the API doc link: http://mbed.org/users/frankvnk/code/CC3000_Hostdriver/docs/tip/modules.html

Committer:
frankvnk
Date:
Thu Jul 04 08:10:21 2013 +0000
Revision:
1:bbcaf0b2f367
Parent:
0:c44f0314d6ec
Child:
4:d8255a5aad46
Code cleanup - test printfs added

Who changed what in which revision?

UserRevisionLine numberNew contents of line
frankvnk 0:c44f0314d6ec 1 /*****************************************************************************
frankvnk 0:c44f0314d6ec 2 *
frankvnk 0:c44f0314d6ec 3 * socket.c - CC3000 Host Driver Implementation.
frankvnk 0:c44f0314d6ec 4 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
frankvnk 0:c44f0314d6ec 5 *
frankvnk 0:c44f0314d6ec 6 * Redistribution and use in source and binary forms, with or without
frankvnk 0:c44f0314d6ec 7 * modification, are permitted provided that the following conditions
frankvnk 0:c44f0314d6ec 8 * are met:
frankvnk 0:c44f0314d6ec 9 *
frankvnk 0:c44f0314d6ec 10 * Redistributions of source code must retain the above copyright
frankvnk 0:c44f0314d6ec 11 * notice, this list of conditions and the following disclaimer.
frankvnk 0:c44f0314d6ec 12 *
frankvnk 0:c44f0314d6ec 13 * Redistributions in binary form must reproduce the above copyright
frankvnk 0:c44f0314d6ec 14 * notice, this list of conditions and the following disclaimer in the
frankvnk 0:c44f0314d6ec 15 * documentation and/or other materials provided with the
frankvnk 0:c44f0314d6ec 16 * distribution.
frankvnk 0:c44f0314d6ec 17 *
frankvnk 0:c44f0314d6ec 18 * Neither the name of Texas Instruments Incorporated nor the names of
frankvnk 0:c44f0314d6ec 19 * its contributors may be used to endorse or promote products derived
frankvnk 0:c44f0314d6ec 20 * from this software without specific prior written permission.
frankvnk 0:c44f0314d6ec 21 *
frankvnk 0:c44f0314d6ec 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
frankvnk 0:c44f0314d6ec 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
frankvnk 0:c44f0314d6ec 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
frankvnk 0:c44f0314d6ec 25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
frankvnk 0:c44f0314d6ec 26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
frankvnk 0:c44f0314d6ec 27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
frankvnk 0:c44f0314d6ec 28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
frankvnk 0:c44f0314d6ec 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
frankvnk 0:c44f0314d6ec 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
frankvnk 0:c44f0314d6ec 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
frankvnk 0:c44f0314d6ec 32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
frankvnk 0:c44f0314d6ec 33 *
frankvnk 0:c44f0314d6ec 34 *****************************************************************************/
frankvnk 0:c44f0314d6ec 35
frankvnk 0:c44f0314d6ec 36 //*****************************************************************************
frankvnk 0:c44f0314d6ec 37 //
frankvnk 0:c44f0314d6ec 38 //! \addtogroup socket_api
frankvnk 0:c44f0314d6ec 39 //! @{
frankvnk 0:c44f0314d6ec 40 //
frankvnk 0:c44f0314d6ec 41 //*****************************************************************************
frankvnk 0:c44f0314d6ec 42
frankvnk 0:c44f0314d6ec 43 /*#include <stdio.h>
frankvnk 0:c44f0314d6ec 44 #include <string.h>
frankvnk 0:c44f0314d6ec 45 #include <stdlib.h>*/
frankvnk 0:c44f0314d6ec 46 #include "socket.h"
frankvnk 0:c44f0314d6ec 47 #include "hci.h"
frankvnk 0:c44f0314d6ec 48 #include "evnt_handler.h"
frankvnk 0:c44f0314d6ec 49 #include "netapp.h"
frankvnk 0:c44f0314d6ec 50
frankvnk 0:c44f0314d6ec 51 //Enable this flag if and only if you must comply with BSD socket
frankvnk 0:c44f0314d6ec 52 //close() function
frankvnk 0:c44f0314d6ec 53 #ifdef _API_USE_BSD_CLOSE
frankvnk 0:c44f0314d6ec 54 #define close(sd) closesocket(sd)
frankvnk 0:c44f0314d6ec 55 #endif
frankvnk 0:c44f0314d6ec 56
frankvnk 0:c44f0314d6ec 57 //Enable this flag if and only if you must comply with BSD socket read() and
frankvnk 0:c44f0314d6ec 58 //write() functions
frankvnk 0:c44f0314d6ec 59 #ifdef _API_USE_BSD_READ_WRITE
frankvnk 0:c44f0314d6ec 60 #define read(sd, buf, len, flags) recv(sd, buf, len, flags)
frankvnk 0:c44f0314d6ec 61 #define write(sd, buf, len, flags) send(sd, buf, len, flags)
frankvnk 0:c44f0314d6ec 62 #endif
frankvnk 0:c44f0314d6ec 63
frankvnk 0:c44f0314d6ec 64 #define SOCKET_OPEN_PARAMS_LEN (12)
frankvnk 0:c44f0314d6ec 65 #define SOCKET_CLOSE_PARAMS_LEN (4)
frankvnk 0:c44f0314d6ec 66 #define SOCKET_ACCEPT_PARAMS_LEN (4)
frankvnk 0:c44f0314d6ec 67 #define SOCKET_BIND_PARAMS_LEN (20)
frankvnk 0:c44f0314d6ec 68 #define SOCKET_LISTEN_PARAMS_LEN (8)
frankvnk 0:c44f0314d6ec 69 #define SOCKET_GET_HOST_BY_NAME_PARAMS_LEN (9)
frankvnk 0:c44f0314d6ec 70 #define SOCKET_CONNECT_PARAMS_LEN (20)
frankvnk 0:c44f0314d6ec 71 #define SOCKET_SELECT_PARAMS_LEN (44)
frankvnk 0:c44f0314d6ec 72 #define SOCKET_SET_SOCK_OPT_PARAMS_LEN (20)
frankvnk 0:c44f0314d6ec 73 #define SOCKET_GET_SOCK_OPT_PARAMS_LEN (12)
frankvnk 0:c44f0314d6ec 74 #define SOCKET_RECV_FROM_PARAMS_LEN (12)
frankvnk 0:c44f0314d6ec 75 #define SOCKET_SENDTO_PARAMS_LEN (24)
frankvnk 0:c44f0314d6ec 76 #define SOCKET_MDNS_ADVERTISE_PARAMS_LEN (12)
frankvnk 0:c44f0314d6ec 77
frankvnk 0:c44f0314d6ec 78 #define NULL 0
frankvnk 0:c44f0314d6ec 79
frankvnk 0:c44f0314d6ec 80 // The legnth of arguments for the SEND command: sd + buff_offset + len + flags,
frankvnk 0:c44f0314d6ec 81 // while size of each parameter is 32 bit - so the total length is 16 bytes;
frankvnk 0:c44f0314d6ec 82
frankvnk 0:c44f0314d6ec 83 #define HCI_CMND_SEND_ARG_LENGTH (16)
frankvnk 0:c44f0314d6ec 84
frankvnk 0:c44f0314d6ec 85
frankvnk 0:c44f0314d6ec 86 #define SELECT_TIMEOUT_MIN_MICRO_SECONDS 5000
frankvnk 0:c44f0314d6ec 87
frankvnk 0:c44f0314d6ec 88 #define HEADERS_SIZE_DATA (SPI_HEADER_SIZE + 5)
frankvnk 0:c44f0314d6ec 89
frankvnk 0:c44f0314d6ec 90 #define SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE)
frankvnk 0:c44f0314d6ec 91
frankvnk 0:c44f0314d6ec 92 #define MDNS_DEVICE_SERVICE_MAX_LENGTH (32)
frankvnk 0:c44f0314d6ec 93
frankvnk 0:c44f0314d6ec 94
frankvnk 0:c44f0314d6ec 95 //*****************************************************************************
frankvnk 0:c44f0314d6ec 96 //
frankvnk 0:c44f0314d6ec 97 //! HostFlowControlConsumeBuff
frankvnk 0:c44f0314d6ec 98 //!
frankvnk 0:c44f0314d6ec 99 //! @param sd socket descriptor
frankvnk 0:c44f0314d6ec 100 //!
frankvnk 0:c44f0314d6ec 101 //! @return 0 in case there are buffers available,
frankvnk 0:c44f0314d6ec 102 //! -1 in case of bad socket
frankvnk 0:c44f0314d6ec 103 //! -2 if there are no free buffers present (only when
frankvnk 0:c44f0314d6ec 104 //! SEND_NON_BLOCKING is enabled)
frankvnk 0:c44f0314d6ec 105 //!
frankvnk 0:c44f0314d6ec 106 //! @brief if SEND_NON_BLOCKING not define - block until have free buffer
frankvnk 0:c44f0314d6ec 107 //! becomes available, else return immediately with correct status
frankvnk 0:c44f0314d6ec 108 //! regarding the buffers available.
frankvnk 0:c44f0314d6ec 109 //
frankvnk 0:c44f0314d6ec 110 //*****************************************************************************
frankvnk 0:c44f0314d6ec 111 int HostFlowControlConsumeBuff(int sd)
frankvnk 0:c44f0314d6ec 112 {
frankvnk 0:c44f0314d6ec 113 #ifndef SEND_NON_BLOCKING
frankvnk 0:c44f0314d6ec 114 /* wait in busy loop */
frankvnk 0:c44f0314d6ec 115 do
frankvnk 0:c44f0314d6ec 116 {
frankvnk 0:c44f0314d6ec 117 // In case last transmission failed then we will return the last failure
frankvnk 0:c44f0314d6ec 118 // reason here.
frankvnk 0:c44f0314d6ec 119 // Note that the buffer will not be allocated in this case
frankvnk 0:c44f0314d6ec 120 if (tSLInformation.slTransmitDataError != 0)
frankvnk 0:c44f0314d6ec 121 {
frankvnk 0:c44f0314d6ec 122 errno = tSLInformation.slTransmitDataError;
frankvnk 0:c44f0314d6ec 123 tSLInformation.slTransmitDataError = 0;
frankvnk 0:c44f0314d6ec 124 return errno;
frankvnk 0:c44f0314d6ec 125 }
frankvnk 0:c44f0314d6ec 126
frankvnk 0:c44f0314d6ec 127 if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd))
frankvnk 0:c44f0314d6ec 128 return -1;
frankvnk 0:c44f0314d6ec 129 } while(0 == tSLInformation.usNumberOfFreeBuffers);
frankvnk 0:c44f0314d6ec 130
frankvnk 0:c44f0314d6ec 131 tSLInformation.usNumberOfFreeBuffers--;
frankvnk 0:c44f0314d6ec 132
frankvnk 0:c44f0314d6ec 133 return 0;
frankvnk 0:c44f0314d6ec 134 #else
frankvnk 0:c44f0314d6ec 135
frankvnk 0:c44f0314d6ec 136 // In case last transmission failed then we will return the last failure
frankvnk 0:c44f0314d6ec 137 // reason here.
frankvnk 0:c44f0314d6ec 138 // Note that the buffer will not be allocated in this case
frankvnk 0:c44f0314d6ec 139 if (tSLInformation.slTransmitDataError != 0)
frankvnk 0:c44f0314d6ec 140 {
frankvnk 0:c44f0314d6ec 141 errno = tSLInformation.slTransmitDataError;
frankvnk 0:c44f0314d6ec 142 tSLInformation.slTransmitDataError = 0;
frankvnk 0:c44f0314d6ec 143 return errno;
frankvnk 0:c44f0314d6ec 144 }
frankvnk 0:c44f0314d6ec 145 if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd))
frankvnk 0:c44f0314d6ec 146 return -1;
frankvnk 0:c44f0314d6ec 147
frankvnk 0:c44f0314d6ec 148 //If there are no available buffers, return -2. It is recommended to use
frankvnk 0:c44f0314d6ec 149 // select or receive to see if there is any buffer occupied with received data
frankvnk 0:c44f0314d6ec 150 // If so, call receive() to release the buffer.
frankvnk 0:c44f0314d6ec 151 if(0 == tSLInformation.usNumberOfFreeBuffers)
frankvnk 0:c44f0314d6ec 152 {
frankvnk 0:c44f0314d6ec 153 return -2;
frankvnk 0:c44f0314d6ec 154 }
frankvnk 0:c44f0314d6ec 155 else
frankvnk 0:c44f0314d6ec 156 {
frankvnk 0:c44f0314d6ec 157 tSLInformation.usNumberOfFreeBuffers--;
frankvnk 0:c44f0314d6ec 158 return 0;
frankvnk 0:c44f0314d6ec 159 }
frankvnk 0:c44f0314d6ec 160 #endif
frankvnk 0:c44f0314d6ec 161 }
frankvnk 0:c44f0314d6ec 162
frankvnk 0:c44f0314d6ec 163 //*****************************************************************************
frankvnk 0:c44f0314d6ec 164 //
frankvnk 0:c44f0314d6ec 165 //! socket
frankvnk 0:c44f0314d6ec 166 //!
frankvnk 0:c44f0314d6ec 167 //! @param domain selects the protocol family which will be used for
frankvnk 0:c44f0314d6ec 168 //! communication. On this version only AF_INET is supported
frankvnk 0:c44f0314d6ec 169 //! @param type specifies the communication semantics. On this version
frankvnk 0:c44f0314d6ec 170 //! only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW are supported
frankvnk 0:c44f0314d6ec 171 //! @param protocol specifies a particular protocol to be used with the
frankvnk 0:c44f0314d6ec 172 //! socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are
frankvnk 0:c44f0314d6ec 173 //! supported.
frankvnk 0:c44f0314d6ec 174 //!
frankvnk 0:c44f0314d6ec 175 //! @return On success, socket handle that is used for consequent socket
frankvnk 0:c44f0314d6ec 176 //! operations. On error, -1 is returned.
frankvnk 0:c44f0314d6ec 177 //!
frankvnk 0:c44f0314d6ec 178 //! @brief create an endpoint for communication
frankvnk 0:c44f0314d6ec 179 //! The socket function creates a socket that is bound to a specific
frankvnk 0:c44f0314d6ec 180 //! transport service provider. This function is called by the
frankvnk 0:c44f0314d6ec 181 //! application layer to obtain a socket handle.
frankvnk 0:c44f0314d6ec 182 //
frankvnk 0:c44f0314d6ec 183 //*****************************************************************************
frankvnk 0:c44f0314d6ec 184
frankvnk 0:c44f0314d6ec 185 int socket(long domain, long type, long protocol)
frankvnk 0:c44f0314d6ec 186 {
frankvnk 0:c44f0314d6ec 187 long ret;
frankvnk 0:c44f0314d6ec 188 unsigned char *ptr, *args;
frankvnk 0:c44f0314d6ec 189
frankvnk 0:c44f0314d6ec 190 ret = EFAIL;
frankvnk 0:c44f0314d6ec 191 ptr = tSLInformation.pucTxCommandBuffer;
frankvnk 0:c44f0314d6ec 192 args = (ptr + HEADERS_SIZE_CMD);
frankvnk 0:c44f0314d6ec 193
frankvnk 0:c44f0314d6ec 194 // Fill in HCI packet structure
frankvnk 0:c44f0314d6ec 195 args = UINT32_TO_STREAM(args, domain);
frankvnk 0:c44f0314d6ec 196 args = UINT32_TO_STREAM(args, type);
frankvnk 0:c44f0314d6ec 197 args = UINT32_TO_STREAM(args, protocol);
frankvnk 0:c44f0314d6ec 198
frankvnk 0:c44f0314d6ec 199 // Initiate a HCI command
frankvnk 0:c44f0314d6ec 200 hci_command_send(HCI_CMND_SOCKET, ptr, SOCKET_OPEN_PARAMS_LEN);
frankvnk 0:c44f0314d6ec 201
frankvnk 0:c44f0314d6ec 202 // Since we are in blocking state - wait for event complete
frankvnk 0:c44f0314d6ec 203 SimpleLinkWaitEvent(HCI_CMND_SOCKET, &ret);
frankvnk 0:c44f0314d6ec 204
frankvnk 0:c44f0314d6ec 205 // Process the event
frankvnk 0:c44f0314d6ec 206 errno = ret;
frankvnk 0:c44f0314d6ec 207
frankvnk 0:c44f0314d6ec 208 set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
frankvnk 0:c44f0314d6ec 209
frankvnk 0:c44f0314d6ec 210 return(ret);
frankvnk 0:c44f0314d6ec 211 }
frankvnk 0:c44f0314d6ec 212
frankvnk 0:c44f0314d6ec 213 //*****************************************************************************
frankvnk 0:c44f0314d6ec 214 //
frankvnk 0:c44f0314d6ec 215 //! closesocket
frankvnk 0:c44f0314d6ec 216 //!
frankvnk 0:c44f0314d6ec 217 //! @param sd socket handle.
frankvnk 0:c44f0314d6ec 218 //!
frankvnk 0:c44f0314d6ec 219 //! @return On success, zero is returned. On error, -1 is returned.
frankvnk 0:c44f0314d6ec 220 //!
frankvnk 0:c44f0314d6ec 221 //! @brief The socket function closes a created socket.
frankvnk 0:c44f0314d6ec 222 //
frankvnk 0:c44f0314d6ec 223 //*****************************************************************************
frankvnk 0:c44f0314d6ec 224
frankvnk 0:c44f0314d6ec 225 long closesocket(long sd)
frankvnk 0:c44f0314d6ec 226 {
frankvnk 0:c44f0314d6ec 227 long ret;
frankvnk 0:c44f0314d6ec 228 unsigned char *ptr, *args;
frankvnk 0:c44f0314d6ec 229
frankvnk 0:c44f0314d6ec 230 ret = EFAIL;
frankvnk 0:c44f0314d6ec 231 ptr = tSLInformation.pucTxCommandBuffer;
frankvnk 0:c44f0314d6ec 232 args = (ptr + HEADERS_SIZE_CMD);
frankvnk 0:c44f0314d6ec 233
frankvnk 0:c44f0314d6ec 234 // Fill in HCI packet structure
frankvnk 0:c44f0314d6ec 235 args = UINT32_TO_STREAM(args, sd);
frankvnk 0:c44f0314d6ec 236
frankvnk 0:c44f0314d6ec 237 // Initiate a HCI command
frankvnk 0:c44f0314d6ec 238 hci_command_send(HCI_CMND_CLOSE_SOCKET, ptr, SOCKET_CLOSE_PARAMS_LEN);
frankvnk 0:c44f0314d6ec 239
frankvnk 0:c44f0314d6ec 240 // Since we are in blocking state - wait for event complete
frankvnk 0:c44f0314d6ec 241 SimpleLinkWaitEvent(HCI_CMND_CLOSE_SOCKET, &ret);
frankvnk 0:c44f0314d6ec 242 errno = ret;
frankvnk 0:c44f0314d6ec 243
frankvnk 0:c44f0314d6ec 244 // since 'close' call may result in either OK (and then it closed) or error
frankvnk 0:c44f0314d6ec 245 // mark this socket as invalid
frankvnk 0:c44f0314d6ec 246 set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
frankvnk 0:c44f0314d6ec 247
frankvnk 0:c44f0314d6ec 248 return(ret);
frankvnk 0:c44f0314d6ec 249 }
frankvnk 0:c44f0314d6ec 250
frankvnk 0:c44f0314d6ec 251 //*****************************************************************************
frankvnk 0:c44f0314d6ec 252 //
frankvnk 0:c44f0314d6ec 253 //! accept
frankvnk 0:c44f0314d6ec 254 //!
frankvnk 0:c44f0314d6ec 255 //! @param[in] sd socket descriptor (handle)
frankvnk 0:c44f0314d6ec 256 //! @param[out] addr the argument addr is a pointer to a sockaddr structure
frankvnk 0:c44f0314d6ec 257 //! This structure is filled in with the address of the
frankvnk 0:c44f0314d6ec 258 //! peer socket, as known to the communications layer.
frankvnk 0:c44f0314d6ec 259 //! determined. The exact format of the address returned
frankvnk 0:c44f0314d6ec 260 //! addr is by the socket's address sockaddr.
frankvnk 0:c44f0314d6ec 261 //! On this version only AF_INET is supported.
frankvnk 0:c44f0314d6ec 262 //! This argument returns in network order.
frankvnk 0:c44f0314d6ec 263 //! @param[out] addrlen the addrlen argument is a value-result argument:
frankvnk 0:c44f0314d6ec 264 //! it should initially contain the size of the structure
frankvnk 0:c44f0314d6ec 265 //! pointed to by addr.
frankvnk 0:c44f0314d6ec 266 //!
frankvnk 0:c44f0314d6ec 267 //! @return For socket in blocking mode:
frankvnk 0:c44f0314d6ec 268 //! On success, socket handle. on failure negative
frankvnk 0:c44f0314d6ec 269 //! For socket in non-blocking mode:
frankvnk 0:c44f0314d6ec 270 //! - On connection establishment, socket handle
frankvnk 0:c44f0314d6ec 271 //! - On connection pending, SOC_IN_PROGRESS (-2)
frankvnk 0:c44f0314d6ec 272 //! - On failure, SOC_ERROR (-1)
frankvnk 0:c44f0314d6ec 273 //!
frankvnk 0:c44f0314d6ec 274 //! @brief accept a connection on a socket:
frankvnk 0:c44f0314d6ec 275 //! This function is used with connection-based socket types
frankvnk 0:c44f0314d6ec 276 //! (SOCK_STREAM). It extracts the first connection request on the
frankvnk 0:c44f0314d6ec 277 //! queue of pending connections, creates a new connected socket, and
frankvnk 0:c44f0314d6ec 278 //! returns a new file descriptor referring to that socket.
frankvnk 0:c44f0314d6ec 279 //! The newly created socket is not in the listening state.
frankvnk 0:c44f0314d6ec 280 //! The original socket sd is unaffected by this call.
frankvnk 0:c44f0314d6ec 281 //! The argument sd is a socket that has been created with socket(),
frankvnk 0:c44f0314d6ec 282 //! bound to a local address with bind(), and is listening for
frankvnk 0:c44f0314d6ec 283 //! connections after a listen(). The argument addr is a pointer
frankvnk 0:c44f0314d6ec 284 //! to a sockaddr structure. This structure is filled in with the
frankvnk 0:c44f0314d6ec 285 //! address of the peer socket, as known to the communications layer.
frankvnk 0:c44f0314d6ec 286 //! The exact format of the address returned addr is determined by the
frankvnk 0:c44f0314d6ec 287 //! socket's address family. The addrlen argument is a value-result
frankvnk 0:c44f0314d6ec 288 //! argument: it should initially contain the size of the structure
frankvnk 0:c44f0314d6ec 289 //! pointed to by addr, on return it will contain the actual
frankvnk 0:c44f0314d6ec 290 //! length (in bytes) of the address returned.
frankvnk 0:c44f0314d6ec 291 //!
frankvnk 0:c44f0314d6ec 292 //! @sa socket ; bind ; listen
frankvnk 0:c44f0314d6ec 293 //
frankvnk 0:c44f0314d6ec 294 //*****************************************************************************
frankvnk 0:c44f0314d6ec 295
frankvnk 0:c44f0314d6ec 296 long accept(long sd, sockaddr *addr, socklen_t *addrlen)
frankvnk 0:c44f0314d6ec 297 {
frankvnk 0:c44f0314d6ec 298 long ret;
frankvnk 0:c44f0314d6ec 299 unsigned char *ptr, *args;
frankvnk 0:c44f0314d6ec 300 tBsdReturnParams tAcceptReturnArguments;
frankvnk 0:c44f0314d6ec 301
frankvnk 0:c44f0314d6ec 302 ret = EFAIL;
frankvnk 0:c44f0314d6ec 303 ptr = tSLInformation.pucTxCommandBuffer;
frankvnk 0:c44f0314d6ec 304 args = (ptr + HEADERS_SIZE_CMD);
frankvnk 0:c44f0314d6ec 305
frankvnk 0:c44f0314d6ec 306 // Fill in temporary command buffer
frankvnk 0:c44f0314d6ec 307 args = UINT32_TO_STREAM(args, sd);
frankvnk 0:c44f0314d6ec 308
frankvnk 0:c44f0314d6ec 309 // Initiate a HCI command
frankvnk 0:c44f0314d6ec 310 hci_command_send(HCI_CMND_ACCEPT, ptr, SOCKET_ACCEPT_PARAMS_LEN);
frankvnk 0:c44f0314d6ec 311
frankvnk 0:c44f0314d6ec 312 // Since we are in blocking state - wait for event complete
frankvnk 0:c44f0314d6ec 313 SimpleLinkWaitEvent(HCI_CMND_ACCEPT, &tAcceptReturnArguments);
frankvnk 0:c44f0314d6ec 314
frankvnk 0:c44f0314d6ec 315
frankvnk 0:c44f0314d6ec 316 // need specify return parameters!!!
frankvnk 0:c44f0314d6ec 317 memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN);
frankvnk 0:c44f0314d6ec 318 *addrlen = ASIC_ADDR_LEN;
frankvnk 0:c44f0314d6ec 319 errno = tAcceptReturnArguments.iStatus;
frankvnk 0:c44f0314d6ec 320 ret = errno;
frankvnk 0:c44f0314d6ec 321
frankvnk 0:c44f0314d6ec 322 // if succeeded, iStatus = new socket descriptor. otherwise - error number
frankvnk 0:c44f0314d6ec 323 if(M_IS_VALID_SD(ret))
frankvnk 0:c44f0314d6ec 324 {
frankvnk 0:c44f0314d6ec 325 set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
frankvnk 0:c44f0314d6ec 326 }
frankvnk 0:c44f0314d6ec 327 else
frankvnk 0:c44f0314d6ec 328 {
frankvnk 0:c44f0314d6ec 329 set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
frankvnk 0:c44f0314d6ec 330 }
frankvnk 0:c44f0314d6ec 331
frankvnk 0:c44f0314d6ec 332 return(ret);
frankvnk 0:c44f0314d6ec 333 }
frankvnk 0:c44f0314d6ec 334
frankvnk 0:c44f0314d6ec 335 //*****************************************************************************
frankvnk 0:c44f0314d6ec 336 //
frankvnk 0:c44f0314d6ec 337 //! bind
frankvnk 0:c44f0314d6ec 338 //!
frankvnk 0:c44f0314d6ec 339 //! @param[in] sd socket descriptor (handle)
frankvnk 0:c44f0314d6ec 340 //! @param[out] addr specifies the destination address. On this version
frankvnk 0:c44f0314d6ec 341 //! only AF_INET is supported.
frankvnk 0:c44f0314d6ec 342 //! @param[out] addrlen contains the size of the structure pointed to by addr.
frankvnk 0:c44f0314d6ec 343 //!
frankvnk 0:c44f0314d6ec 344 //! @return On success, zero is returned. On error, -1 is returned.
frankvnk 0:c44f0314d6ec 345 //!
frankvnk 0:c44f0314d6ec 346 //! @brief assign a name to a socket
frankvnk 0:c44f0314d6ec 347 //! This function gives the socket the local address addr.
frankvnk 0:c44f0314d6ec 348 //! addr is addrlen bytes long. Traditionally, this is called when a
frankvnk 0:c44f0314d6ec 349 //! socket is created with socket, it exists in a name space (address
frankvnk 0:c44f0314d6ec 350 //! family) but has no name assigned.
frankvnk 0:c44f0314d6ec 351 //! It is necessary to assign a local address before a SOCK_STREAM
frankvnk 0:c44f0314d6ec 352 //! socket may receive connections.
frankvnk 0:c44f0314d6ec 353 //!
frankvnk 0:c44f0314d6ec 354 //! @sa socket ; accept ; listen
frankvnk 0:c44f0314d6ec 355 //
frankvnk 0:c44f0314d6ec 356 //*****************************************************************************
frankvnk 0:c44f0314d6ec 357
frankvnk 0:c44f0314d6ec 358 long bind(long sd, const sockaddr *addr, long addrlen)
frankvnk 0:c44f0314d6ec 359 {
frankvnk 0:c44f0314d6ec 360 long ret;
frankvnk 0:c44f0314d6ec 361 unsigned char *ptr, *args;
frankvnk 0:c44f0314d6ec 362
frankvnk 0:c44f0314d6ec 363 ret = EFAIL;
frankvnk 0:c44f0314d6ec 364 ptr = tSLInformation.pucTxCommandBuffer;
frankvnk 0:c44f0314d6ec 365 args = (ptr + HEADERS_SIZE_CMD);
frankvnk 0:c44f0314d6ec 366
frankvnk 0:c44f0314d6ec 367 addrlen = ASIC_ADDR_LEN;
frankvnk 0:c44f0314d6ec 368
frankvnk 0:c44f0314d6ec 369 // Fill in temporary command buffer
frankvnk 0:c44f0314d6ec 370 args = UINT32_TO_STREAM(args, sd);
frankvnk 0:c44f0314d6ec 371 args = UINT32_TO_STREAM(args, 0x00000008);
frankvnk 0:c44f0314d6ec 372 args = UINT32_TO_STREAM(args, addrlen);
frankvnk 0:c44f0314d6ec 373 ARRAY_TO_STREAM(args, ((unsigned char *)addr), addrlen);
frankvnk 0:c44f0314d6ec 374
frankvnk 0:c44f0314d6ec 375 // Initiate a HCI command
frankvnk 0:c44f0314d6ec 376 hci_command_send(HCI_CMND_BIND, ptr, SOCKET_BIND_PARAMS_LEN);
frankvnk 0:c44f0314d6ec 377
frankvnk 0:c44f0314d6ec 378 // Since we are in blocking state - wait for event complete
frankvnk 0:c44f0314d6ec 379 SimpleLinkWaitEvent(HCI_CMND_BIND, &ret);
frankvnk 0:c44f0314d6ec 380
frankvnk 0:c44f0314d6ec 381 errno = ret;
frankvnk 0:c44f0314d6ec 382
frankvnk 0:c44f0314d6ec 383 return(ret);
frankvnk 0:c44f0314d6ec 384 }
frankvnk 0:c44f0314d6ec 385
frankvnk 0:c44f0314d6ec 386 //*****************************************************************************
frankvnk 0:c44f0314d6ec 387 //
frankvnk 0:c44f0314d6ec 388 //! listen
frankvnk 0:c44f0314d6ec 389 //!
frankvnk 0:c44f0314d6ec 390 //! @param[in] sd socket descriptor (handle)
frankvnk 0:c44f0314d6ec 391 //! @param[in] backlog specifies the listen queue depth. On this version
frankvnk 0:c44f0314d6ec 392 //! backlog is not supported.
frankvnk 0:c44f0314d6ec 393 //! @return On success, zero is returned. On error, -1 is returned.
frankvnk 0:c44f0314d6ec 394 //!
frankvnk 0:c44f0314d6ec 395 //! @brief listen for connections on a socket
frankvnk 0:c44f0314d6ec 396 //! The willingness to accept incoming connections and a queue
frankvnk 0:c44f0314d6ec 397 //! limit for incoming connections are specified with listen(),
frankvnk 0:c44f0314d6ec 398 //! and then the connections are accepted with accept.
frankvnk 0:c44f0314d6ec 399 //! The listen() call applies only to sockets of type SOCK_STREAM
frankvnk 0:c44f0314d6ec 400 //! The backlog parameter defines the maximum length the queue of
frankvnk 0:c44f0314d6ec 401 //! pending connections may grow to.
frankvnk 0:c44f0314d6ec 402 //!
frankvnk 0:c44f0314d6ec 403 //! @sa socket ; accept ; bind
frankvnk 0:c44f0314d6ec 404 //!
frankvnk 0:c44f0314d6ec 405 //! @note On this version, backlog is not supported
frankvnk 0:c44f0314d6ec 406 //
frankvnk 0:c44f0314d6ec 407 //*****************************************************************************
frankvnk 0:c44f0314d6ec 408
frankvnk 0:c44f0314d6ec 409 long listen(long sd, long backlog)
frankvnk 0:c44f0314d6ec 410 {
frankvnk 0:c44f0314d6ec 411 long ret;
frankvnk 0:c44f0314d6ec 412 unsigned char *ptr, *args;
frankvnk 0:c44f0314d6ec 413
frankvnk 0:c44f0314d6ec 414 ret = EFAIL;
frankvnk 0:c44f0314d6ec 415 ptr = tSLInformation.pucTxCommandBuffer;
frankvnk 0:c44f0314d6ec 416 args = (ptr + HEADERS_SIZE_CMD);
frankvnk 0:c44f0314d6ec 417
frankvnk 0:c44f0314d6ec 418 // Fill in temporary command buffer
frankvnk 0:c44f0314d6ec 419 args = UINT32_TO_STREAM(args, sd);
frankvnk 0:c44f0314d6ec 420 args = UINT32_TO_STREAM(args, backlog);
frankvnk 0:c44f0314d6ec 421
frankvnk 0:c44f0314d6ec 422 // Initiate a HCI command
frankvnk 0:c44f0314d6ec 423 hci_command_send(HCI_CMND_LISTEN, ptr, SOCKET_LISTEN_PARAMS_LEN);
frankvnk 0:c44f0314d6ec 424
frankvnk 0:c44f0314d6ec 425 // Since we are in blocking state - wait for event complete
frankvnk 0:c44f0314d6ec 426 SimpleLinkWaitEvent(HCI_CMND_LISTEN, &ret);
frankvnk 0:c44f0314d6ec 427 errno = ret;
frankvnk 0:c44f0314d6ec 428
frankvnk 0:c44f0314d6ec 429 return(ret);
frankvnk 0:c44f0314d6ec 430 }
frankvnk 0:c44f0314d6ec 431
frankvnk 0:c44f0314d6ec 432 //*****************************************************************************
frankvnk 0:c44f0314d6ec 433 //
frankvnk 0:c44f0314d6ec 434 //! gethostbyname
frankvnk 0:c44f0314d6ec 435 //!
frankvnk 0:c44f0314d6ec 436 //! @param[in] hostname host name
frankvnk 0:c44f0314d6ec 437 //! @param[in] usNameLen name length
frankvnk 0:c44f0314d6ec 438 //! @param[out] out_ip_addr This parameter is filled in with host IP address.
frankvnk 0:c44f0314d6ec 439 //! In case that host name is not resolved,
frankvnk 0:c44f0314d6ec 440 //! out_ip_addr is zero.
frankvnk 0:c44f0314d6ec 441 //! @return On success, positive is returned. On error, negative is returned
frankvnk 0:c44f0314d6ec 442 //!
frankvnk 0:c44f0314d6ec 443 //! @brief Get host IP by name. Obtain the IP Address of machine on network,
frankvnk 0:c44f0314d6ec 444 //! by its name.
frankvnk 0:c44f0314d6ec 445 //!
frankvnk 0:c44f0314d6ec 446 //! @note On this version, only blocking mode is supported. Also note that
frankvnk 0:c44f0314d6ec 447 //! the function requires DNS server to be configured prior to its usage.
frankvnk 0:c44f0314d6ec 448 //
frankvnk 0:c44f0314d6ec 449 //*****************************************************************************
frankvnk 0:c44f0314d6ec 450 #ifndef CC3000_TINY_DRIVER
frankvnk 0:c44f0314d6ec 451 int gethostbyname(char * hostname, unsigned short usNameLen, unsigned long* out_ip_addr)
frankvnk 0:c44f0314d6ec 452 {
frankvnk 0:c44f0314d6ec 453 tBsdGethostbynameParams ret;
frankvnk 0:c44f0314d6ec 454 unsigned char *ptr, *args;
frankvnk 0:c44f0314d6ec 455
frankvnk 0:c44f0314d6ec 456 errno = EFAIL;
frankvnk 0:c44f0314d6ec 457
frankvnk 0:c44f0314d6ec 458 if (usNameLen > HOSTNAME_MAX_LENGTH)
frankvnk 0:c44f0314d6ec 459 {
frankvnk 0:c44f0314d6ec 460 return errno;
frankvnk 0:c44f0314d6ec 461 }
frankvnk 0:c44f0314d6ec 462
frankvnk 0:c44f0314d6ec 463 ptr = tSLInformation.pucTxCommandBuffer;
frankvnk 0:c44f0314d6ec 464 args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
frankvnk 0:c44f0314d6ec 465
frankvnk 0:c44f0314d6ec 466 // Fill in HCI packet structure
frankvnk 0:c44f0314d6ec 467 args = UINT32_TO_STREAM(args, 8);
frankvnk 0:c44f0314d6ec 468 args = UINT32_TO_STREAM(args, usNameLen);
frankvnk 0:c44f0314d6ec 469 ARRAY_TO_STREAM(args, hostname, usNameLen);
frankvnk 0:c44f0314d6ec 470
frankvnk 0:c44f0314d6ec 471 // Initiate a HCI command
frankvnk 0:c44f0314d6ec 472 hci_command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN + usNameLen - 1);
frankvnk 0:c44f0314d6ec 473
frankvnk 0:c44f0314d6ec 474 // Since we are in blocking state - wait for event complete
frankvnk 0:c44f0314d6ec 475 SimpleLinkWaitEvent(HCI_EVNT_BSD_GETHOSTBYNAME, &ret);
frankvnk 0:c44f0314d6ec 476
frankvnk 0:c44f0314d6ec 477 errno = ret.retVal;
frankvnk 0:c44f0314d6ec 478
frankvnk 0:c44f0314d6ec 479 (*((long*)out_ip_addr)) = ret.outputAddress;
frankvnk 0:c44f0314d6ec 480
frankvnk 0:c44f0314d6ec 481 return (errno);
frankvnk 0:c44f0314d6ec 482
frankvnk 0:c44f0314d6ec 483 }
frankvnk 0:c44f0314d6ec 484 #endif
frankvnk 0:c44f0314d6ec 485
frankvnk 0:c44f0314d6ec 486 //*****************************************************************************
frankvnk 0:c44f0314d6ec 487 //
frankvnk 0:c44f0314d6ec 488 //! connect
frankvnk 0:c44f0314d6ec 489 //!
frankvnk 0:c44f0314d6ec 490 //! @param[in] sd socket descriptor (handle)
frankvnk 0:c44f0314d6ec 491 //! @param[in] addr specifies the destination addr. On this version
frankvnk 0:c44f0314d6ec 492 //! only AF_INET is supported.
frankvnk 0:c44f0314d6ec 493 //! @param[out] addrlen contains the size of the structure pointed to by addr
frankvnk 0:c44f0314d6ec 494 //! @return On success, zero is returned. On error, -1 is returned
frankvnk 0:c44f0314d6ec 495 //!
frankvnk 0:c44f0314d6ec 496 //! @brief initiate a connection on a socket
frankvnk 0:c44f0314d6ec 497 //! Function connects the socket referred to by the socket descriptor
frankvnk 0:c44f0314d6ec 498 //! sd, to the address specified by addr. The addrlen argument
frankvnk 0:c44f0314d6ec 499 //! specifies the size of addr. The format of the address in addr is
frankvnk 0:c44f0314d6ec 500 //! determined by the address space of the socket. If it is of type
frankvnk 0:c44f0314d6ec 501 //! SOCK_DGRAM, this call specifies the peer with which the socket is
frankvnk 0:c44f0314d6ec 502 //! to be associated; this address is that to which datagrams are to be
frankvnk 0:c44f0314d6ec 503 //! sent, and the only address from which datagrams are to be received.
frankvnk 0:c44f0314d6ec 504 //! If the socket is of type SOCK_STREAM, this call attempts to make a
frankvnk 0:c44f0314d6ec 505 //! connection to another socket. The other socket is specified by
frankvnk 0:c44f0314d6ec 506 //! address, which is an address in the communications space of the
frankvnk 0:c44f0314d6ec 507 //! socket. Note that the function implements only blocking behavior
frankvnk 0:c44f0314d6ec 508 //! thus the caller will be waiting either for the connection
frankvnk 0:c44f0314d6ec 509 //! establishment or for the connection establishment failure.
frankvnk 0:c44f0314d6ec 510 //!
frankvnk 0:c44f0314d6ec 511 //! @sa socket
frankvnk 0:c44f0314d6ec 512 //
frankvnk 0:c44f0314d6ec 513 //*****************************************************************************
frankvnk 0:c44f0314d6ec 514
frankvnk 0:c44f0314d6ec 515 long connect(long sd, const sockaddr *addr, long addrlen)
frankvnk 0:c44f0314d6ec 516 {
frankvnk 0:c44f0314d6ec 517 long int ret;
frankvnk 0:c44f0314d6ec 518 unsigned char *ptr, *args;
frankvnk 0:c44f0314d6ec 519
frankvnk 0:c44f0314d6ec 520 ret = EFAIL;
frankvnk 0:c44f0314d6ec 521 ptr = tSLInformation.pucTxCommandBuffer;
frankvnk 0:c44f0314d6ec 522 args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
frankvnk 0:c44f0314d6ec 523 addrlen = 8;
frankvnk 0:c44f0314d6ec 524
frankvnk 0:c44f0314d6ec 525 // Fill in temporary command buffer
frankvnk 0:c44f0314d6ec 526 args = UINT32_TO_STREAM(args, sd);
frankvnk 0:c44f0314d6ec 527 args = UINT32_TO_STREAM(args, 0x00000008);
frankvnk 0:c44f0314d6ec 528 args = UINT32_TO_STREAM(args, addrlen);
frankvnk 0:c44f0314d6ec 529 ARRAY_TO_STREAM(args, ((unsigned char *)addr), addrlen);
frankvnk 0:c44f0314d6ec 530
frankvnk 0:c44f0314d6ec 531 // Initiate a HCI command
frankvnk 0:c44f0314d6ec 532 hci_command_send(HCI_CMND_CONNECT, ptr, SOCKET_CONNECT_PARAMS_LEN);
frankvnk 0:c44f0314d6ec 533
frankvnk 0:c44f0314d6ec 534 // Since we are in blocking state - wait for event complete
frankvnk 0:c44f0314d6ec 535 SimpleLinkWaitEvent(HCI_CMND_CONNECT, &ret);
frankvnk 0:c44f0314d6ec 536
frankvnk 0:c44f0314d6ec 537 errno = ret;
frankvnk 0:c44f0314d6ec 538
frankvnk 0:c44f0314d6ec 539 return((long)ret);
frankvnk 0:c44f0314d6ec 540 }
frankvnk 0:c44f0314d6ec 541
frankvnk 0:c44f0314d6ec 542
frankvnk 0:c44f0314d6ec 543 //*****************************************************************************
frankvnk 0:c44f0314d6ec 544 //
frankvnk 0:c44f0314d6ec 545 //! select
frankvnk 0:c44f0314d6ec 546 //!
frankvnk 0:c44f0314d6ec 547 //! @param[in] nfds the highest-numbered file descriptor in any of the
frankvnk 0:c44f0314d6ec 548 //! three sets, plus 1.
frankvnk 0:c44f0314d6ec 549 //! @param[out] writesds socket descriptors list for write monitoring
frankvnk 0:c44f0314d6ec 550 //! @param[out] readsds socket descriptors list for read monitoring
frankvnk 0:c44f0314d6ec 551 //! @param[out] exceptsds socket descriptors list for exception monitoring
frankvnk 0:c44f0314d6ec 552 //! @param[in] timeout is an upper bound on the amount of time elapsed
frankvnk 0:c44f0314d6ec 553 //! before select() returns. Null means infinity
frankvnk 0:c44f0314d6ec 554 //! timeout. The minimum timeout is 5 milliseconds,
frankvnk 0:c44f0314d6ec 555 //! less than 5 milliseconds will be set
frankvnk 0:c44f0314d6ec 556 //! automatically to 5 milliseconds.
frankvnk 0:c44f0314d6ec 557 //! @return On success, select() returns the number of file descriptors
frankvnk 0:c44f0314d6ec 558 //! contained in the three returned descriptor sets (that is, the
frankvnk 0:c44f0314d6ec 559 //! total number of bits that are set in readfds, writefds,
frankvnk 0:c44f0314d6ec 560 //! exceptfds) which may be zero if the timeout expires before
frankvnk 0:c44f0314d6ec 561 //! anything interesting happens.
frankvnk 0:c44f0314d6ec 562 //! On error, -1 is returned.
frankvnk 0:c44f0314d6ec 563 //! *readsds - return the sockets on which Read request will
frankvnk 0:c44f0314d6ec 564 //! return without delay with valid data.
frankvnk 0:c44f0314d6ec 565 //! *writesds - return the sockets on which Write request
frankvnk 0:c44f0314d6ec 566 //! will return without delay.
frankvnk 0:c44f0314d6ec 567 //! *exceptsds - return the sockets which closed recently.
frankvnk 0:c44f0314d6ec 568 //!
frankvnk 0:c44f0314d6ec 569 //! @brief Monitor socket activity
frankvnk 0:c44f0314d6ec 570 //! Select allow a program to monitor multiple file descriptors,
frankvnk 0:c44f0314d6ec 571 //! waiting until one or more of the file descriptors become
frankvnk 0:c44f0314d6ec 572 //! "ready" for some class of I/O operation
frankvnk 0:c44f0314d6ec 573 //!
frankvnk 0:c44f0314d6ec 574 //! @Note If the timeout value set to less than 5ms it will automatically set
frankvnk 0:c44f0314d6ec 575 //! to 5ms to prevent overload of the system
frankvnk 0:c44f0314d6ec 576 //!
frankvnk 0:c44f0314d6ec 577 //! @sa socket
frankvnk 0:c44f0314d6ec 578 //
frankvnk 0:c44f0314d6ec 579 //*****************************************************************************
frankvnk 0:c44f0314d6ec 580
frankvnk 0:c44f0314d6ec 581 int select(long nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, struct timeval *timeout)
frankvnk 0:c44f0314d6ec 582 {
frankvnk 0:c44f0314d6ec 583 unsigned char *ptr, *args;
frankvnk 0:c44f0314d6ec 584 tBsdSelectRecvParams tParams;
frankvnk 0:c44f0314d6ec 585 unsigned long is_blocking;
frankvnk 0:c44f0314d6ec 586
frankvnk 0:c44f0314d6ec 587 if( timeout == NULL)
frankvnk 0:c44f0314d6ec 588 {
frankvnk 0:c44f0314d6ec 589 is_blocking = 1; /* blocking , infinity timeout */
frankvnk 0:c44f0314d6ec 590 }
frankvnk 0:c44f0314d6ec 591 else
frankvnk 0:c44f0314d6ec 592 {
frankvnk 0:c44f0314d6ec 593 is_blocking = 0; /* no blocking, timeout */
frankvnk 0:c44f0314d6ec 594 }
frankvnk 0:c44f0314d6ec 595
frankvnk 0:c44f0314d6ec 596 // Fill in HCI packet structure
frankvnk 0:c44f0314d6ec 597 ptr = tSLInformation.pucTxCommandBuffer;
frankvnk 0:c44f0314d6ec 598 args = (ptr + HEADERS_SIZE_CMD);
frankvnk 0:c44f0314d6ec 599
frankvnk 0:c44f0314d6ec 600 // Fill in temporary command buffer
frankvnk 0:c44f0314d6ec 601 args = UINT32_TO_STREAM(args, nfds);
frankvnk 0:c44f0314d6ec 602 args = UINT32_TO_STREAM(args, 0x00000014);
frankvnk 0:c44f0314d6ec 603 args = UINT32_TO_STREAM(args, 0x00000014);
frankvnk 0:c44f0314d6ec 604 args = UINT32_TO_STREAM(args, 0x00000014);
frankvnk 0:c44f0314d6ec 605 args = UINT32_TO_STREAM(args, 0x00000014);
frankvnk 0:c44f0314d6ec 606 args = UINT32_TO_STREAM(args, is_blocking);
frankvnk 0:c44f0314d6ec 607 args = UINT32_TO_STREAM(args, ((readsds) ? *(unsigned long*)readsds : 0));
frankvnk 0:c44f0314d6ec 608 args = UINT32_TO_STREAM(args, ((writesds) ? *(unsigned long*)writesds : 0));
frankvnk 0:c44f0314d6ec 609 args = UINT32_TO_STREAM(args, ((exceptsds) ? *(unsigned long*)exceptsds : 0));
frankvnk 0:c44f0314d6ec 610
frankvnk 0:c44f0314d6ec 611 if (timeout)
frankvnk 0:c44f0314d6ec 612 {
frankvnk 0:c44f0314d6ec 613 if ( 0 == timeout->tv_sec && timeout->tv_usec < SELECT_TIMEOUT_MIN_MICRO_SECONDS)
frankvnk 0:c44f0314d6ec 614 {
frankvnk 0:c44f0314d6ec 615 timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS;
frankvnk 0:c44f0314d6ec 616 }
frankvnk 0:c44f0314d6ec 617 args = UINT32_TO_STREAM(args, timeout->tv_sec);
frankvnk 0:c44f0314d6ec 618 args = UINT32_TO_STREAM(args, timeout->tv_usec);
frankvnk 0:c44f0314d6ec 619 }
frankvnk 0:c44f0314d6ec 620
frankvnk 0:c44f0314d6ec 621 // Initiate a HCI command
frankvnk 0:c44f0314d6ec 622 hci_command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN);
frankvnk 0:c44f0314d6ec 623
frankvnk 0:c44f0314d6ec 624 // Since we are in blocking state - wait for event complete
frankvnk 0:c44f0314d6ec 625 SimpleLinkWaitEvent(HCI_EVNT_SELECT, &tParams);
frankvnk 0:c44f0314d6ec 626
frankvnk 0:c44f0314d6ec 627 // Update actually read FD
frankvnk 0:c44f0314d6ec 628 if (tParams.iStatus >= 0)
frankvnk 0:c44f0314d6ec 629 {
frankvnk 0:c44f0314d6ec 630 if (readsds)
frankvnk 0:c44f0314d6ec 631 {
frankvnk 0:c44f0314d6ec 632 memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd));
frankvnk 0:c44f0314d6ec 633 }
frankvnk 0:c44f0314d6ec 634
frankvnk 0:c44f0314d6ec 635 if (writesds)
frankvnk 0:c44f0314d6ec 636 {
frankvnk 0:c44f0314d6ec 637 memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd));
frankvnk 0:c44f0314d6ec 638 }
frankvnk 0:c44f0314d6ec 639
frankvnk 0:c44f0314d6ec 640 if (exceptsds)
frankvnk 0:c44f0314d6ec 641 {
frankvnk 0:c44f0314d6ec 642 memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd));
frankvnk 0:c44f0314d6ec 643 }
frankvnk 0:c44f0314d6ec 644
frankvnk 0:c44f0314d6ec 645 return(tParams.iStatus);
frankvnk 0:c44f0314d6ec 646
frankvnk 0:c44f0314d6ec 647 }
frankvnk 0:c44f0314d6ec 648 else
frankvnk 0:c44f0314d6ec 649 {
frankvnk 0:c44f0314d6ec 650 errno = tParams.iStatus;
frankvnk 0:c44f0314d6ec 651 return(-1);
frankvnk 0:c44f0314d6ec 652 }
frankvnk 0:c44f0314d6ec 653 }
frankvnk 0:c44f0314d6ec 654
frankvnk 0:c44f0314d6ec 655 //*****************************************************************************
frankvnk 0:c44f0314d6ec 656 //
frankvnk 0:c44f0314d6ec 657 //! setsockopt
frankvnk 0:c44f0314d6ec 658 //!
frankvnk 0:c44f0314d6ec 659 //! @param[in] sd socket handle
frankvnk 0:c44f0314d6ec 660 //! @param[in] level defines the protocol level for this option
frankvnk 0:c44f0314d6ec 661 //! @param[in] optname defines the option name to Interrogate
frankvnk 0:c44f0314d6ec 662 //! @param[in] optval specifies a value for the option
frankvnk 0:c44f0314d6ec 663 //! @param[in] optlen specifies the length of the option value
frankvnk 0:c44f0314d6ec 664 //! @return On success, zero is returned. On error, -1 is returned
frankvnk 0:c44f0314d6ec 665 //!
frankvnk 0:c44f0314d6ec 666 //! @brief set socket options
frankvnk 0:c44f0314d6ec 667 //! This function manipulate the options associated with a socket.
frankvnk 0:c44f0314d6ec 668 //! Options may exist at multiple protocol levels; they are always
frankvnk 0:c44f0314d6ec 669 //! present at the uppermost socket level.
frankvnk 0:c44f0314d6ec 670 //! When manipulating socket options the level at which the option
frankvnk 0:c44f0314d6ec 671 //! resides and the name of the option must be specified.
frankvnk 0:c44f0314d6ec 672 //! To manipulate options at the socket level, level is specified as
frankvnk 0:c44f0314d6ec 673 //! SOL_SOCKET. To manipulate options at any other level the protocol
frankvnk 0:c44f0314d6ec 674 //! number of the appropriate protocol controlling the option is
frankvnk 0:c44f0314d6ec 675 //! supplied. For example, to indicate that an option is to be
frankvnk 0:c44f0314d6ec 676 //! interpreted by the TCP protocol, level should be set to the
frankvnk 0:c44f0314d6ec 677 //! protocol number of TCP;
frankvnk 0:c44f0314d6ec 678 //! The parameters optval and optlen are used to access optval -
frankvnk 0:c44f0314d6ec 679 //! use for setsockopt(). For getsockopt() they identify a buffer
frankvnk 0:c44f0314d6ec 680 //! in which the value for the requested option(s) are to
frankvnk 0:c44f0314d6ec 681 //! be returned. For getsockopt(), optlen is a value-result
frankvnk 0:c44f0314d6ec 682 //! parameter, initially containing the size of the buffer
frankvnk 0:c44f0314d6ec 683 //! pointed to by option_value, and modified on return to
frankvnk 0:c44f0314d6ec 684 //! indicate the actual size of the value returned. If no option
frankvnk 0:c44f0314d6ec 685 //! value is to be supplied or returned, option_value may be NULL.
frankvnk 0:c44f0314d6ec 686 //!
frankvnk 0:c44f0314d6ec 687 //! @Note On this version the following two socket options are enabled:
frankvnk 0:c44f0314d6ec 688 //! The only protocol level supported in this version
frankvnk 0:c44f0314d6ec 689 //! is SOL_SOCKET (level).
frankvnk 0:c44f0314d6ec 690 //! 1. SOCKOPT_RECV_TIMEOUT (optname)
frankvnk 0:c44f0314d6ec 691 //! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout
frankvnk 0:c44f0314d6ec 692 //! in milliseconds.
frankvnk 0:c44f0314d6ec 693 //! In that case optval should be pointer to unsigned long.
frankvnk 0:c44f0314d6ec 694 //! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on
frankvnk 0:c44f0314d6ec 695 //! or off.
frankvnk 0:c44f0314d6ec 696 //! In that case optval should be SOCK_ON or SOCK_OFF (optval).
frankvnk 0:c44f0314d6ec 697 //!
frankvnk 0:c44f0314d6ec 698 //! @sa getsockopt
frankvnk 0:c44f0314d6ec 699 //
frankvnk 0:c44f0314d6ec 700 //*****************************************************************************
frankvnk 0:c44f0314d6ec 701
frankvnk 0:c44f0314d6ec 702 #ifndef CC3000_TINY_DRIVER
frankvnk 0:c44f0314d6ec 703 int setsockopt(long sd, long level, long optname, const void *optval, socklen_t optlen)
frankvnk 0:c44f0314d6ec 704 {
frankvnk 0:c44f0314d6ec 705 int ret;
frankvnk 0:c44f0314d6ec 706 unsigned char *ptr, *args;
frankvnk 0:c44f0314d6ec 707
frankvnk 0:c44f0314d6ec 708 ptr = tSLInformation.pucTxCommandBuffer;
frankvnk 0:c44f0314d6ec 709 args = (ptr + HEADERS_SIZE_CMD);
frankvnk 0:c44f0314d6ec 710
frankvnk 0:c44f0314d6ec 711 // Fill in temporary command buffer
frankvnk 0:c44f0314d6ec 712 args = UINT32_TO_STREAM(args, sd);
frankvnk 0:c44f0314d6ec 713 args = UINT32_TO_STREAM(args, level);
frankvnk 0:c44f0314d6ec 714 args = UINT32_TO_STREAM(args, optname);
frankvnk 0:c44f0314d6ec 715 args = UINT32_TO_STREAM(args, 0x00000008);
frankvnk 0:c44f0314d6ec 716 args = UINT32_TO_STREAM(args, optlen);
frankvnk 0:c44f0314d6ec 717 ARRAY_TO_STREAM(args, ((unsigned char *)optval), optlen);
frankvnk 0:c44f0314d6ec 718
frankvnk 0:c44f0314d6ec 719 // Initiate a HCI command
frankvnk 0:c44f0314d6ec 720 hci_command_send(HCI_CMND_SETSOCKOPT, ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN + optlen);
frankvnk 0:c44f0314d6ec 721
frankvnk 0:c44f0314d6ec 722 // Since we are in blocking state - wait for event complete
frankvnk 0:c44f0314d6ec 723 SimpleLinkWaitEvent(HCI_CMND_SETSOCKOPT, &ret);
frankvnk 0:c44f0314d6ec 724
frankvnk 0:c44f0314d6ec 725 if (ret >= 0)
frankvnk 0:c44f0314d6ec 726 {
frankvnk 0:c44f0314d6ec 727 return (0);
frankvnk 0:c44f0314d6ec 728 }
frankvnk 0:c44f0314d6ec 729 else
frankvnk 0:c44f0314d6ec 730 {
frankvnk 0:c44f0314d6ec 731 errno = ret;
frankvnk 0:c44f0314d6ec 732 return (-1);
frankvnk 0:c44f0314d6ec 733 }
frankvnk 0:c44f0314d6ec 734 }
frankvnk 0:c44f0314d6ec 735 #endif
frankvnk 0:c44f0314d6ec 736
frankvnk 0:c44f0314d6ec 737 //*****************************************************************************
frankvnk 0:c44f0314d6ec 738 //
frankvnk 0:c44f0314d6ec 739 //! getsockopt
frankvnk 0:c44f0314d6ec 740 //!
frankvnk 0:c44f0314d6ec 741 //! @param[in] sd socket handle
frankvnk 0:c44f0314d6ec 742 //! @param[in] level defines the protocol level for this option
frankvnk 0:c44f0314d6ec 743 //! @param[in] optname defines the option name to Interrogate
frankvnk 0:c44f0314d6ec 744 //! @param[out] optval specifies a value for the option
frankvnk 0:c44f0314d6ec 745 //! @param[out] optlen specifies the length of the option value
frankvnk 0:c44f0314d6ec 746 //! @return On success, zero is returned. On error, -1 is returned
frankvnk 0:c44f0314d6ec 747 //!
frankvnk 0:c44f0314d6ec 748 //! @brief set socket options
frankvnk 0:c44f0314d6ec 749 //! This function manipulate the options associated with a socket.
frankvnk 0:c44f0314d6ec 750 //! Options may exist at multiple protocol levels; they are always
frankvnk 0:c44f0314d6ec 751 //! present at the uppermost socket level.
frankvnk 0:c44f0314d6ec 752 //! When manipulating socket options the level at which the option
frankvnk 0:c44f0314d6ec 753 //! resides and the name of the option must be specified.
frankvnk 0:c44f0314d6ec 754 //! To manipulate options at the socket level, level is specified as
frankvnk 0:c44f0314d6ec 755 //! SOL_SOCKET. To manipulate options at any other level the protocol
frankvnk 0:c44f0314d6ec 756 //! number of the appropriate protocol controlling the option is
frankvnk 0:c44f0314d6ec 757 //! supplied. For example, to indicate that an option is to be
frankvnk 0:c44f0314d6ec 758 //! interpreted by the TCP protocol, level should be set to the
frankvnk 0:c44f0314d6ec 759 //! protocol number of TCP;
frankvnk 0:c44f0314d6ec 760 //! The parameters optval and optlen are used to access optval -
frankvnk 0:c44f0314d6ec 761 //! use for setsockopt(). For getsockopt() they identify a buffer
frankvnk 0:c44f0314d6ec 762 //! in which the value for the requested option(s) are to
frankvnk 0:c44f0314d6ec 763 //! be returned. For getsockopt(), optlen is a value-result
frankvnk 0:c44f0314d6ec 764 //! parameter, initially containing the size of the buffer
frankvnk 0:c44f0314d6ec 765 //! pointed to by option_value, and modified on return to
frankvnk 0:c44f0314d6ec 766 //! indicate the actual size of the value returned. If no option
frankvnk 0:c44f0314d6ec 767 //! value is to be supplied or returned, option_value may be NULL.
frankvnk 0:c44f0314d6ec 768 //!
frankvnk 0:c44f0314d6ec 769 //! @Note On this version the following two socket options are enabled:
frankvnk 0:c44f0314d6ec 770 //! The only protocol level supported in this version
frankvnk 0:c44f0314d6ec 771 //! is SOL_SOCKET (level).
frankvnk 0:c44f0314d6ec 772 //! 1. SOCKOPT_RECV_TIMEOUT (optname)
frankvnk 0:c44f0314d6ec 773 //! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout
frankvnk 0:c44f0314d6ec 774 //! in milliseconds.
frankvnk 0:c44f0314d6ec 775 //! In that case optval should be pointer to unsigned long.
frankvnk 0:c44f0314d6ec 776 //! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on
frankvnk 0:c44f0314d6ec 777 //! or off.
frankvnk 0:c44f0314d6ec 778 //! In that case optval should be SOCK_ON or SOCK_OFF (optval).
frankvnk 0:c44f0314d6ec 779 //!
frankvnk 0:c44f0314d6ec 780 //! @sa setsockopt
frankvnk 0:c44f0314d6ec 781 //
frankvnk 0:c44f0314d6ec 782 //*****************************************************************************
frankvnk 0:c44f0314d6ec 783
frankvnk 0:c44f0314d6ec 784 int
frankvnk 0:c44f0314d6ec 785 getsockopt (long sd, long level, long optname, void *optval, socklen_t *optlen)
frankvnk 0:c44f0314d6ec 786 {
frankvnk 0:c44f0314d6ec 787 unsigned char *ptr, *args;
frankvnk 0:c44f0314d6ec 788 tBsdGetSockOptReturnParams tRetParams;
frankvnk 0:c44f0314d6ec 789
frankvnk 0:c44f0314d6ec 790 ptr = tSLInformation.pucTxCommandBuffer;
frankvnk 0:c44f0314d6ec 791 args = (ptr + HEADERS_SIZE_CMD);
frankvnk 0:c44f0314d6ec 792
frankvnk 0:c44f0314d6ec 793 // Fill in temporary command buffer
frankvnk 0:c44f0314d6ec 794 args = UINT32_TO_STREAM(args, sd);
frankvnk 0:c44f0314d6ec 795 args = UINT32_TO_STREAM(args, level);
frankvnk 0:c44f0314d6ec 796 args = UINT32_TO_STREAM(args, optname);
frankvnk 0:c44f0314d6ec 797
frankvnk 0:c44f0314d6ec 798 // Initiate a HCI command
frankvnk 0:c44f0314d6ec 799 hci_command_send(HCI_CMND_GETSOCKOPT, ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN);
frankvnk 0:c44f0314d6ec 800
frankvnk 0:c44f0314d6ec 801 // Since we are in blocking state - wait for event complete
frankvnk 0:c44f0314d6ec 802 SimpleLinkWaitEvent(HCI_CMND_GETSOCKOPT, &tRetParams);
frankvnk 0:c44f0314d6ec 803
frankvnk 0:c44f0314d6ec 804 if (((signed char)tRetParams.iStatus) >= 0)
frankvnk 0:c44f0314d6ec 805 {
frankvnk 0:c44f0314d6ec 806 *optlen = 4;
frankvnk 0:c44f0314d6ec 807 memcpy(optval, tRetParams.ucOptValue, 4);
frankvnk 0:c44f0314d6ec 808 return (0);
frankvnk 0:c44f0314d6ec 809 }
frankvnk 0:c44f0314d6ec 810 else
frankvnk 0:c44f0314d6ec 811 {
frankvnk 0:c44f0314d6ec 812 errno = tRetParams.iStatus;
frankvnk 0:c44f0314d6ec 813 return (-1);
frankvnk 0:c44f0314d6ec 814 }
frankvnk 0:c44f0314d6ec 815 }
frankvnk 0:c44f0314d6ec 816
frankvnk 0:c44f0314d6ec 817 //*****************************************************************************
frankvnk 0:c44f0314d6ec 818 //
frankvnk 0:c44f0314d6ec 819 //! simple_link_recv
frankvnk 0:c44f0314d6ec 820 //!
frankvnk 0:c44f0314d6ec 821 //! @param sd socket handle
frankvnk 0:c44f0314d6ec 822 //! @param buf read buffer
frankvnk 0:c44f0314d6ec 823 //! @param len buffer length
frankvnk 0:c44f0314d6ec 824 //! @param flags indicates blocking or non-blocking operation
frankvnk 0:c44f0314d6ec 825 //! @param from pointer to an address structure indicating source address
frankvnk 0:c44f0314d6ec 826 //! @param fromlen source address structure size
frankvnk 0:c44f0314d6ec 827 //!
frankvnk 0:c44f0314d6ec 828 //! @return Return the number of bytes received, or -1 if an error
frankvnk 0:c44f0314d6ec 829 //! occurred
frankvnk 0:c44f0314d6ec 830 //!
frankvnk 0:c44f0314d6ec 831 //! @brief Read data from socket
frankvnk 0:c44f0314d6ec 832 //! Return the length of the message on successful completion.
frankvnk 0:c44f0314d6ec 833 //! If a message is too long to fit in the supplied buffer,
frankvnk 0:c44f0314d6ec 834 //! excess bytes may be discarded depending on the type of
frankvnk 0:c44f0314d6ec 835 //! socket the message is received from
frankvnk 0:c44f0314d6ec 836 //
frankvnk 0:c44f0314d6ec 837 //*****************************************************************************
frankvnk 0:c44f0314d6ec 838 int simple_link_recv(long sd, void *buf, long len, long flags, sockaddr *from, socklen_t *fromlen, long opcode)
frankvnk 0:c44f0314d6ec 839 {
frankvnk 0:c44f0314d6ec 840 unsigned char *ptr, *args;
frankvnk 0:c44f0314d6ec 841 tBsdReadReturnParams tSocketReadEvent;
frankvnk 0:c44f0314d6ec 842
frankvnk 0:c44f0314d6ec 843 ptr = tSLInformation.pucTxCommandBuffer;
frankvnk 0:c44f0314d6ec 844 args = (ptr + HEADERS_SIZE_CMD);
frankvnk 0:c44f0314d6ec 845
frankvnk 0:c44f0314d6ec 846 // Fill in HCI packet structure
frankvnk 0:c44f0314d6ec 847 args = UINT32_TO_STREAM(args, sd);
frankvnk 0:c44f0314d6ec 848 args = UINT32_TO_STREAM(args, len);
frankvnk 0:c44f0314d6ec 849 args = UINT32_TO_STREAM(args, flags);
frankvnk 0:c44f0314d6ec 850
frankvnk 0:c44f0314d6ec 851 // Generate the read command, and wait for the
frankvnk 0:c44f0314d6ec 852 hci_command_send(opcode, ptr, SOCKET_RECV_FROM_PARAMS_LEN);
frankvnk 0:c44f0314d6ec 853
frankvnk 0:c44f0314d6ec 854 // Since we are in blocking state - wait for event complete
frankvnk 0:c44f0314d6ec 855 SimpleLinkWaitEvent(opcode, &tSocketReadEvent);
frankvnk 0:c44f0314d6ec 856
frankvnk 0:c44f0314d6ec 857 // In case the number of bytes is more then zero - read data
frankvnk 0:c44f0314d6ec 858 if (tSocketReadEvent.iNumberOfBytes > 0)
frankvnk 0:c44f0314d6ec 859 {
frankvnk 0:c44f0314d6ec 860 // Wait for the data in a synchronous way. Here we assume that the bug is
frankvnk 0:c44f0314d6ec 861 // big enough to store also parameters of receive from too....
frankvnk 0:c44f0314d6ec 862 SimpleLinkWaitData((unsigned char *)buf, (unsigned char *)from, (unsigned char *)fromlen);
frankvnk 0:c44f0314d6ec 863 }
frankvnk 0:c44f0314d6ec 864
frankvnk 0:c44f0314d6ec 865 errno = tSocketReadEvent.iNumberOfBytes;
frankvnk 0:c44f0314d6ec 866
frankvnk 0:c44f0314d6ec 867 return(tSocketReadEvent.iNumberOfBytes);
frankvnk 0:c44f0314d6ec 868 }
frankvnk 0:c44f0314d6ec 869
frankvnk 0:c44f0314d6ec 870 //*****************************************************************************
frankvnk 0:c44f0314d6ec 871 //
frankvnk 0:c44f0314d6ec 872 //! recv
frankvnk 0:c44f0314d6ec 873 //!
frankvnk 0:c44f0314d6ec 874 //! @param[in] sd socket handle
frankvnk 0:c44f0314d6ec 875 //! @param[out] buf Points to the buffer where the message should be stored
frankvnk 0:c44f0314d6ec 876 //! @param[in] len Specifies the length in bytes of the buffer pointed to
frankvnk 0:c44f0314d6ec 877 //! by the buffer argument.
frankvnk 0:c44f0314d6ec 878 //! @param[in] flags Specifies the type of message reception.
frankvnk 0:c44f0314d6ec 879 //! On this version, this parameter is not supported.
frankvnk 0:c44f0314d6ec 880 //!
frankvnk 0:c44f0314d6ec 881 //! @return Return the number of bytes received, or -1 if an error
frankvnk 0:c44f0314d6ec 882 //! occurred
frankvnk 0:c44f0314d6ec 883 //!
frankvnk 0:c44f0314d6ec 884 //! @brief function receives a message from a connection-mode socket
frankvnk 0:c44f0314d6ec 885 //!
frankvnk 0:c44f0314d6ec 886 //! @sa recvfrom
frankvnk 0:c44f0314d6ec 887 //!
frankvnk 0:c44f0314d6ec 888 //! @Note On this version, only blocking mode is supported.
frankvnk 0:c44f0314d6ec 889 //
frankvnk 0:c44f0314d6ec 890 //*****************************************************************************
frankvnk 0:c44f0314d6ec 891
frankvnk 0:c44f0314d6ec 892 int recv(long sd, void *buf, long len, long flags)
frankvnk 0:c44f0314d6ec 893 {
frankvnk 0:c44f0314d6ec 894 return(simple_link_recv(sd, buf, len, flags, NULL, NULL, HCI_CMND_RECV));
frankvnk 0:c44f0314d6ec 895 }
frankvnk 0:c44f0314d6ec 896
frankvnk 0:c44f0314d6ec 897 //*****************************************************************************
frankvnk 0:c44f0314d6ec 898 //
frankvnk 0:c44f0314d6ec 899 //! recvfrom
frankvnk 0:c44f0314d6ec 900 //!
frankvnk 0:c44f0314d6ec 901 //! @param[in] sd socket handle
frankvnk 0:c44f0314d6ec 902 //! @param[out] buf Points to the buffer where the message should be stored
frankvnk 0:c44f0314d6ec 903 //! @param[in] len Specifies the length in bytes of the buffer pointed to
frankvnk 0:c44f0314d6ec 904 //! by the buffer argument.
frankvnk 0:c44f0314d6ec 905 //! @param[in] flags Specifies the type of message reception.
frankvnk 0:c44f0314d6ec 906 //! On this version, this parameter is not supported.
frankvnk 0:c44f0314d6ec 907 //! @param[in] from pointer to an address structure indicating the source
frankvnk 0:c44f0314d6ec 908 //! address: sockaddr. On this version only AF_INET is
frankvnk 0:c44f0314d6ec 909 //! supported.
frankvnk 0:c44f0314d6ec 910 //! @param[in] fromlen source address tructure size
frankvnk 0:c44f0314d6ec 911 //!
frankvnk 0:c44f0314d6ec 912 //! @return Return the number of bytes received, or -1 if an error
frankvnk 0:c44f0314d6ec 913 //! occurred
frankvnk 0:c44f0314d6ec 914 //!
frankvnk 0:c44f0314d6ec 915 //! @brief read data from socket
frankvnk 0:c44f0314d6ec 916 //! function receives a message from a connection-mode or
frankvnk 0:c44f0314d6ec 917 //! connectionless-mode socket. Note that raw sockets are not
frankvnk 0:c44f0314d6ec 918 //! supported.
frankvnk 0:c44f0314d6ec 919 //!
frankvnk 0:c44f0314d6ec 920 //! @sa recv
frankvnk 0:c44f0314d6ec 921 //!
frankvnk 0:c44f0314d6ec 922 //! @Note On this version, only blocking mode is supported.
frankvnk 0:c44f0314d6ec 923 //
frankvnk 0:c44f0314d6ec 924 //*****************************************************************************
frankvnk 0:c44f0314d6ec 925 int recvfrom(long sd, void *buf, long len, long flags, sockaddr *from, socklen_t *fromlen)
frankvnk 0:c44f0314d6ec 926 {
frankvnk 0:c44f0314d6ec 927 return(simple_link_recv(sd, buf, len, flags, from, fromlen, HCI_CMND_RECVFROM));
frankvnk 0:c44f0314d6ec 928 }
frankvnk 0:c44f0314d6ec 929
frankvnk 0:c44f0314d6ec 930 //*****************************************************************************
frankvnk 0:c44f0314d6ec 931 //
frankvnk 0:c44f0314d6ec 932 //! simple_link_send
frankvnk 0:c44f0314d6ec 933 //!
frankvnk 0:c44f0314d6ec 934 //! @param sd socket handle
frankvnk 0:c44f0314d6ec 935 //! @param buf write buffer
frankvnk 0:c44f0314d6ec 936 //! @param len buffer length
frankvnk 0:c44f0314d6ec 937 //! @param flags On this version, this parameter is not supported
frankvnk 0:c44f0314d6ec 938 //! @param to pointer to an address structure indicating destination
frankvnk 0:c44f0314d6ec 939 //! address
frankvnk 0:c44f0314d6ec 940 //! @param tolen destination address structure size
frankvnk 0:c44f0314d6ec 941 //!
frankvnk 0:c44f0314d6ec 942 //! @return Return the number of bytes transmitted, or -1 if an error
frankvnk 0:c44f0314d6ec 943 //! occurred, or -2 in case there are no free buffers available
frankvnk 0:c44f0314d6ec 944 //! (only when SEND_NON_BLOCKING is enabled)
frankvnk 0:c44f0314d6ec 945 //!
frankvnk 0:c44f0314d6ec 946 //! @brief This function is used to transmit a message to another
frankvnk 0:c44f0314d6ec 947 //! socket
frankvnk 0:c44f0314d6ec 948 //
frankvnk 0:c44f0314d6ec 949 //*****************************************************************************
frankvnk 0:c44f0314d6ec 950 int simple_link_send(long sd, const void *buf, long len, long flags, const sockaddr *to, long tolen, long opcode)
frankvnk 0:c44f0314d6ec 951 {
frankvnk 0:c44f0314d6ec 952 unsigned char uArgSize = 0x00, addrlen = 0x00;
frankvnk 0:c44f0314d6ec 953 unsigned char *ptr, *pDataPtr = NULL, *args;
frankvnk 0:c44f0314d6ec 954 unsigned long addr_offset = 0x00;
frankvnk 0:c44f0314d6ec 955 int res;
frankvnk 1:bbcaf0b2f367 956 tBsdReadReturnParams tSocketSendEvent;
frankvnk 0:c44f0314d6ec 957
frankvnk 0:c44f0314d6ec 958 // Check the bsd_arguments
frankvnk 0:c44f0314d6ec 959 if (0 != (res = HostFlowControlConsumeBuff(sd)))
frankvnk 0:c44f0314d6ec 960 {
frankvnk 0:c44f0314d6ec 961 return res;
frankvnk 0:c44f0314d6ec 962 }
frankvnk 0:c44f0314d6ec 963
frankvnk 0:c44f0314d6ec 964 //Update the number of sent packets
frankvnk 0:c44f0314d6ec 965 tSLInformation.NumberOfSentPackets++;
frankvnk 0:c44f0314d6ec 966
frankvnk 0:c44f0314d6ec 967 // Allocate a buffer and construct a packet and send it over spi
frankvnk 0:c44f0314d6ec 968 ptr = tSLInformation.pucTxCommandBuffer;
frankvnk 0:c44f0314d6ec 969 args = (ptr + HEADERS_SIZE_DATA);
frankvnk 0:c44f0314d6ec 970
frankvnk 0:c44f0314d6ec 971 // Update the offset of data and parameters according to the command
frankvnk 0:c44f0314d6ec 972 switch(opcode)
frankvnk 0:c44f0314d6ec 973 {
frankvnk 0:c44f0314d6ec 974 case HCI_CMND_SENDTO:
frankvnk 0:c44f0314d6ec 975 {
frankvnk 0:c44f0314d6ec 976 addr_offset = len + sizeof(len) + sizeof(len);
frankvnk 0:c44f0314d6ec 977 addrlen = 8;
frankvnk 0:c44f0314d6ec 978 uArgSize = SOCKET_SENDTO_PARAMS_LEN;
frankvnk 0:c44f0314d6ec 979 pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN;
frankvnk 0:c44f0314d6ec 980 break;
frankvnk 0:c44f0314d6ec 981 }
frankvnk 0:c44f0314d6ec 982
frankvnk 0:c44f0314d6ec 983 case HCI_CMND_SEND:
frankvnk 0:c44f0314d6ec 984 {
frankvnk 0:c44f0314d6ec 985 tolen = 0;
frankvnk 0:c44f0314d6ec 986 to = NULL;
frankvnk 0:c44f0314d6ec 987 uArgSize = HCI_CMND_SEND_ARG_LENGTH;
frankvnk 0:c44f0314d6ec 988 pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH;
frankvnk 0:c44f0314d6ec 989 break;
frankvnk 0:c44f0314d6ec 990 }
frankvnk 0:c44f0314d6ec 991
frankvnk 0:c44f0314d6ec 992 default:
frankvnk 0:c44f0314d6ec 993 {
frankvnk 0:c44f0314d6ec 994 break;
frankvnk 0:c44f0314d6ec 995 }
frankvnk 0:c44f0314d6ec 996 }
frankvnk 0:c44f0314d6ec 997
frankvnk 0:c44f0314d6ec 998 // Fill in temporary command buffer
frankvnk 0:c44f0314d6ec 999 args = UINT32_TO_STREAM(args, sd);
frankvnk 0:c44f0314d6ec 1000 args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd));
frankvnk 0:c44f0314d6ec 1001 args = UINT32_TO_STREAM(args, len);
frankvnk 0:c44f0314d6ec 1002 args = UINT32_TO_STREAM(args, flags);
frankvnk 0:c44f0314d6ec 1003
frankvnk 0:c44f0314d6ec 1004 if (opcode == HCI_CMND_SENDTO)
frankvnk 0:c44f0314d6ec 1005 {
frankvnk 0:c44f0314d6ec 1006 args = UINT32_TO_STREAM(args, addr_offset);
frankvnk 0:c44f0314d6ec 1007 args = UINT32_TO_STREAM(args, addrlen);
frankvnk 0:c44f0314d6ec 1008 }
frankvnk 0:c44f0314d6ec 1009
frankvnk 0:c44f0314d6ec 1010 // Copy the data received from user into the TX Buffer
frankvnk 0:c44f0314d6ec 1011 ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)buf), len);
frankvnk 0:c44f0314d6ec 1012
frankvnk 0:c44f0314d6ec 1013 // In case we are using SendTo, copy the to parameters
frankvnk 0:c44f0314d6ec 1014 if (opcode == HCI_CMND_SENDTO)
frankvnk 0:c44f0314d6ec 1015 {
frankvnk 0:c44f0314d6ec 1016 ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)to), tolen);
frankvnk 0:c44f0314d6ec 1017 }
frankvnk 0:c44f0314d6ec 1018
frankvnk 0:c44f0314d6ec 1019 // Initiate a HCI command
frankvnk 0:c44f0314d6ec 1020 hci_data_send(opcode, ptr, uArgSize, len,(unsigned char*)to, tolen);
frankvnk 1:bbcaf0b2f367 1021 if (opcode == HCI_CMND_SENDTO)
frankvnk 1:bbcaf0b2f367 1022 SimpleLinkWaitEvent(HCI_EVNT_SENDTO, &tSocketSendEvent);
frankvnk 1:bbcaf0b2f367 1023 else
frankvnk 1:bbcaf0b2f367 1024 SimpleLinkWaitEvent(HCI_EVNT_SEND, &tSocketSendEvent);
frankvnk 0:c44f0314d6ec 1025
frankvnk 0:c44f0314d6ec 1026 return (len);
frankvnk 0:c44f0314d6ec 1027 }
frankvnk 0:c44f0314d6ec 1028
frankvnk 0:c44f0314d6ec 1029
frankvnk 0:c44f0314d6ec 1030 //*****************************************************************************
frankvnk 0:c44f0314d6ec 1031 //
frankvnk 0:c44f0314d6ec 1032 //! send
frankvnk 0:c44f0314d6ec 1033 //!
frankvnk 0:c44f0314d6ec 1034 //! @param sd socket handle
frankvnk 0:c44f0314d6ec 1035 //! @param buf Points to a buffer containing the message to be sent
frankvnk 0:c44f0314d6ec 1036 //! @param len message size in bytes
frankvnk 0:c44f0314d6ec 1037 //! @param flags On this version, this parameter is not supported
frankvnk 0:c44f0314d6ec 1038 //!
frankvnk 0:c44f0314d6ec 1039 //! @return Return the number of bytes transmitted, or -1 if an
frankvnk 0:c44f0314d6ec 1040 //! error occurred
frankvnk 0:c44f0314d6ec 1041 //!
frankvnk 0:c44f0314d6ec 1042 //! @brief Write data to TCP socket
frankvnk 0:c44f0314d6ec 1043 //! This function is used to transmit a message to another
frankvnk 0:c44f0314d6ec 1044 //! socket.
frankvnk 0:c44f0314d6ec 1045 //!
frankvnk 0:c44f0314d6ec 1046 //! @Note On this version, only blocking mode is supported.
frankvnk 0:c44f0314d6ec 1047 //!
frankvnk 0:c44f0314d6ec 1048 //! @sa sendto
frankvnk 0:c44f0314d6ec 1049 //
frankvnk 0:c44f0314d6ec 1050 //*****************************************************************************
frankvnk 0:c44f0314d6ec 1051
frankvnk 0:c44f0314d6ec 1052 int send(long sd, const void *buf, long len, long flags)
frankvnk 0:c44f0314d6ec 1053 {
frankvnk 0:c44f0314d6ec 1054 return(simple_link_send(sd, buf, len, flags, NULL, 0, HCI_CMND_SEND));
frankvnk 0:c44f0314d6ec 1055 }
frankvnk 0:c44f0314d6ec 1056
frankvnk 0:c44f0314d6ec 1057 //*****************************************************************************
frankvnk 0:c44f0314d6ec 1058 //
frankvnk 0:c44f0314d6ec 1059 //! sendto
frankvnk 0:c44f0314d6ec 1060 //!
frankvnk 0:c44f0314d6ec 1061 //! @param sd socket handle
frankvnk 0:c44f0314d6ec 1062 //! @param buf Points to a buffer containing the message to be sent
frankvnk 0:c44f0314d6ec 1063 //! @param len message size in bytes
frankvnk 0:c44f0314d6ec 1064 //! @param flags On this version, this parameter is not supported
frankvnk 0:c44f0314d6ec 1065 //! @param to pointer to an address structure indicating the destination
frankvnk 0:c44f0314d6ec 1066 //! address: sockaddr. On this version only AF_INET is
frankvnk 0:c44f0314d6ec 1067 //! supported.
frankvnk 0:c44f0314d6ec 1068 //! @param tolen destination address structure size
frankvnk 0:c44f0314d6ec 1069 //!
frankvnk 0:c44f0314d6ec 1070 //! @return Return the number of bytes transmitted, or -1 if an
frankvnk 0:c44f0314d6ec 1071 //! error occurred
frankvnk 0:c44f0314d6ec 1072 //!
frankvnk 0:c44f0314d6ec 1073 //! @brief Write data to TCP socket
frankvnk 0:c44f0314d6ec 1074 //! This function is used to transmit a message to another
frankvnk 0:c44f0314d6ec 1075 //! socket.
frankvnk 0:c44f0314d6ec 1076 //!
frankvnk 0:c44f0314d6ec 1077 //! @Note On this version, only blocking mode is supported.
frankvnk 0:c44f0314d6ec 1078 //!
frankvnk 0:c44f0314d6ec 1079 //! @sa send
frankvnk 0:c44f0314d6ec 1080 //
frankvnk 0:c44f0314d6ec 1081 //*****************************************************************************
frankvnk 0:c44f0314d6ec 1082
frankvnk 0:c44f0314d6ec 1083 int sendto(long sd, const void *buf, long len, long flags, const sockaddr *to, socklen_t tolen)
frankvnk 0:c44f0314d6ec 1084 {
frankvnk 0:c44f0314d6ec 1085 return(simple_link_send(sd, buf, len, flags, to, tolen, HCI_CMND_SENDTO));
frankvnk 0:c44f0314d6ec 1086 }
frankvnk 0:c44f0314d6ec 1087
frankvnk 0:c44f0314d6ec 1088 //*****************************************************************************
frankvnk 0:c44f0314d6ec 1089 //
frankvnk 0:c44f0314d6ec 1090 //! mdnsAdvertiser
frankvnk 0:c44f0314d6ec 1091 //!
frankvnk 0:c44f0314d6ec 1092 //! @param[in] mdnsEnabled flag to enable/disable the mDNS feature
frankvnk 0:c44f0314d6ec 1093 //! @param[in] deviceServiceName Service name as part of the published
frankvnk 0:c44f0314d6ec 1094 //! canonical domain name
frankvnk 0:c44f0314d6ec 1095 //! @param[in] deviceServiceNameLength Length of the service name
frankvnk 0:c44f0314d6ec 1096 //!
frankvnk 0:c44f0314d6ec 1097 //!
frankvnk 0:c44f0314d6ec 1098 //! @return On success, zero is returned, return SOC_ERROR if socket was not
frankvnk 0:c44f0314d6ec 1099 //! opened successfully, or if an error occurred.
frankvnk 0:c44f0314d6ec 1100 //!
frankvnk 0:c44f0314d6ec 1101 //! @brief Set CC3000 in mDNS advertiser mode in order to advertise itself.
frankvnk 0:c44f0314d6ec 1102 //
frankvnk 0:c44f0314d6ec 1103 //*****************************************************************************
frankvnk 0:c44f0314d6ec 1104
frankvnk 0:c44f0314d6ec 1105 int mdnsAdvertiser(unsigned short mdnsEnabled, char * deviceServiceName, unsigned short deviceServiceNameLength)
frankvnk 0:c44f0314d6ec 1106 {
frankvnk 0:c44f0314d6ec 1107 int ret;
frankvnk 0:c44f0314d6ec 1108 unsigned char *pTxBuffer, *pArgs;
frankvnk 0:c44f0314d6ec 1109
frankvnk 0:c44f0314d6ec 1110 if (deviceServiceNameLength > MDNS_DEVICE_SERVICE_MAX_LENGTH)
frankvnk 0:c44f0314d6ec 1111 {
frankvnk 0:c44f0314d6ec 1112 return EFAIL;
frankvnk 0:c44f0314d6ec 1113 }
frankvnk 0:c44f0314d6ec 1114
frankvnk 0:c44f0314d6ec 1115 pTxBuffer = tSLInformation.pucTxCommandBuffer;
frankvnk 0:c44f0314d6ec 1116 pArgs = (pTxBuffer + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
frankvnk 0:c44f0314d6ec 1117
frankvnk 0:c44f0314d6ec 1118 // Fill in HCI packet structure
frankvnk 0:c44f0314d6ec 1119 pArgs = UINT32_TO_STREAM(pArgs, mdnsEnabled);
frankvnk 0:c44f0314d6ec 1120 pArgs = UINT32_TO_STREAM(pArgs, 8);
frankvnk 0:c44f0314d6ec 1121 pArgs = UINT32_TO_STREAM(pArgs, deviceServiceNameLength);
frankvnk 0:c44f0314d6ec 1122 ARRAY_TO_STREAM(pArgs, deviceServiceName, deviceServiceNameLength);
frankvnk 0:c44f0314d6ec 1123
frankvnk 0:c44f0314d6ec 1124 // Initiate a HCI command
frankvnk 0:c44f0314d6ec 1125 hci_command_send(HCI_CMND_MDNS_ADVERTISE, pTxBuffer, SOCKET_MDNS_ADVERTISE_PARAMS_LEN + deviceServiceNameLength);
frankvnk 0:c44f0314d6ec 1126
frankvnk 0:c44f0314d6ec 1127 // Since we are in blocking state - wait for event complete
frankvnk 0:c44f0314d6ec 1128 SimpleLinkWaitEvent(HCI_EVNT_MDNS_ADVERTISE, &ret);
frankvnk 0:c44f0314d6ec 1129
frankvnk 0:c44f0314d6ec 1130 return ret;
frankvnk 0:c44f0314d6ec 1131
frankvnk 0:c44f0314d6ec 1132 }
frankvnk 0:c44f0314d6ec 1133
frankvnk 0:c44f0314d6ec 1134
frankvnk 0:c44f0314d6ec 1135