From 520885d4d0f94d730a73e12c88a0bad8f52acbff Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 16 Oct 2013 11:59:26 -0600 Subject: CC3000 driver changes from David Sidrane --- nuttx/drivers/mtd/sst25.c | 2 +- nuttx/drivers/wireless/cc3000/Kconfig | 52 +- nuttx/drivers/wireless/cc3000/Make.defs | 5 +- nuttx/drivers/wireless/cc3000/cc3000_common.c | 261 ++- nuttx/drivers/wireless/cc3000/evnt_handler.c | 1652 +++++++------- nuttx/drivers/wireless/cc3000/hci.c | 430 ++-- .../drivers/wireless/cc3000/host_driver_version.h | 16 +- nuttx/drivers/wireless/cc3000/netapp.c | 810 +++---- nuttx/drivers/wireless/cc3000/nvmem.c | 606 ++--- nuttx/drivers/wireless/cc3000/socket.c | 2241 ++++++++++--------- nuttx/drivers/wireless/cc3000/spi.c | 827 ++----- nuttx/drivers/wireless/cc3000/spi.h | 71 +- nuttx/drivers/wireless/cc3000/spi_version.h | 94 +- nuttx/drivers/wireless/cc3000/wlan.c | 2362 ++++++++++---------- 14 files changed, 4646 insertions(+), 4783 deletions(-) diff --git a/nuttx/drivers/mtd/sst25.c b/nuttx/drivers/mtd/sst25.c index c8c9cf0b3..aed37e984 100644 --- a/nuttx/drivers/mtd/sst25.c +++ b/nuttx/drivers/mtd/sst25.c @@ -362,7 +362,7 @@ static inline int sst25_readid(struct sst25_dev_s *priv) priv->nsectors = SST25_VF016_NSECTORS; return OK; - /* Not implemented yet */ + /* Support for this part is not implemented yet */ default: break; diff --git a/nuttx/drivers/wireless/cc3000/Kconfig b/nuttx/drivers/wireless/cc3000/Kconfig index 1e1145218..6e71a9af1 100644 --- a/nuttx/drivers/wireless/cc3000/Kconfig +++ b/nuttx/drivers/wireless/cc3000/Kconfig @@ -3,8 +3,54 @@ # see misc/tools/kconfig-language.txt. # -config WL_CC3000_DUMMY - bool "CC3000 Wireless Module Dummy Test" - default n +config WL_CC3000 + bool "CC3000 Wireless Module" + default n select SPI + ---help--- + Enable support for the TI CC3000 Wifi Module +if WL_CC3000 + +config CC3000_MULTIPLE + bool "Multiple CC3000 Devices" + default n + ---help--- + Can be defined to support multiple CC3000 devices on board. + +config CC3000_NPOLLWAITERS + int "Number poll waiters" + default 4 + depends on !DISABLE_POLL + ---help--- + Maximum number of threads that can be waiting on poll() + +config CC3000_SPIDEV + int "SPI bus number" + default 2 + ---help--- + Selects the SPI bus number identying that SPI interface that + connects the CC3000 to the MCU. + +config CC3000_DEVMINOR + int "Input device minor number" + default 0 + ---help--- + The CC3000 device will be registered as /dev/wirelessN where N is the + value provided by this setting. + +config CC3000_SPI_MODE + int "SPI mode" + default 0 + range 0 3 + ---help--- + Controls the SPI mode. The device should work in mode 0, but + sometimes you need to experiment. + +config CC3000_SPI_FREQUENCY + int "SPI frequency" + default 16000000 + ---help--- + Define to use a different SPI bus frequency. + +endif diff --git a/nuttx/drivers/wireless/cc3000/Make.defs b/nuttx/drivers/wireless/cc3000/Make.defs index 5ca9179ee..9eea9e018 100644 --- a/nuttx/drivers/wireless/cc3000/Make.defs +++ b/nuttx/drivers/wireless/cc3000/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # drivers/wireless/Make.defs # -# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. +# Copyright (C) 2013 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -37,7 +37,8 @@ ifeq ($(CONFIG_WL_CC3000),y) # Include cc3000 drivers -CSRCS += cc3000_common.c evnt_handler.c hci.c netapp.c nvmem.c security.c socket.c spi.c wlan.c +CSRCS += cc3000.c cc3000_common.c evnt_handler.c hci.c netapp.c nvmem.c +CSRCS += security.c socket.c spi.c wlan.c # Include wireless devices build support diff --git a/nuttx/drivers/wireless/cc3000/cc3000_common.c b/nuttx/drivers/wireless/cc3000/cc3000_common.c index 75a6ded4b..c4183f871 100644 --- a/nuttx/drivers/wireless/cc3000/cc3000_common.c +++ b/nuttx/drivers/wireless/cc3000/cc3000_common.c @@ -1,164 +1,153 @@ /***************************************************************************** -* -* cc3000_common.c.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -//***************************************************************************** -// -//! \addtogroup common_api -//! @{ -// -//***************************************************************************** -/****************************************************************************** + * cc3000_common.c.c - CC3000 Host Driver Implementation. + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. * - * Include files + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/****************************************************************************** + * Included files *****************************************************************************/ + +#include +#include + #include -#include +#include #include #include -//***************************************************************************** -// -//! __error__ -//! -//! @param pcFilename - file name, where error occurred -//! @param ulLine - line number, where error occurred -//! -//! @return none -//! -//! @brief stub function for ASSERT macro -// -//***************************************************************************** -void -__error__(char *pcFilename, unsigned long ulLine) -{ - //TODO full up function -} - - +/***************************************************************************** + * Name:__error__ + * + * Description: + * Stub function for ASSERT macro + * + * Input Parameters: + * pcFilename - file name, where error occurred + * ulLine - line number, where error occurred + * + * Returned Value: + * None + * + *****************************************************************************/ -//***************************************************************************** -// -//! UINT32_TO_STREAM_f -//! -//! @param p pointer to the new stream -//! @param u32 pointer to the 32 bit -//! -//! @return pointer to the new stream -//! -//! @brief This function is used for copying 32 bit to stream -//! while converting to little endian format. -// -//***************************************************************************** +/***************************************************************************** + * Name: UINT32_TO_STREAM_f + * + * Description: + * This function is used for copying 32 bit to stream while converting to + * little endian format. + * + * Input Parameters: + * p pointer to the new stream + * u32 pointer to the 32 bit + * + * Returned Value: + * Pointer to the new stream + * + *****************************************************************************/ uint8_t* UINT32_TO_STREAM_f (uint8_t *p, unsigned long u32) { - *(p)++ = (uint8_t)(u32); - *(p)++ = (uint8_t)((u32) >> 8); - *(p)++ = (uint8_t)((u32) >> 16); - *(p)++ = (uint8_t)((u32) >> 24); - return p; + *(p)++ = (uint8_t)(u32); + *(p)++ = (uint8_t)((u32) >> 8); + *(p)++ = (uint8_t)((u32) >> 16); + *(p)++ = (uint8_t)((u32) >> 24); + return p; } -//***************************************************************************** -// -//! UINT16_TO_STREAM_f -//! -//! @param p pointer to the new stream -//! @param u32 pointer to the 16 bit -//! -//! @return pointer to the new stream -//! -//! @brief This function is used for copying 16 bit to stream -//! while converting to little endian format. -// -//***************************************************************************** +/***************************************************************************** + * Name: UINT16_TO_STREAM_f + * + * Description: + * This function is used for copying 16 bit to stream while converting to + * little endian format. + * + * Input Parameters: + * p pointer to the new stream + * u16 pointer to the 16 bit + * + * Returned Value: + * Pointer to the new stream + * + *****************************************************************************/ uint8_t* UINT16_TO_STREAM_f (uint8_t *p, uint16_t u16) { - *(p)++ = (uint8_t)(u16); - *(p)++ = (uint8_t)((u16) >> 8); - return p; + *(p)++ = (uint8_t)(u16); + *(p)++ = (uint8_t)((u16) >> 8); + return p; } -//***************************************************************************** -// -//! STREAM_TO_UINT16_f -//! -//! @param p pointer to the stream -//! @param offset offset in the stream -//! -//! @return pointer to the new 16 bit -//! -//! @brief This function is used for copying received stream to -//! 16 bit in little endian format. -// -//***************************************************************************** +/***************************************************************************** + * Name: STREAM_TO_UINT16_f + * + * Description: + * This function is used for copying received stream to 16 bit in little + * endian format. + * + * Input Parameters: + * p pointer to the stream + * offset offset in the stream + * + * Returned Value: + * Pointer to the new 16 bit + * + *****************************************************************************/ uint16_t STREAM_TO_UINT16_f(char* p, uint16_t offset) { - return (uint16_t)((uint16_t)((uint16_t) - (*(p + offset + 1)) << 8) + (uint16_t)(*(p + offset))); + return (uint16_t)((uint16_t)((uint16_t) + (*(p + offset + 1)) << 8) + (uint16_t)(*(p + offset))); } -//***************************************************************************** -// -//! STREAM_TO_UINT32_f -//! -//! @param p pointer to the stream -//! @param offset offset in the stream -//! -//! @return pointer to the new 32 bit -//! -//! @brief This function is used for copying received stream to -//! 32 bit in little endian format. -// -//***************************************************************************** +/***************************************************************************** + * Name: STREAM_TO_UINT32_f + * + * Description: + * This function is used for copying received stream to 32 bit in little + * endian format. + * + * Input Parameters: + * p pointer to the stream + * offset offset in the stream + * + * Returned Value: + * Pointer to the new 32 bit + * + *****************************************************************************/ unsigned long STREAM_TO_UINT32_f(char* p, uint16_t offset) { - return (unsigned long)((unsigned long)((unsigned long) - (*(p + offset + 3)) << 24) + (unsigned long)((unsigned long) - (*(p + offset + 2)) << 16) + (unsigned long)((unsigned long) - (*(p + offset + 1)) << 8) + (unsigned long)(*(p + offset))); + return (unsigned long)((unsigned long)((unsigned long) + (*(p + offset + 3)) << 24) + (unsigned long)((unsigned long) + (*(p + offset + 2)) << 16) + (unsigned long)((unsigned long) + (*(p + offset + 1)) << 8) + (unsigned long)(*(p + offset))); } - - - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** diff --git a/nuttx/drivers/wireless/cc3000/evnt_handler.c b/nuttx/drivers/wireless/cc3000/evnt_handler.c index ffc3ae6cd..708c09f12 100644 --- a/nuttx/drivers/wireless/cc3000/evnt_handler.c +++ b/nuttx/drivers/wireless/cc3000/evnt_handler.c @@ -1,843 +1,933 @@ /***************************************************************************** -* -* evnt_handler.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -//***************************************************************************** -// -//! \addtogroup evnt_handler_api -//! @{ -// -//****************************************************************************** - -//****************************************************************************** -// INCLUDE FILES -//****************************************************************************** + * evnt_handler.c - CC3000 Host Driver Implementation. + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +/****************************************************************************** + * Included Files + ******************************************************************************/ #include +#include + #include #include #include #include -#include +#include #include -#include - +#include "spi.h" -//***************************************************************************** -// COMMON DEFINES -//***************************************************************************** +/***************************************************************************** + * Pre-processor Definitions + *****************************************************************************/ + +#define FLOW_CONTROL_EVENT_HANDLE_OFFSET (0) +#define FLOW_CONTROL_EVENT_BLOCK_MODE_OFFSET (1) +#define FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET (2) +#define FLOW_CONTROL_EVENT_SIZE (4) + +#define BSD_RSP_PARAMS_SOCKET_OFFSET (0) +#define BSD_RSP_PARAMS_STATUS_OFFSET (4) + +#define GET_HOST_BY_NAME_RETVAL_OFFSET (0) +#define GET_HOST_BY_NAME_ADDR_OFFSET (4) + +#define ACCEPT_SD_OFFSET (0) +#define ACCEPT_RETURN_STATUS_OFFSET (4) +#define ACCEPT_ADDRESS__OFFSET (8) + +#define SL_RECEIVE_SD_OFFSET (0) +#define SL_RECEIVE_NUM_BYTES_OFFSET (4) +#define SL_RECEIVE__FLAGS__OFFSET (8) + +#define SELECT_STATUS_OFFSET (0) +#define SELECT_READFD_OFFSET (4) +#define SELECT_WRITEFD_OFFSET (8) +#define SELECT_EXFD_OFFSET (12) + +#define NETAPP_IPCONFIG_IP_OFFSET (0) +#define NETAPP_IPCONFIG_SUBNET_OFFSET (4) +#define NETAPP_IPCONFIG_GW_OFFSET (8) +#define NETAPP_IPCONFIG_DHCP_OFFSET (12) +#define NETAPP_IPCONFIG_DNS_OFFSET (16) +#define NETAPP_IPCONFIG_MAC_OFFSET (20) +#define NETAPP_IPCONFIG_SSID_OFFSET (26) + +#define NETAPP_IPCONFIG_IP_LENGTH (4) +#define NETAPP_IPCONFIG_MAC_LENGTH (6) +#define NETAPP_IPCONFIG_SSID_LENGTH (32) + +#define NETAPP_PING_PACKETS_SENT_OFFSET (0) +#define NETAPP_PING_PACKETS_RCVD_OFFSET (4) +#define NETAPP_PING_MIN_RTT_OFFSET (8) +#define NETAPP_PING_MAX_RTT_OFFSET (12) +#define NETAPP_PING_AVG_RTT_OFFSET (16) + +#define GET_SCAN_RESULTS_TABlE_COUNT_OFFSET (0) +#define GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET (4) +#define GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET (8) +#define GET_SCAN_RESULTS_FRAME_TIME_OFFSET (10) +#define GET_SCAN_RESULTS_SSID_MAC_LENGTH (38) -#define FLOW_CONTROL_EVENT_HANDLE_OFFSET (0) -#define FLOW_CONTROL_EVENT_BLOCK_MODE_OFFSET (1) -#define FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET (2) -#define FLOW_CONTROL_EVENT_SIZE (4) +/***************************************************************************** + * Public Data + *****************************************************************************/ -#define BSD_RSP_PARAMS_SOCKET_OFFSET (0) -#define BSD_RSP_PARAMS_STATUS_OFFSET (4) +unsigned long socket_active_status = SOCKET_STATUS_INIT_VAL; -#define GET_HOST_BY_NAME_RETVAL_OFFSET (0) -#define GET_HOST_BY_NAME_ADDR_OFFSET (4) +/***************************************************************************** + * Private Function Prototypes + *****************************************************************************/ -#define ACCEPT_SD_OFFSET (0) -#define ACCEPT_RETURN_STATUS_OFFSET (4) -#define ACCEPT_ADDRESS__OFFSET (8) +static long hci_event_unsol_flowcontrol_handler(char *pEvent); +static void update_socket_active_status(char *resp_params); -#define SL_RECEIVE_SD_OFFSET (0) -#define SL_RECEIVE_NUM_BYTES_OFFSET (4) -#define SL_RECEIVE__FLAGS__OFFSET (8) +/***************************************************************************** + * Public Functions + *****************************************************************************/ +/***************************************************************************** + * Name: hci_unsol_handle_patch_request + * + * Description: + * Handle unsolicited event from type patch request + * + * Input Parameters: + * event_hdr event header + * + * Returned Value: + * None + * + *****************************************************************************/ +void hci_unsol_handle_patch_request(char *event_hdr) +{ + char *params = (char *)(event_hdr) + HCI_EVENT_HEADER_SIZE; + unsigned long ucLength = 0; + char *patch; + + switch (*params) + { + case HCI_EVENT_PATCHES_DRV_REQ: + + if (tSLInformation.sDriverPatches) + { + patch = tSLInformation.sDriverPatches(&ucLength); + + if (patch) + { + hci_patch_send(HCI_EVENT_PATCHES_DRV_REQ, + tSLInformation.pucTxCommandBuffer, + patch, ucLength); + return; + } + } + + /* Send 0 length Patches response event */ + + hci_patch_send(HCI_EVENT_PATCHES_DRV_REQ, + tSLInformation.pucTxCommandBuffer, 0, 0); + break; + + case HCI_EVENT_PATCHES_FW_REQ: + + if (tSLInformation.sFWPatches) + { + patch = tSLInformation.sFWPatches(&ucLength); + + /* Build and send a patch */ + + if (patch) + { + hci_patch_send(HCI_EVENT_PATCHES_FW_REQ, + tSLInformation.pucTxCommandBuffer, + patch, ucLength); + return; + } + } + + /* Send 0 length Patches response event */ + + hci_patch_send(HCI_EVENT_PATCHES_FW_REQ, + tSLInformation.pucTxCommandBuffer, 0, 0); + break; + + case HCI_EVENT_PATCHES_BOOTLOAD_REQ: + + if (tSLInformation.sBootLoaderPatches) + { + patch = tSLInformation.sBootLoaderPatches(&ucLength); + + if (patch) + { + hci_patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, + tSLInformation.pucTxCommandBuffer, + patch, ucLength); + return; + } + } + + /* Send 0 length Patches response event */ + + hci_patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, + tSLInformation.pucTxCommandBuffer, 0, 0); + break; + } +} -#define SELECT_STATUS_OFFSET (0) -#define SELECT_READFD_OFFSET (4) -#define SELECT_WRITEFD_OFFSET (8) -#define SELECT_EXFD_OFFSET (12) +/***************************************************************************** + * Name: hci_event_handler + * + * Description: + * Parse the incoming events packets and issues corresponding event handler + * from global array of handlers pointers + * + * Input Parameters: + * pRetParams incoming data buffer + * from from information (in case of data received) + * fromlen from information length (in case of data received) + * + * Returned Value: + * None + * + *****************************************************************************/ + +uint8_t *hci_event_handler(void *pRetParams, uint8_t *from, uint8_t *fromlen) +{ + uint8_t *pucReceivedData, ucArgsize; + uint16_t usLength; + uint8_t *pucReceivedParams; + uint16_t usReceivedEventOpcode = 0; + unsigned long retValue32; + uint8_t * RecvParams; + uint8_t *RetParams; + while (1) + { + if (tSLInformation.usEventOrDataReceived != 0) + { + pucReceivedData = (tSLInformation.pucReceivedData); -#define NETAPP_IPCONFIG_IP_OFFSET (0) -#define NETAPP_IPCONFIG_SUBNET_OFFSET (4) -#define NETAPP_IPCONFIG_GW_OFFSET (8) -#define NETAPP_IPCONFIG_DHCP_OFFSET (12) -#define NETAPP_IPCONFIG_DNS_OFFSET (16) -#define NETAPP_IPCONFIG_MAC_OFFSET (20) -#define NETAPP_IPCONFIG_SSID_OFFSET (26) + if (*pucReceivedData == HCI_TYPE_EVNT) + { + /* Event Received */ -#define NETAPP_IPCONFIG_IP_LENGTH (4) -#define NETAPP_IPCONFIG_MAC_LENGTH (6) -#define NETAPP_IPCONFIG_SSID_LENGTH (32) + STREAM_TO_UINT16((char *)pucReceivedData, + HCI_EVENT_OPCODE_OFFSET, + usReceivedEventOpcode); + pucReceivedParams = pucReceivedData + HCI_EVENT_HEADER_SIZE; + RecvParams = pucReceivedParams; + RetParams = (uint8_t *)pRetParams; -#define NETAPP_PING_PACKETS_SENT_OFFSET (0) -#define NETAPP_PING_PACKETS_RCVD_OFFSET (4) -#define NETAPP_PING_MIN_RTT_OFFSET (8) -#define NETAPP_PING_MAX_RTT_OFFSET (12) -#define NETAPP_PING_AVG_RTT_OFFSET (16) + /* In case unsolicited event received - here the handling finished */ -#define GET_SCAN_RESULTS_TABlE_COUNT_OFFSET (0) -#define GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET (4) -#define GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET (8) -#define GET_SCAN_RESULTS_FRAME_TIME_OFFSET (10) -#define GET_SCAN_RESULTS_SSID_MAC_LENGTH (38) + if (hci_unsol_event_handler((char *)pucReceivedData) == 0) + { + STREAM_TO_UINT8(pucReceivedData, HCI_DATA_LENGTH_OFFSET, usLength); + + switch(usReceivedEventOpcode) + { + case HCI_CMND_READ_BUFFER_SIZE: + { + STREAM_TO_UINT8((char *)pucReceivedParams, 0, + tSLInformation.usNumberOfFreeBuffers); + STREAM_TO_UINT16((char *)pucReceivedParams, 1, + tSLInformation.usSlBufferLength); + } + break; + + case HCI_CMND_WLAN_CONFIGURE_PATCH: + case HCI_NETAPP_DHCP: + case HCI_NETAPP_PING_SEND: + case HCI_NETAPP_PING_STOP: + case HCI_NETAPP_ARP_FLUSH: + case HCI_NETAPP_SET_DEBUG_LEVEL: + case HCI_NETAPP_SET_TIMERS: + case HCI_EVNT_NVMEM_READ: + case HCI_EVNT_NVMEM_CREATE_ENTRY: + case HCI_CMND_NVMEM_WRITE_PATCH: + case HCI_NETAPP_PING_REPORT: + case HCI_EVNT_MDNS_ADVERTISE: + + STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET, + *(uint8_t *)pRetParams); + break; + + case HCI_CMND_SETSOCKOPT: + case HCI_CMND_WLAN_CONNECT: + case HCI_CMND_WLAN_IOCTL_STATUSGET: + case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE: + case HCI_CMND_WLAN_IOCTL_DEL_PROFILE: + case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY: + case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM: + case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START: + case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP: + case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX: + case HCI_CMND_EVENT_MASK: + case HCI_EVNT_WLAN_DISCONNECT: + case HCI_EVNT_SOCKET: + case HCI_EVNT_BIND: + case HCI_CMND_LISTEN: + case HCI_EVNT_CLOSE_SOCKET: + case HCI_EVNT_CONNECT: + case HCI_EVNT_NVMEM_WRITE: + + STREAM_TO_UINT32((char *)pucReceivedParams, 0, + *(unsigned long *)pRetParams); + break; + + case HCI_EVNT_READ_SP_VERSION: + + STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET, + *(uint8_t *)pRetParams); + pRetParams = ((char *)pRetParams) + 1; + STREAM_TO_UINT32((char *)pucReceivedParams, 0, retValue32); + UINT32_TO_STREAM((uint8_t *)pRetParams, retValue32); + break; + + case HCI_EVNT_BSD_GETHOSTBYNAME: + + STREAM_TO_UINT32((char *)pucReceivedParams, + GET_HOST_BY_NAME_RETVAL_OFFSET, + *(unsigned long *)pRetParams); + pRetParams = ((char *)pRetParams) + 4; + STREAM_TO_UINT32((char *)pucReceivedParams, + GET_HOST_BY_NAME_ADDR_OFFSET, + *(unsigned long *)pRetParams); + break; + + case HCI_EVNT_ACCEPT: + { + STREAM_TO_UINT32((char *)pucReceivedParams, + ACCEPT_SD_OFFSET, + *(unsigned long *)pRetParams); + pRetParams = ((char *)pRetParams) + 4; + STREAM_TO_UINT32((char *)pucReceivedParams, + ACCEPT_RETURN_STATUS_OFFSET, + *(unsigned long *)pRetParams); + pRetParams = ((char *)pRetParams) + 4; + + /* This argument returns in network order */ + + memcpy((uint8_t *)pRetParams, + pucReceivedParams + ACCEPT_ADDRESS__OFFSET, + sizeof(sockaddr)); + } + break; + + case HCI_EVNT_RECV: + case HCI_EVNT_RECVFROM: + { + STREAM_TO_UINT32((char *)pucReceivedParams, + SL_RECEIVE_SD_OFFSET, + *(unsigned long *)pRetParams); + pRetParams = ((char *)pRetParams) + 4; + STREAM_TO_UINT32((char *)pucReceivedParams, + SL_RECEIVE_NUM_BYTES_OFFSET, + *(unsigned long *)pRetParams); + pRetParams = ((char *)pRetParams) + 4; + STREAM_TO_UINT32((char *)pucReceivedParams, + SL_RECEIVE__FLAGS__OFFSET, + *(unsigned long *)pRetParams); + + if (((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes == + ERROR_SOCKET_INACTIVE) + { + set_socket_active_status + (((tBsdReadReturnParams *)pRetParams)->iSocketDescriptor,SOCKET_STATUS_INACTIVE); + } + } + break; + + case HCI_EVNT_SEND: + case HCI_EVNT_SENDTO: + { + STREAM_TO_UINT32((char *)pucReceivedParams, + SL_RECEIVE_SD_OFFSET, + *(unsigned long *)pRetParams); + pRetParams = ((char *)pRetParams) + 4; + STREAM_TO_UINT32((char *)pucReceivedParams, + SL_RECEIVE_NUM_BYTES_OFFSET, + *(unsigned long *)pRetParams); + pRetParams = ((char *)pRetParams) + 4; + } + break; + + case HCI_EVNT_SELECT: + { + STREAM_TO_UINT32((char *)pucReceivedParams, + SELECT_STATUS_OFFSET, + *(unsigned long *)pRetParams); + pRetParams = ((char *)pRetParams) + 4; + STREAM_TO_UINT32((char *)pucReceivedParams, + SELECT_READFD_OFFSET, + *(unsigned long *)pRetParams); + pRetParams = ((char *)pRetParams) + 4; + STREAM_TO_UINT32((char *)pucReceivedParams, + SELECT_WRITEFD_OFFSET, + *(unsigned long *)pRetParams); + pRetParams = ((char *)pRetParams) + 4; + STREAM_TO_UINT32((char *)pucReceivedParams, + SELECT_EXFD_OFFSET, + *(unsigned long *)pRetParams); + } + break; + + case HCI_CMND_GETSOCKOPT: + + STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET, + ((tBsdGetSockOptReturnParams *)pRetParams)->iStatus); + + /* This argument returns in network order */ + + memcpy((uint8_t *)pRetParams, pucReceivedParams, 4); + break; + + case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS: + + STREAM_TO_UINT32((char *)pucReceivedParams, + GET_SCAN_RESULTS_TABlE_COUNT_OFFSET, + *(unsigned long *)pRetParams); + pRetParams = ((char *)pRetParams) + 4; + STREAM_TO_UINT32((char *)pucReceivedParams, + GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET, + *(unsigned long *)pRetParams); + pRetParams = ((char *)pRetParams) + 4; + + STREAM_TO_UINT16((char *)pucReceivedParams, + GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET, + *(unsigned long *)pRetParams); + pRetParams = ((char *)pRetParams) + 2; + STREAM_TO_UINT16((char *)pucReceivedParams, + GET_SCAN_RESULTS_FRAME_TIME_OFFSET, + *(unsigned long *)pRetParams); + pRetParams = ((char *)pRetParams) + 2; + memcpy((uint8_t *)pRetParams, + (char *)(pucReceivedParams + + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), + GET_SCAN_RESULTS_SSID_MAC_LENGTH); + break; + + case HCI_CMND_SIMPLE_LINK_START: + break; + + case HCI_NETAPP_IPCONFIG: + + /* Read IP address */ + + STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); + RecvParams += 4; + + /* Read subnet */ + + STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); + RecvParams += 4; + + /* Read default GW */ + + STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); + RecvParams += 4; + + /* Read DHCP server */ + + STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); + RecvParams += 4; + + /* Read DNS server */ + + STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); + RecvParams += 4; + + /* Read Mac address */ + + STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH); + RecvParams += 6; + + /* Read SSID */ + + STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH); + break; + + default: + PANIC(); + break; + } + } + if (usReceivedEventOpcode == tSLInformation.usRxEventOpcode) + { + tSLInformation.usRxEventOpcode = 0; + } + } + else + { + pucReceivedParams = pucReceivedData; + STREAM_TO_UINT8((char *)pucReceivedData, + HCI_PACKET_ARGSIZE_OFFSET, ucArgsize); + STREAM_TO_UINT16((char *)pucReceivedData, + HCI_PACKET_LENGTH_OFFSET, usLength); -//***************************************************************************** -// GLOBAL VARAIABLES -//***************************************************************************** + /* Data received: note that the only case where from and from length + * are not null is in recv from, so fill the args accordingly + */ -unsigned long socket_active_status = SOCKET_STATUS_INIT_VAL; + if (from) + { + STREAM_TO_UINT32((char *)(pucReceivedData + HCI_DATA_HEADER_SIZE), + BSD_RECV_FROM_FROMLEN_OFFSET, + *(unsigned long *)fromlen); + memcpy(from, + (pucReceivedData + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET), + *fromlen); + } + memcpy(pRetParams, pucReceivedParams + HCI_DATA_HEADER_SIZE + ucArgsize, + usLength - ucArgsize); -//***************************************************************************** -// Prototypes for the static functions -//***************************************************************************** + tSLInformation.usRxDataPending = 0; + } -static long hci_event_unsol_flowcontrol_handler(char *pEvent); + tSLInformation.usEventOrDataReceived = 0; -static void update_socket_active_status(char *resp_params); + SpiResumeSpi(); + /* Since we are going to TX - we need to handle this event after the + * ResumeSPi since we need interrupts + */ -//***************************************************************************** -// -//! hci_unsol_handle_patch_request -//! -//! @param event_hdr event header -//! -//! @return none -//! -//! @brief Handle unsolicited event from type patch request -// -//***************************************************************************** -void hci_unsol_handle_patch_request(char *event_hdr) -{ - char *params = (char *)(event_hdr) + HCI_EVENT_HEADER_SIZE; - unsigned long ucLength = 0; - char *patch; - - switch (*params) - { - case HCI_EVENT_PATCHES_DRV_REQ: - - if (tSLInformation.sDriverPatches) - { - patch = tSLInformation.sDriverPatches(&ucLength); - - if (patch) - { - hci_patch_send(HCI_EVENT_PATCHES_DRV_REQ, - tSLInformation.pucTxCommandBuffer, patch, ucLength); - return; - } - } - - // Send 0 length Patches response event - hci_patch_send(HCI_EVENT_PATCHES_DRV_REQ, - tSLInformation.pucTxCommandBuffer, 0, 0); - break; - - case HCI_EVENT_PATCHES_FW_REQ: - - if (tSLInformation.sFWPatches) - { - patch = tSLInformation.sFWPatches(&ucLength); - - // Build and send a patch - if (patch) - { - hci_patch_send(HCI_EVENT_PATCHES_FW_REQ, - tSLInformation.pucTxCommandBuffer, patch, ucLength); - return; - } - } - - // Send 0 length Patches response event - hci_patch_send(HCI_EVENT_PATCHES_FW_REQ, - tSLInformation.pucTxCommandBuffer, 0, 0); - break; - - case HCI_EVENT_PATCHES_BOOTLOAD_REQ: - - if (tSLInformation.sBootLoaderPatches) - { - patch = tSLInformation.sBootLoaderPatches(&ucLength); - - if (patch) - { - hci_patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, - tSLInformation.pucTxCommandBuffer, patch, ucLength); - return; - } - } - - // Send 0 length Patches response event - hci_patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, - tSLInformation.pucTxCommandBuffer, 0, 0); - break; - } -} + if ((*pucReceivedData == HCI_TYPE_EVNT) && + (usReceivedEventOpcode == HCI_EVNT_PATCHES_REQ)) + { + hci_unsol_handle_patch_request((char *)pucReceivedData); + } + if ((tSLInformation.usRxEventOpcode == 0) && + (tSLInformation.usRxDataPending == 0)) + { + break; + } + } + } + return NULL; +} -//***************************************************************************** -// -//! hci_event_handler -//! -//! @param pRetParams incoming data buffer -//! @param from from information (in case of data received) -//! @param fromlen from information length (in case of data received) -//! -//! @return none -//! -//! @brief Parse the incoming events packets and issues corresponding -//! event handler from global array of handlers pointers -// -//***************************************************************************** - - -uint8_t * -hci_event_handler(void *pRetParams, uint8_t *from, uint8_t *fromlen) +/***************************************************************************** + * Name: hci_unsol_event_handler + * + * Description: + * Handle unsolicited events + * + * Input Parameters: + * event_hdr event header + * + * Returned Value: + * 1 if event supported and handled + * 0 if event is not supported + * + *****************************************************************************/ + +long hci_unsol_event_handler(char *event_hdr) { - uint8_t *pucReceivedData, ucArgsize; - uint16_t usLength; - uint8_t *pucReceivedParams; - uint16_t usReceivedEventOpcode = 0; - unsigned long retValue32; - uint8_t * RecvParams; - uint8_t *RetParams; - - - while (1) - { - if (tSLInformation.usEventOrDataReceived != 0) - { - pucReceivedData = (tSLInformation.pucReceivedData); - - if (*pucReceivedData == HCI_TYPE_EVNT) - { - // Event Received - STREAM_TO_UINT16((char *)pucReceivedData, HCI_EVENT_OPCODE_OFFSET, - usReceivedEventOpcode); - pucReceivedParams = pucReceivedData + HCI_EVENT_HEADER_SIZE; - RecvParams = pucReceivedParams; - RetParams = (uint8_t *)pRetParams; - - // In case unsolicited event received - here the handling finished - if (hci_unsol_event_handler((char *)pucReceivedData) == 0) - { - STREAM_TO_UINT8(pucReceivedData, HCI_DATA_LENGTH_OFFSET, usLength); - - switch(usReceivedEventOpcode) - { - case HCI_CMND_READ_BUFFER_SIZE: - { - STREAM_TO_UINT8((char *)pucReceivedParams, 0, - tSLInformation.usNumberOfFreeBuffers); - STREAM_TO_UINT16((char *)pucReceivedParams, 1, - tSLInformation.usSlBufferLength); - } - break; - - case HCI_CMND_WLAN_CONFIGURE_PATCH: - case HCI_NETAPP_DHCP: - case HCI_NETAPP_PING_SEND: - case HCI_NETAPP_PING_STOP: - case HCI_NETAPP_ARP_FLUSH: - case HCI_NETAPP_SET_DEBUG_LEVEL: - case HCI_NETAPP_SET_TIMERS: - case HCI_EVNT_NVMEM_READ: - case HCI_EVNT_NVMEM_CREATE_ENTRY: - case HCI_CMND_NVMEM_WRITE_PATCH: - case HCI_NETAPP_PING_REPORT: - case HCI_EVNT_MDNS_ADVERTISE: - - STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET - ,*(uint8_t *)pRetParams); - break; - - case HCI_CMND_SETSOCKOPT: - case HCI_CMND_WLAN_CONNECT: - case HCI_CMND_WLAN_IOCTL_STATUSGET: - case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE: - case HCI_CMND_WLAN_IOCTL_DEL_PROFILE: - case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY: - case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM: - case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START: - case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP: - case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX: - case HCI_CMND_EVENT_MASK: - case HCI_EVNT_WLAN_DISCONNECT: - case HCI_EVNT_SOCKET: - case HCI_EVNT_BIND: - case HCI_CMND_LISTEN: - case HCI_EVNT_CLOSE_SOCKET: - case HCI_EVNT_CONNECT: - case HCI_EVNT_NVMEM_WRITE: - - STREAM_TO_UINT32((char *)pucReceivedParams,0 - ,*(unsigned long *)pRetParams); - break; - - case HCI_EVNT_READ_SP_VERSION: - - STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET - ,*(uint8_t *)pRetParams); - pRetParams = ((char *)pRetParams) + 1; - STREAM_TO_UINT32((char *)pucReceivedParams, 0, retValue32); - UINT32_TO_STREAM((uint8_t *)pRetParams, retValue32); - break; - - case HCI_EVNT_BSD_GETHOSTBYNAME: - - STREAM_TO_UINT32((char *)pucReceivedParams - ,GET_HOST_BY_NAME_RETVAL_OFFSET,*(unsigned long *)pRetParams); - pRetParams = ((char *)pRetParams) + 4; - STREAM_TO_UINT32((char *)pucReceivedParams - ,GET_HOST_BY_NAME_ADDR_OFFSET,*(unsigned long *)pRetParams); - break; - - case HCI_EVNT_ACCEPT: - { - STREAM_TO_UINT32((char *)pucReceivedParams,ACCEPT_SD_OFFSET - ,*(unsigned long *)pRetParams); - pRetParams = ((char *)pRetParams) + 4; - STREAM_TO_UINT32((char *)pucReceivedParams - ,ACCEPT_RETURN_STATUS_OFFSET,*(unsigned long *)pRetParams); - pRetParams = ((char *)pRetParams) + 4; - - //This argument returns in network order - memcpy((uint8_t *)pRetParams, - pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr)); - break; - } - - case HCI_EVNT_RECV: - case HCI_EVNT_RECVFROM: - { - STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams); - pRetParams = ((char *)pRetParams) + 4; - STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams); - pRetParams = ((char *)pRetParams) + 4; - STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(unsigned long *)pRetParams); - - if(((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes == ERROR_SOCKET_INACTIVE) - { - set_socket_active_status(((tBsdReadReturnParams *)pRetParams)->iSocketDescriptor,SOCKET_STATUS_INACTIVE); - } - break; - } - - case HCI_EVNT_SEND: - case HCI_EVNT_SENDTO: - { - STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams); - pRetParams = ((char *)pRetParams) + 4; - STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams); - pRetParams = ((char *)pRetParams) + 4; - - break; - } - - case HCI_EVNT_SELECT: - { - STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_STATUS_OFFSET,*(unsigned long *)pRetParams); - pRetParams = ((char *)pRetParams) + 4; - STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_READFD_OFFSET,*(unsigned long *)pRetParams); - pRetParams = ((char *)pRetParams) + 4; - STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(unsigned long *)pRetParams); - pRetParams = ((char *)pRetParams) + 4; - STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_EXFD_OFFSET,*(unsigned long *)pRetParams); - break; - } - - case HCI_CMND_GETSOCKOPT: - - STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)pRetParams)->iStatus); - //This argument returns in network order - memcpy((uint8_t *)pRetParams, pucReceivedParams, 4); - break; - - case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS: - - STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(unsigned long *)pRetParams); - pRetParams = ((char *)pRetParams) + 4; - STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(unsigned long *)pRetParams); - pRetParams = ((char *)pRetParams) + 4; - STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(unsigned long *)pRetParams); - pRetParams = ((char *)pRetParams) + 2; - STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(unsigned long *)pRetParams); - pRetParams = ((char *)pRetParams) + 2; - memcpy((uint8_t *)pRetParams, - (char *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), - GET_SCAN_RESULTS_SSID_MAC_LENGTH); - break; - - case HCI_CMND_SIMPLE_LINK_START: - break; - - case HCI_NETAPP_IPCONFIG: - - //Read IP address - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); - RecvParams += 4; - - //Read subnet - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); - RecvParams += 4; - - //Read default GW - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); - RecvParams += 4; - - //Read DHCP server - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); - RecvParams += 4; - - //Read DNS server - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); - RecvParams += 4; - - //Read Mac address - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH); - RecvParams += 6; - - //Read SSID - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH); - - } - } - - if (usReceivedEventOpcode == tSLInformation.usRxEventOpcode) - { - tSLInformation.usRxEventOpcode = 0; - } - } - else - { - pucReceivedParams = pucReceivedData; - STREAM_TO_UINT8((char *)pucReceivedData, HCI_PACKET_ARGSIZE_OFFSET, ucArgsize); - - STREAM_TO_UINT16((char *)pucReceivedData, HCI_PACKET_LENGTH_OFFSET, usLength); - - // Data received: note that the only case where from and from length - // are not null is in recv from, so fill the args accordingly - if (from) - { - STREAM_TO_UINT32((char *)(pucReceivedData + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(unsigned long *)fromlen); - memcpy(from, (pucReceivedData + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen); - } - - memcpy(pRetParams, pucReceivedParams + HCI_DATA_HEADER_SIZE + ucArgsize, - usLength - ucArgsize); - - tSLInformation.usRxDataPending = 0; - } - - tSLInformation.usEventOrDataReceived = 0; - - SpiResumeSpi(); - - // Since we are going to TX - we need to handle this event after the - // ResumeSPi since we need interrupts - if ((*pucReceivedData == HCI_TYPE_EVNT) && - (usReceivedEventOpcode == HCI_EVNT_PATCHES_REQ)) - { - hci_unsol_handle_patch_request((char *)pucReceivedData); - } - - if ((tSLInformation.usRxEventOpcode == 0) && (tSLInformation.usRxDataPending == 0)) - { - return NULL; - } - } - } + char * data = NULL; + long event_type; + unsigned long NumberOfReleasedPackets; + unsigned long NumberOfSentPackets; + + STREAM_TO_UINT16(event_hdr, HCI_EVENT_OPCODE_OFFSET,event_type); + + if (event_type & HCI_EVNT_UNSOL_BASE) + { + switch(event_type) + { + case HCI_EVNT_DATA_UNSOL_FREE_BUFF: + { + hci_event_unsol_flowcontrol_handler(event_hdr); + + NumberOfReleasedPackets = tSLInformation.NumberOfReleasedPackets; + NumberOfSentPackets = tSLInformation.NumberOfSentPackets; + + if (NumberOfReleasedPackets == NumberOfSentPackets) + { + if (tSLInformation.InformHostOnTxComplete) + { + tSLInformation.sWlanCB(HCI_EVENT_CC3000_CAN_SHUT_DOWN, NULL, 0); + } + } + + return 1; + } + } + } + + if (event_type & HCI_EVNT_WLAN_UNSOL_BASE) + { + switch(event_type) + { + case HCI_EVNT_WLAN_KEEPALIVE: + case HCI_EVNT_WLAN_UNSOL_CONNECT: + case HCI_EVNT_WLAN_UNSOL_DISCONNECT: + case HCI_EVNT_WLAN_UNSOL_INIT: + case HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE: + + if (tSLInformation.sWlanCB) + { + tSLInformation.sWlanCB(event_type, 0, 0); + } + break; + + case HCI_EVNT_WLAN_UNSOL_DHCP: + { + uint8_t params[NETAPP_IPCONFIG_MAC_OFFSET + 1]; // extra byte is for the status + uint8_t *recParams = params; + + data = (char*)(event_hdr) + HCI_EVENT_HEADER_SIZE; + + /* Read IP address */ + + STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); + data += 4; + + /* Read subnet */ + + STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); + data += 4; + + /* Read default GW */ + + STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); + data += 4; + + /* Read DHCP server */ + + STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); + data += 4; + + /* Read DNS server */ + + STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); + + /* Read the status */ + + STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, *recParams); + + if (tSLInformation.sWlanCB) + { + tSLInformation.sWlanCB(event_type, (char *)params, sizeof(params)); + } + } + break; + + case HCI_EVNT_WLAN_ASYNC_PING_REPORT: + { + netapp_pingreport_args_t params; + data = (char*)(event_hdr) + HCI_EVENT_HEADER_SIZE; + STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_SENT_OFFSET, params.packets_sent); + STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_RCVD_OFFSET, params.packets_received); + STREAM_TO_UINT32(data, NETAPP_PING_MIN_RTT_OFFSET, params.min_round_time); + STREAM_TO_UINT32(data, NETAPP_PING_MAX_RTT_OFFSET, params.max_round_time); + STREAM_TO_UINT32(data, NETAPP_PING_AVG_RTT_OFFSET, params.avg_round_time); + + if (tSLInformation.sWlanCB) + { + tSLInformation.sWlanCB(event_type, (char *)¶ms, sizeof(params)); + } + } + break; + + case HCI_EVNT_BSD_TCP_CLOSE_WAIT: + { + if (tSLInformation.sWlanCB) + { + tSLInformation.sWlanCB(event_type, NULL, 0); + } + } + break; + + /* 'default' case which means "event not supported" */ + + default: + return 0; + } + + return 1; + } + + if ((event_type == HCI_EVNT_SEND) || (event_type == HCI_EVNT_SENDTO) || + (event_type == HCI_EVNT_WRITE)) + { + char *pArg; + long status; + + pArg = M_BSD_RESP_PARAMS_OFFSET(event_hdr); + STREAM_TO_UINT32(pArg, BSD_RSP_PARAMS_STATUS_OFFSET,status); + + if (ERROR_SOCKET_INACTIVE == status) + { + /* The only synchronous event that can come from SL device in form of + * command complete is "Command Complete" on data sent, in case SL device + * was unable to transmit + */ -} + STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, + tSLInformation.slTransmitDataError); + update_socket_active_status(M_BSD_RESP_PARAMS_OFFSET(event_hdr)); -//***************************************************************************** -// -//! hci_unsol_event_handler -//! -//! @param event_hdr event header -//! -//! @return 1 if event supported and handled -//! 0 if event is not supported -//! -//! @brief Handle unsolicited events -// -//***************************************************************************** -long -hci_unsol_event_handler(char *event_hdr) -{ - char * data = NULL; - long event_type; - unsigned long NumberOfReleasedPackets; - unsigned long NumberOfSentPackets; - - STREAM_TO_UINT16(event_hdr, HCI_EVENT_OPCODE_OFFSET,event_type); - - if (event_type & HCI_EVNT_UNSOL_BASE) - { - switch(event_type) - { - - case HCI_EVNT_DATA_UNSOL_FREE_BUFF: - { - hci_event_unsol_flowcontrol_handler(event_hdr); - - NumberOfReleasedPackets = tSLInformation.NumberOfReleasedPackets; - NumberOfSentPackets = tSLInformation.NumberOfSentPackets; - - if (NumberOfReleasedPackets == NumberOfSentPackets) - { - if (tSLInformation.InformHostOnTxComplete) - { - tSLInformation.sWlanCB(HCI_EVENT_CC3000_CAN_SHUT_DOWN, NULL, 0); - } - } - return 1; - - } - } - } - - if(event_type & HCI_EVNT_WLAN_UNSOL_BASE) - { - switch(event_type) - { - case HCI_EVNT_WLAN_KEEPALIVE: - case HCI_EVNT_WLAN_UNSOL_CONNECT: - case HCI_EVNT_WLAN_UNSOL_DISCONNECT: - case HCI_EVNT_WLAN_UNSOL_INIT: - case HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE: - - if( tSLInformation.sWlanCB ) - { - tSLInformation.sWlanCB(event_type, 0, 0); - } - break; - - case HCI_EVNT_WLAN_UNSOL_DHCP: - { - uint8_t params[NETAPP_IPCONFIG_MAC_OFFSET + 1]; // extra byte is for the status - uint8_t *recParams = params; - - data = (char*)(event_hdr) + HCI_EVENT_HEADER_SIZE; - - //Read IP address - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); - data += 4; - //Read subnet - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); - data += 4; - //Read default GW - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); - data += 4; - //Read DHCP server - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); - data += 4; - //Read DNS server - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); - // read the status - STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, *recParams); - - - if( tSLInformation.sWlanCB ) - { - tSLInformation.sWlanCB(event_type, (char *)params, sizeof(params)); - } - } - break; - - case HCI_EVNT_WLAN_ASYNC_PING_REPORT: - { - netapp_pingreport_args_t params; - data = (char*)(event_hdr) + HCI_EVENT_HEADER_SIZE; - STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_SENT_OFFSET, params.packets_sent); - STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_RCVD_OFFSET, params.packets_received); - STREAM_TO_UINT32(data, NETAPP_PING_MIN_RTT_OFFSET, params.min_round_time); - STREAM_TO_UINT32(data, NETAPP_PING_MAX_RTT_OFFSET, params.max_round_time); - STREAM_TO_UINT32(data, NETAPP_PING_AVG_RTT_OFFSET, params.avg_round_time); - - if( tSLInformation.sWlanCB ) - { - tSLInformation.sWlanCB(event_type, (char *)¶ms, sizeof(params)); - } - } - break; - case HCI_EVNT_BSD_TCP_CLOSE_WAIT: - { - if( tSLInformation.sWlanCB ) - { - tSLInformation.sWlanCB(event_type, NULL, 0); - } - } - break; - - //'default' case which means "event not supported" - default: - return (0); - } - return(1); - } - - if ((event_type == HCI_EVNT_SEND) || (event_type == HCI_EVNT_SENDTO) - || (event_type == HCI_EVNT_WRITE)) - { - char *pArg; - long status; - - pArg = M_BSD_RESP_PARAMS_OFFSET(event_hdr); - STREAM_TO_UINT32(pArg, BSD_RSP_PARAMS_STATUS_OFFSET,status); - - if (ERROR_SOCKET_INACTIVE == status) - { - // The only synchronous event that can come from SL device in form of - // command complete is "Command Complete" on data sent, in case SL device - // was unable to transmit - STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, tSLInformation.slTransmitDataError); - update_socket_active_status(M_BSD_RESP_PARAMS_OFFSET(event_hdr)); - - return (1); - } - else - return (0); - } - - return(0); + return 1; + } + else + { + return 0; + } + } + + return 0; } -//***************************************************************************** -// -//! hci_unsolicited_event_handler -//! -//! @param None -//! -//! @return ESUCCESS if successful, EFAIL if an error occurred -//! -//! @brief Parse the incoming unsolicited event packets and issues -//! corresponding event handler. -// -//***************************************************************************** -long -hci_unsolicited_event_handler(void) +/***************************************************************************** + * Name: hci_unsolicited_event_handler + * + * Description: + * Parse the incoming unsolicited event packets and issues corresponding + * event handler. + * + * Input Parameters: + * None + * + * Returned Value: + * ESUCCESS if successful, EFAIL if an error occurred + * + *****************************************************************************/ + +long hci_unsolicited_event_handler(void) { - unsigned long res = 0; - uint8_t *pucReceivedData; - - if (tSLInformation.usEventOrDataReceived != 0) - { - pucReceivedData = (tSLInformation.pucReceivedData); - - if (*pucReceivedData == HCI_TYPE_EVNT) - { - - // In case unsolicited event received - here the handling finished - if (hci_unsol_event_handler((char *)pucReceivedData) == 1) - { - - // There was an unsolicited event received - we can release the buffer - // and clean the event received - tSLInformation.usEventOrDataReceived = 0; - - res = 1; - SpiResumeSpi(); - } - } - } - - return res; + unsigned long res = 0; + uint8_t *pucReceivedData; + + if (tSLInformation.usEventOrDataReceived != 0) + { + pucReceivedData = (tSLInformation.pucReceivedData); + + if (*pucReceivedData == HCI_TYPE_EVNT) + { + /* In case unsolicited event received - here the handling finished */ + + if (hci_unsol_event_handler((char *)pucReceivedData) == 1) + { + /* There was an unsolicited event received - we can release the buffer + * and clean the event received + */ + + tSLInformation.usEventOrDataReceived = 0; + + res = 1; + SpiResumeSpi(); + } + } + } + + return res; } -//***************************************************************************** -// -//! set_socket_active_status -//! -//! @param Sd -//! @param Status -//! @return none -//! -//! @brief Check if the socket ID and status are valid and set -//! accordingly the global socket status -// -//***************************************************************************** +/***************************************************************************** + * Name: set_socket_active_status + * + * Description: + * Check if the socket ID and status are valid and set accordingly the + * global socket status + * + * Input Parameters: + * Sd + * Status + * + * Returned Value: + * None + * + *****************************************************************************/ + void set_socket_active_status(long Sd, long Status) { - if(M_IS_VALID_SD(Sd) && M_IS_VALID_STATUS(Status)) - { - socket_active_status &= ~(1 << Sd); /* clean socket's mask */ - socket_active_status |= (Status << Sd); /* set new socket's mask */ - } + if (M_IS_VALID_SD(Sd) && M_IS_VALID_STATUS(Status)) + { + socket_active_status &= ~(1 << Sd); /* Clean socket's mask */ + socket_active_status |= (Status << Sd); /* Set new socket's mask */ + } } - -//***************************************************************************** -// -//! hci_event_unsol_flowcontrol_handler -//! -//! @param pEvent pointer to the string contains parameters for IPERF -//! @return ESUCCESS if successful, EFAIL if an error occurred -//! -//! @brief Called in case unsolicited event from type -//! HCI_EVNT_DATA_UNSOL_FREE_BUFF has received. -//! Keep track on the number of packets transmitted and update the -//! number of free buffer in the SL device. -// -//***************************************************************************** -long -hci_event_unsol_flowcontrol_handler(char *pEvent) +/***************************************************************************** + * Name: hci_event_unsol_flowcontrol_handler + * + * Description: + * Called in case unsolicited event from type HCI_EVNT_DATA_UNSOL_FREE_BUFF + * has received. Keep track on the number of packets transmitted and update + * the number of free buffer in the SL device. + * + * Input Parameters: + * pEvent pointer to the string contains parameters for IPERF + * + * Returned Value: + * ESUCCESS if successful, EFAIL if an error occurred + * + *****************************************************************************/ + +long hci_event_unsol_flowcontrol_handler(char *pEvent) { - - long temp, value; - uint16_t i; - uint16_t pusNumberOfHandles=0; - char *pReadPayload; - - STREAM_TO_UINT16((char *)pEvent,HCI_EVENT_HEADER_SIZE,pusNumberOfHandles); - pReadPayload = ((char *)pEvent + - HCI_EVENT_HEADER_SIZE + sizeof(pusNumberOfHandles)); - temp = 0; - - for(i = 0; i < pusNumberOfHandles ; i++) - { - STREAM_TO_UINT16(pReadPayload, FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET, value); - temp += value; - pReadPayload += FLOW_CONTROL_EVENT_SIZE; - } - - tSLInformation.usNumberOfFreeBuffers += temp; - tSLInformation.NumberOfReleasedPackets += temp; - - return(ESUCCESS); + long temp, value; + uint16_t i; + uint16_t pusNumberOfHandles=0; + char *pReadPayload; + + STREAM_TO_UINT16((char *)pEvent,HCI_EVENT_HEADER_SIZE,pusNumberOfHandles); + pReadPayload = ((char *)pEvent + + HCI_EVENT_HEADER_SIZE + sizeof(pusNumberOfHandles)); + temp = 0; + + for (i = 0; i < pusNumberOfHandles ; i++) + { + STREAM_TO_UINT16(pReadPayload, FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET, value); + temp += value; + pReadPayload += FLOW_CONTROL_EVENT_SIZE; + } + + tSLInformation.usNumberOfFreeBuffers += temp; + tSLInformation.NumberOfReleasedPackets += temp; + + return(ESUCCESS); } -//***************************************************************************** -// -//! get_socket_active_status -//! -//! @param Sd Socket IS -//! @return Current status of the socket. -//! -//! @brief Retrieve socket status -// -//***************************************************************************** - -long -get_socket_active_status(long Sd) +/***************************************************************************** + * Name: get_socket_active_status + * + * Description: + * Retrieve socket status + * + * Input Parameters: + * Sd Socket IS + * + * Returned Value: + * Current status of the socket. + * + *****************************************************************************/ + +long get_socket_active_status(long Sd) { - if(M_IS_VALID_SD(Sd)) - { - return (socket_active_status & (1 << Sd)) ? SOCKET_STATUS_INACTIVE : SOCKET_STATUS_ACTIVE; - } - return SOCKET_STATUS_INACTIVE; + if (M_IS_VALID_SD(Sd)) + { + return (socket_active_status & (1 << Sd)) ? + SOCKET_STATUS_INACTIVE : SOCKET_STATUS_ACTIVE; + } + + return SOCKET_STATUS_INACTIVE; } -//***************************************************************************** -// -//! update_socket_active_status -//! -//! @param resp_params Socket IS -//! @return Current status of the socket. -//! -//! @brief Retrieve socket status -// -//***************************************************************************** -void -update_socket_active_status(char *resp_params) +/***************************************************************************** + * Name: update_socket_active_status + * + * Description: + * Retrieve socket status + * + * Input Parameters: + * resp_params Socket IS + * + * Returned Value: + * Current status of the socket. + * + *****************************************************************************/ + +void update_socket_active_status(char *resp_params) { - long status, sd; - - STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_SOCKET_OFFSET,sd); - STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_STATUS_OFFSET,status); - - if(ERROR_SOCKET_INACTIVE == status) - { - set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); - } -} + long status, sd; + STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_SOCKET_OFFSET,sd); + STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_STATUS_OFFSET,status); -//***************************************************************************** -// -//! SimpleLinkWaitEvent -//! -//! @param usOpcode command operation code -//! @param pRetParams command return parameters -//! -//! @return none -//! -//! @brief Wait for event, pass it to the hci_event_handler and -//! update the event opcode in a global variable. -// -//***************************************************************************** - -void -SimpleLinkWaitEvent(uint16_t usOpcode, void *pRetParams) -{ - // In the blocking implementation the control to caller will be returned only - // after the end of current transaction - tSLInformation.usRxEventOpcode = usOpcode; - hci_event_handler(pRetParams, 0, 0); + if (ERROR_SOCKET_INACTIVE == status) + { + set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); + } } -//***************************************************************************** -// -//! SimpleLinkWaitData -//! -//! @param pBuf data buffer -//! @param from from information -//! @param fromlen from information length -//! -//! @return none -//! -//! @brief Wait for data, pass it to the hci_event_handler -//! and update in a global variable that there is -//! data to read. -// -//***************************************************************************** - -void -SimpleLinkWaitData(uint8_t *pBuf, uint8_t *from, - uint8_t *fromlen) +/***************************************************************************** + * Name: SimpleLinkWaitEvent + * + * Description: + * Wait for event, pass it to the hci_event_handler and update the event + * opcode in a global variable. + * + * Input Parameters: + * usOpcode command operation code + * pRetParams command return parameters + * + * Returned Value: + * None + * + *****************************************************************************/ + +void SimpleLinkWaitEvent(uint16_t usOpcode, void *pRetParams) { - // In the blocking implementation the control to caller will be returned only - // after the end of current transaction, i.e. only after data will be received - tSLInformation.usRxDataPending = 1; - hci_event_handler(pBuf, from, fromlen); + /* In the blocking implementation the control to caller will be returned only + * after the end of current transaction + */ + + tSLInformation.usRxEventOpcode = usOpcode; + hci_event_handler(pRetParams, 0, 0); } -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** +/***************************************************************************** + * Name: SimpleLinkWaitData + * + * Description: + * Wait for data, pass it to the hci_event_handler and update in a global + * variable that there is data to read. + * + * Input Parameters: + * pBuf data buffer + * from from information + * fromlen from information length + * + * Returned Value: + * None + * + *****************************************************************************/ + +void SimpleLinkWaitData(uint8_t *pBuf, uint8_t *from, uint8_t *fromlen) +{ + /* In the blocking implementation the control to caller will be returned only + * after the end of current transaction, i.e. only after data will be received + */ + + tSLInformation.usRxDataPending = 1; + hci_event_handler(pBuf, from, fromlen); +} diff --git a/nuttx/drivers/wireless/cc3000/hci.c b/nuttx/drivers/wireless/cc3000/hci.c index 033f1e7cd..37daf0544 100644 --- a/nuttx/drivers/wireless/cc3000/hci.c +++ b/nuttx/drivers/wireless/cc3000/hci.c @@ -1,230 +1,236 @@ /***************************************************************************** -* -* hci.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ - -//***************************************************************************** -// -//! \addtogroup hci_app -//! @{ -// -//***************************************************************************** + * hci.c - CC3000 Host Driver Implementation. + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +/****************************************************************************** + * Included Files + ******************************************************************************/ #include #include #include -#include +#include "spi.h" #include #include -#define SL_PATCH_PORTION_SIZE (1000) - - -//***************************************************************************** -// -//! hci_command_send -//! -//! @param usOpcode command operation code -//! @param pucBuff pointer to the command's arguments buffer -//! @param ucArgsLength length of the arguments -//! -//! @return none -//! -//! @brief Initiate an HCI command. -// -//***************************************************************************** -uint16_t -hci_command_send(uint16_t usOpcode, uint8_t *pucBuff, - uint8_t ucArgsLength) -{ - uint8_t *stream; - - stream = (pucBuff + SPI_HEADER_SIZE); - - UINT8_TO_STREAM(stream, HCI_TYPE_CMND); - stream = UINT16_TO_STREAM(stream, usOpcode); - UINT8_TO_STREAM(stream, ucArgsLength); - - //Update the opcode of the event we will be waiting for - SpiWrite(pucBuff, ucArgsLength + SIMPLE_LINK_HCI_CMND_HEADER_SIZE); - - return(0); +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +#define SL_PATCH_PORTION_SIZE (1000) + +/****************************************************************************** + * Public Functions + ******************************************************************************/ +/****************************************************************************** + * Name: hci_command_send + * + * Description: + * Initiate an HCI command. + * + * Input Parameters: + * usOpcode command operation code + * pucBuff pointer to the command's arguments buffer + * ucArgsLength length of the arguments + * + * Returned Value: + * Zero + * + *****************************************************************************/ + +uint16_t hci_command_send(uint16_t usOpcode, uint8_t *pucBuff, uint8_t ucArgsLength) +{ + uint8_t *stream; + + stream = (pucBuff + SPI_HEADER_SIZE); + + UINT8_TO_STREAM(stream, HCI_TYPE_CMND); + stream = UINT16_TO_STREAM(stream, usOpcode); + UINT8_TO_STREAM(stream, ucArgsLength); + + /* Update the opcode of the event we will be waiting for */ + + SpiWrite(pucBuff, ucArgsLength + SIMPLE_LINK_HCI_CMND_HEADER_SIZE); + + return 0; } -//***************************************************************************** -// -//! hci_data_send -//! -//! @param usOpcode command operation code -//! @param ucArgs pointer to the command's arguments buffer -//! @param usArgsLength length of the arguments -//! @param ucTail pointer to the data buffer -//! @param usTailLength buffer length -//! -//! @return none -//! -//! @brief Initiate an HCI data write operation -// -//***************************************************************************** -long -hci_data_send(uint8_t ucOpcode, - uint8_t *ucArgs, - uint16_t usArgsLength, - uint16_t usDataLength, - const uint8_t *ucTail, - uint16_t usTailLength) +/****************************************************************************** + * Name: hci_data_send + * + * Description: + * + * + * Input Parameters: + * usOpcode command operation code + * ucArgs pointer to the command's arguments buffer + * usArgsLength length of the arguments + * ucTail pointer to the data buffer + * usTailLength buffer length + * + * Returned Value: + * None + * + *****************************************************************************/ + +long hci_data_send(uint8_t ucOpcode, uint8_t *ucArgs, uint16_t usArgsLength, + uint16_t usDataLength, const uint8_t *ucTail, + uint16_t usTailLength) { - uint8_t *stream; - - stream = ((ucArgs) + SPI_HEADER_SIZE); - - UINT8_TO_STREAM(stream, HCI_TYPE_DATA); - UINT8_TO_STREAM(stream, ucOpcode); - UINT8_TO_STREAM(stream, usArgsLength); - stream = UINT16_TO_STREAM(stream, usArgsLength + usDataLength + usTailLength); - - // Send the packet over the SPI - SpiWrite(ucArgs, SIMPLE_LINK_HCI_DATA_HEADER_SIZE + usArgsLength + usDataLength + usTailLength); - - return(ESUCCESS); + uint8_t *stream; + + stream = ((ucArgs) + SPI_HEADER_SIZE); + + UINT8_TO_STREAM(stream, HCI_TYPE_DATA); + UINT8_TO_STREAM(stream, ucOpcode); + UINT8_TO_STREAM(stream, usArgsLength); + stream = UINT16_TO_STREAM(stream, usArgsLength + usDataLength + usTailLength); + + /* Send the packet over the SPI */ + + SpiWrite(ucArgs, SIMPLE_LINK_HCI_DATA_HEADER_SIZE + usArgsLength + usDataLength + usTailLength); + + return ESUCCESS; } +/****************************************************************************** + * Name: hci_data_command_send + * + * Description: + * Prepeare HCI header and initiate an HCI data write operation + * + * Input Parameters: + * usOpcode command operation code + * pucBuff pointer to the data buffer + * ucArgsLength arguments length + * ucDataLength data length + * + * Returned Value: + * None + * + *****************************************************************************/ -//***************************************************************************** -// -//! hci_data_command_send -//! -//! @param usOpcode command operation code -//! @param pucBuff pointer to the data buffer -//! @param ucArgsLength arguments length -//! @param ucDataLength data length -//! -//! @return none -//! -//! @brief Prepeare HCI header and initiate an HCI data write operation -// -//***************************************************************************** void hci_data_command_send(uint16_t usOpcode, uint8_t *pucBuff, - uint8_t ucArgsLength,uint16_t ucDataLength) -{ - uint8_t *stream = (pucBuff + SPI_HEADER_SIZE); - - UINT8_TO_STREAM(stream, HCI_TYPE_DATA); - UINT8_TO_STREAM(stream, usOpcode); - UINT8_TO_STREAM(stream, ucArgsLength); - stream = UINT16_TO_STREAM(stream, ucArgsLength + ucDataLength); - - // Send the command over SPI on data channel - SpiWrite(pucBuff, ucArgsLength + ucDataLength + SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE); - - return; -} + uint8_t ucArgsLength,uint16_t ucDataLength) +{ + uint8_t *stream = (pucBuff + SPI_HEADER_SIZE); + + UINT8_TO_STREAM(stream, HCI_TYPE_DATA); + UINT8_TO_STREAM(stream, usOpcode); + UINT8_TO_STREAM(stream, ucArgsLength); + stream = UINT16_TO_STREAM(stream, ucArgsLength + ucDataLength); -//***************************************************************************** -// -//! hci_patch_send -//! -//! @param usOpcode command operation code -//! @param pucBuff pointer to the command's arguments buffer -//! @param patch pointer to patch content buffer -//! @param usDataLength data length -//! -//! @return none -//! -//! @brief Prepeare HCI header and initiate an HCI patch write operation -// -//***************************************************************************** -void -hci_patch_send(uint8_t ucOpcode, uint8_t *pucBuff, char *patch, uint16_t usDataLength) -{ - uint8_t *data_ptr = (pucBuff + SPI_HEADER_SIZE); - uint16_t usTransLength; - uint8_t *stream = (pucBuff + SPI_HEADER_SIZE); - - UINT8_TO_STREAM(stream, HCI_TYPE_PATCH); - UINT8_TO_STREAM(stream, ucOpcode); - stream = UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE); - - if (usDataLength <= SL_PATCH_PORTION_SIZE) - { - UINT16_TO_STREAM(stream, usDataLength); - stream = UINT16_TO_STREAM(stream, usDataLength); - memcpy((pucBuff + SPI_HEADER_SIZE) + HCI_PATCH_HEADER_SIZE, patch, usDataLength); - - // Update the opcode of the event we will be waiting for - SpiWrite(pucBuff, usDataLength + HCI_PATCH_HEADER_SIZE); - } - else - { - - usTransLength = (usDataLength/SL_PATCH_PORTION_SIZE); - UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE + usTransLength*SIMPLE_LINK_HCI_PATCH_HEADER_SIZE); - stream = UINT16_TO_STREAM(stream, SL_PATCH_PORTION_SIZE); - memcpy(pucBuff + SPI_HEADER_SIZE + HCI_PATCH_HEADER_SIZE, patch, SL_PATCH_PORTION_SIZE); - usDataLength -= SL_PATCH_PORTION_SIZE; - patch += SL_PATCH_PORTION_SIZE; - - // Update the opcode of the event we will be waiting for - SpiWrite(pucBuff, SL_PATCH_PORTION_SIZE + HCI_PATCH_HEADER_SIZE); - - while (usDataLength) - { - if (usDataLength <= SL_PATCH_PORTION_SIZE) - { - usTransLength = usDataLength; - usDataLength = 0; - - } - else - { - usTransLength = SL_PATCH_PORTION_SIZE; - usDataLength -= usTransLength; - } - - *(uint16_t *)data_ptr = usTransLength; - memcpy(data_ptr + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE, patch, usTransLength); - patch += usTransLength; - - // Update the opcode of the event we will be waiting for - SpiWrite((uint8_t *)data_ptr, usTransLength + sizeof(usTransLength)); - } - } + /* Send the command over SPI on data channel */ + + SpiWrite(pucBuff, + ucArgsLength + ucDataLength + SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE); } -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -// -//***************************************************************************** +/****************************************************************************** + * Name: hci_patch_send + * + * Description: + * Prepeare HCI header and initiate an HCI patch write operation + * + * Input Parameters: + * usOpcode command operation code + * pucBuff pointer to the command's arguments buffer + * patch pointer to patch content buffer + * usDataLength data length + * + * Returned Value: + * None + * + *****************************************************************************/ + +void hci_patch_send(uint8_t ucOpcode, uint8_t *pucBuff, char *patch, + uint16_t usDataLength) +{ + uint8_t *data_ptr = (pucBuff + SPI_HEADER_SIZE); + uint16_t usTransLength; + uint8_t *stream = (pucBuff + SPI_HEADER_SIZE); + + UINT8_TO_STREAM(stream, HCI_TYPE_PATCH); + UINT8_TO_STREAM(stream, ucOpcode); + stream = UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE); + + if (usDataLength <= SL_PATCH_PORTION_SIZE) + { + UINT16_TO_STREAM(stream, usDataLength); + stream = UINT16_TO_STREAM(stream, usDataLength); + memcpy((pucBuff + SPI_HEADER_SIZE) + HCI_PATCH_HEADER_SIZE, patch, usDataLength); + + /* Update the opcode of the event we will be waiting for */ + + SpiWrite(pucBuff, usDataLength + HCI_PATCH_HEADER_SIZE); + } + else + { + usTransLength = (usDataLength/SL_PATCH_PORTION_SIZE); + UINT16_TO_STREAM(stream, + usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE + + usTransLength*SIMPLE_LINK_HCI_PATCH_HEADER_SIZE); + stream = UINT16_TO_STREAM(stream, SL_PATCH_PORTION_SIZE); + memcpy(pucBuff + SPI_HEADER_SIZE + HCI_PATCH_HEADER_SIZE, patch, + SL_PATCH_PORTION_SIZE); + usDataLength -= SL_PATCH_PORTION_SIZE; + patch += SL_PATCH_PORTION_SIZE; + + /* Update the opcode of the event we will be waiting for */ + + SpiWrite(pucBuff, SL_PATCH_PORTION_SIZE + HCI_PATCH_HEADER_SIZE); + + while (usDataLength) + { + if (usDataLength <= SL_PATCH_PORTION_SIZE) + { + usTransLength = usDataLength; + usDataLength = 0; + } + else + { + usTransLength = SL_PATCH_PORTION_SIZE; + usDataLength -= usTransLength; + } + + *(uint16_t *)data_ptr = usTransLength; + memcpy(data_ptr + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE, patch, + usTransLength); + patch += usTransLength; + + /* Update the opcode of the event we will be waiting for */ + + SpiWrite((uint8_t *)data_ptr, usTransLength + sizeof(usTransLength)); + } + } +} diff --git a/nuttx/drivers/wireless/cc3000/host_driver_version.h b/nuttx/drivers/wireless/cc3000/host_driver_version.h index 0604fed5f..70204b17f 100644 --- a/nuttx/drivers/wireless/cc3000/host_driver_version.h +++ b/nuttx/drivers/wireless/cc3000/host_driver_version.h @@ -12,23 +12,23 @@ * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the +* documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ diff --git a/nuttx/drivers/wireless/cc3000/netapp.c b/nuttx/drivers/wireless/cc3000/netapp.c index 4bdd205db..dea7dd688 100644 --- a/nuttx/drivers/wireless/cc3000/netapp.c +++ b/nuttx/drivers/wireless/cc3000/netapp.c @@ -1,44 +1,52 @@ /***************************************************************************** -* -* netapp.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ + * netapp.c - CC3000 Host Driver Implementation. + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +/****************************************************************************** + * Included Files + ******************************************************************************/ + #include #include #include -#include +#include #include #include +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + #define MIN_TIMER_VAL_SECONDS 20 #define MIN_TIMER_SET(t) if ((0 != t) && (t < MIN_TIMER_VAL_SECONDS)) \ { \ @@ -46,414 +54,452 @@ } -#define NETAPP_DHCP_PARAMS_LEN (20) -#define NETAPP_SET_TIMER_PARAMS_LEN (20) -#define NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN (4) -#define NETAPP_PING_SEND_PARAMS_LEN (16) - - -//***************************************************************************** -// -//! netapp_config_mac_adrress -//! -//! @param mac device mac address, 6 bytes. Saved: yes -//! -//! @return return on success 0, otherwise error. -//! -//! @brief Configure device MAC address and store it in NVMEM. -//! The value of the MAC address configured through the API will -//! be stored in CC3000 non volatile memory, thus preserved -//! over resets. -// -//***************************************************************************** +#define NETAPP_DHCP_PARAMS_LEN (20) +#define NETAPP_SET_TIMER_PARAMS_LEN (20) +#define NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN (4) +#define NETAPP_PING_SEND_PARAMS_LEN (16) + +/****************************************************************************** + * Public Functions + ******************************************************************************/ + +/****************************************************************************** + * Name: netapp_config_mac_adrress + * + * Description: + * Configure device MAC address and store it in NVMEM. The value of the MAC + * address configured through the API will be stored in CC3000 non volatile + * memory, thus preserved over resets. + * + * Input Parameters: + * mac device mac address, 6 bytes. Saved: yes + * + * Returned Value: + * Return on success 0, otherwise error. + * + *****************************************************************************/ + long netapp_config_mac_adrress(uint8_t * mac) { - return nvmem_set_mac_address(mac); + return nvmem_set_mac_address(mac); } -//***************************************************************************** -// -//! netapp_dhcp -//! -//! @param aucIP device mac address, 6 bytes. Saved: yes -//! @param aucSubnetMask device mac address, 6 bytes. Saved: yes -//! @param aucDefaultGateway device mac address, 6 bytes. Saved: yes -//! @param aucDNSServer device mac address, 6 bytes. Saved: yes -//! -//! @return return on success 0, otherwise error. -//! -//! @brief netapp_dhcp is used to configure the network interface, -//! static or dynamic (DHCP).\n In order to activate DHCP mode, -//! aucIP, aucSubnetMask, aucDefaultGateway must be 0. -//! The default mode of CC3000 is DHCP mode. -//! Note that the configuration is saved in non volatile memory -//! and thus preserved over resets. -//! -//! @note If the mode is altered a reset of CC3000 device is required -//! in order to apply changes.\nAlso note that asynchronous event -//! of DHCP_EVENT, which is generated when an IP address is -//! allocated either by the DHCP server or due to static -//! allocation is generated only upon a connection to the -//! AP was established. -//! -//***************************************************************************** -long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsigned long *aucDefaultGateway, unsigned long *aucDNSServer) +/****************************************************************************** + * Name: netapp_dhcp + * + * Description: + * netapp_dhcp is used to configure the network interface, static or + * dynamic (DHCP).\n In order to activate DHCP mode, aucIP, aucSubnetMask, + * aucDefaultGateway must be 0. The default mode of CC3000 is DHCP mode. Note + * that the configuration is saved in non volatile memory and thus preserved + * over resets. + * + * NOTE: If the mode is altered a reset of CC3000 device is required in order + * to apply changes.\nAlso note that asynchronous event of DHCP_EVENT, which + * is generated when an IP address is allocated either by the DHCP server or + * due to static allocation is generated only upon a connection to the AP was + * established. + * + * Input Parameters: + * aucIP device mac address, 6 bytes. Saved: yes + * aucSubnetMask device mac address, 6 bytes. Saved: yes + * aucDefaultGateway device mac address, 6 bytes. Saved: yes + * aucDNSServer device mac address, 6 bytes. Saved: yes + * + * Returned Value: + * Return on success 0, otherwise error. + * + *****************************************************************************/ + +long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask, + unsigned long *aucDefaultGateway, unsigned long *aucDNSServer) { - int8_t scRet; - uint8_t *ptr; - uint8_t *args; - - scRet = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - ARRAY_TO_STREAM(args,aucIP,4); - ARRAY_TO_STREAM(args,aucSubnetMask,4); - ARRAY_TO_STREAM(args,aucDefaultGateway,4); - args = UINT32_TO_STREAM(args, 0); - ARRAY_TO_STREAM(args,aucDNSServer,4); - - // Initiate a HCI command - hci_command_send(HCI_NETAPP_DHCP, ptr, NETAPP_DHCP_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_NETAPP_DHCP, &scRet); - - return(scRet); -} + int8_t scRet; + uint8_t *ptr; + uint8_t *args; + + scRet = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_CMD); + + /* Fill in temporary command buffer */ + + ARRAY_TO_STREAM(args,aucIP,4); + ARRAY_TO_STREAM(args,aucSubnetMask,4); + ARRAY_TO_STREAM(args,aucDefaultGateway,4); + args = UINT32_TO_STREAM(args, 0); + ARRAY_TO_STREAM(args,aucDNSServer,4); + /* Initiate a HCI command */ -//***************************************************************************** -// -//! netapp_timeout_values -//! -//! @param aucDHCP DHCP lease time request, also impact -//! the DHCP renew timeout. Range: [0-0xffffffff] seconds, -//! 0 or 0xffffffff == infinity lease timeout. -//! Resolution:10 seconds. Influence: only after -//! reconnecting to the AP. -//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds. -//! The parameter is saved into the CC3000 NVMEM. -//! The default value on CC3000 is 14400 seconds. -//! -//! @param aucARP ARP refresh timeout, if ARP entry is not updated by -//! incoming packet, the ARP entry will be deleted by -//! the end of the timeout. -//! Range: [0-0xffffffff] seconds, 0 == infinity ARP timeout -//! Resolution: 10 seconds. Influence: on runtime. -//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds -//! The parameter is saved into the CC3000 NVMEM. -//! The default value on CC3000 is 3600 seconds. -//! -//! @param aucKeepalive Keepalive event sent by the end of keepalive timeout -//! Range: [0-0xffffffff] seconds, 0 == infinity timeout -//! Resolution: 10 seconds. -//! Influence: on runtime. -//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec -//! The parameter is saved into the CC3000 NVMEM. -//! The default value on CC3000 is 10 seconds. -//! -//! @param aucInactivity Socket inactivity timeout, socket timeout is -//! refreshed by incoming or outgoing packet, by the -//! end of the socket timeout the socket will be closed -//! Range: [0-0xffffffff] sec, 0 == infinity timeout. -//! Resolution: 10 seconds. Influence: on runtime. -//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec -//! The parameter is saved into the CC3000 NVMEM. -//! The default value on CC3000 is 60 seconds. -//! -//! @return return on success 0, otherwise error. -//! -//! @brief Set new timeout values. Function set new timeout values for: -//! DHCP lease timeout, ARP refresh timeout, keepalive event -//! timeout and socket inactivity timeout -//! -//! @note If a parameter set to non zero value which is less than 20s, -//! it will be set automatically to 20s. -//! -//***************************************************************************** + hci_command_send(HCI_NETAPP_DHCP, ptr, NETAPP_DHCP_PARAMS_LEN); + + /* Wait for command complete event */ + + SimpleLinkWaitEvent(HCI_NETAPP_DHCP, &scRet); + + return(scRet); +} + +/****************************************************************************** + * Name: netapp_timeout_values + * + * Description: + * Set new timeout values. Function set new timeout values for: DHCP lease + * timeout, ARP refresh timeout, keepalive event timeout and socket + * inactivity timeout + * + * NOTE: If a parameter set to non zero value which is less than 20s, it will + * be set automatically to 20s. + * + * Input Parameters: + * aucDHCP DHCP lease time request, also impact the DHCP renew timeout. + * Range: [0-0xffffffff] seconds, 0 or 0xffffffff == infinity + * lease timeout. + * Resolution: 10 seconds. + * Influence: only after reconnecting to the AP + * Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds. + * The parameter is saved into the CC3000 NVMEM. The default + * value on CC3000 is 14400 seconds. + * aucARP ARP refresh timeout, if ARP entry is not updated by incoming + * packet, the ARP entry will be deleted by the end of the + * timeout. + * Range: [0-0xffffffff] seconds, 0 == infinity ARP timeout + * Resolution: 10 seconds. + * Influence: on runtime. + * Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds. + * The parameter is saved into the CC3000 NVMEM. The default + * value on CC3000 is 3600 seconds. + * aucKeepalive Keepalive event sent by the end of keepalive timeout + * Range: [0-0xffffffff] seconds, 0 == infinity timeout + * Resolution: 10 seconds. + * Influence: on runtime. + * Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec + * The parameter is saved into the CC3000 NVMEM. The default + * value on CC3000 is 10 seconds. + * aucInactivity Socket inactivity timeout, socket timeout is refreshed by + * incoming or outgoing packet, by the end of the socket + * timeout the socket will be closed + * Range: [0-0xffffffff] sec, 0 == infinity timeout. + * Resolution: 10 seconds. Influence: on runtime. + * Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec + * The parameter is saved into the CC3000 NVMEM. The default + * value on CC3000 is 60 seconds. + * + * Returned Value: + * Return on success 0, otherwise error. + * + *****************************************************************************/ #ifndef CC3000_TINY_DRIVER -long -netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP,unsigned long *aucKeepalive, unsigned long *aucInactivity) +long netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP, + unsigned long *aucKeepalive, + unsigned long *aucInactivity) { - int8_t scRet; - uint8_t *ptr; - uint8_t *args; - - scRet = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Set minimal values of timers - MIN_TIMER_SET(*aucDHCP) - MIN_TIMER_SET(*aucARP) - MIN_TIMER_SET(*aucKeepalive) - MIN_TIMER_SET(*aucInactivity) - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, *aucDHCP); - args = UINT32_TO_STREAM(args, *aucARP); - args = UINT32_TO_STREAM(args, *aucKeepalive); - args = UINT32_TO_STREAM(args, *aucInactivity); - - // Initiate a HCI command - hci_command_send(HCI_NETAPP_SET_TIMERS, ptr, NETAPP_SET_TIMER_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_NETAPP_SET_TIMERS, &scRet); - - return(scRet); + int8_t scRet; + uint8_t *ptr; + uint8_t *args; + + scRet = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_CMD); + + /* Set minimal values of timers */ + + MIN_TIMER_SET(*aucDHCP) + MIN_TIMER_SET(*aucARP) + MIN_TIMER_SET(*aucKeepalive) + MIN_TIMER_SET(*aucInactivity) + + /* Fill in temporary command buffer */ + + args = UINT32_TO_STREAM(args, *aucDHCP); + args = UINT32_TO_STREAM(args, *aucARP); + args = UINT32_TO_STREAM(args, *aucKeepalive); + args = UINT32_TO_STREAM(args, *aucInactivity); + + /* Initiate a HCI command */ + + hci_command_send(HCI_NETAPP_SET_TIMERS, ptr, NETAPP_SET_TIMER_PARAMS_LEN); + + /* Wait for command complete event */ + + SimpleLinkWaitEvent(HCI_NETAPP_SET_TIMERS, &scRet); + + return scRet; } #endif -//***************************************************************************** -// -//! netapp_ping_send -//! -//! @param ip destination IP address -//! @param pingAttempts number of echo requests to send -//! @param pingSize send buffer size which may be up to 1400 bytes -//! @param pingTimeout Time to wait for a response,in milliseconds. -//! -//! @return return on success 0, otherwise error. -//! -//! @brief send ICMP ECHO_REQUEST to network hosts -//! -//! @note If an operation finished successfully asynchronous ping report -//! event will be generated. The report structure is as defined -//! by structure netapp_pingreport_args_t. -//! -//! @warning Calling this function while a previous Ping Requests are in -//! progress will stop the previous ping request. -//***************************************************************************** +/****************************************************************************** + * Name: netapp_ping_send + * + * Description: + * Send ICMP ECHO_REQUEST to network hosts + * + * NOTE: If an operation finished successfully asynchronous ping report event + * will be generated. The report structure is as defined by structure + * netapp_pingreport_args_t. + * + * WARNING: Calling this function while a previous Ping Requests are in + * progress will stop the previous ping request. + * + * Input Parameters: + * ip destination IP address + * pingAttempts number of echo requests to send + * pingSize send buffer size which may be up to 1400 bytes + * pingTimeout Time to wait for a response,in milliseconds. + * + * Returned Value: + * Return on success 0, otherwise error. + * + *****************************************************************************/ #ifndef CC3000_TINY_DRIVER -long -netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts, unsigned long ulPingSize, unsigned long ulPingTimeout) +long netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts, + unsigned long ulPingSize, unsigned long ulPingTimeout) { - int8_t scRet; - uint8_t *ptr, *args; - - scRet = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, *ip); - args = UINT32_TO_STREAM(args, ulPingAttempts); - args = UINT32_TO_STREAM(args, ulPingSize); - args = UINT32_TO_STREAM(args, ulPingTimeout); - - // Initiate a HCI command - hci_command_send(HCI_NETAPP_PING_SEND, ptr, NETAPP_PING_SEND_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_NETAPP_PING_SEND, &scRet); - - return(scRet); + int8_t scRet; + uint8_t *ptr, *args; + + scRet = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_CMD); + + /* Fill in temporary command buffer */ + + args = UINT32_TO_STREAM(args, *ip); + args = UINT32_TO_STREAM(args, ulPingAttempts); + args = UINT32_TO_STREAM(args, ulPingSize); + args = UINT32_TO_STREAM(args, ulPingTimeout); + + /* Initiate a HCI command */ + + hci_command_send(HCI_NETAPP_PING_SEND, ptr, NETAPP_PING_SEND_PARAMS_LEN); + + /* Wait for command complete event */ + + SimpleLinkWaitEvent(HCI_NETAPP_PING_SEND, &scRet); + + return scRet; } #endif -//***************************************************************************** -// -//! netapp_ping_report -//! -//! @param none -//! -//! @return none -//! -//! @brief Request for ping status. This API triggers the CC3000 to send -//! asynchronous events: HCI_EVNT_WLAN_ASYNC_PING_REPORT. -//! This event will carry the report structure: -//! netapp_pingreport_args_t. This structure is filled in with ping -//! results up till point of triggering API. -//! netapp_pingreport_args_t:\n packets_sent - echo sent, -//! packets_received - echo reply, min_round_time - minimum -//! round time, max_round_time - max round time, -//! avg_round_time - average round time -//! -//! @note When a ping operation is not active, the returned structure -//! fields are 0. -//! -//***************************************************************************** - +/****************************************************************************** + * Name: netapp_ping_report + * + * Description: + * Request for ping status. This API triggers the CC3000 to send asynchronous + * events: HCI_EVNT_WLAN_ASYNC_PING_REPORT. This event will carry the report + * structure: netapp_pingreport_args_t. This structure is filled in with ping + * results up till point of triggering API. + * + * netapp_pingreport_args_t: + * packets_sent - echo sent, + * packets_received - echo reply + * min_round_time - minimum round time, + * max_round_time - max round time, + * avg_round_time - average round time + * + * NOTE: When a ping operation is not active, the returned structure fields + * are 0. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + *****************************************************************************/ #ifndef CC3000_TINY_DRIVER void netapp_ping_report(void) { - uint8_t *ptr; - ptr = tSLInformation.pucTxCommandBuffer; - int8_t scRet; - - scRet = EFAIL; - - // Initiate a HCI command - hci_command_send(HCI_NETAPP_PING_REPORT, ptr, 0); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_NETAPP_PING_REPORT, &scRet); + uint8_t *ptr; + ptr = tSLInformation.pucTxCommandBuffer; + int8_t scRet; + + scRet = EFAIL; + + /* Initiate a HCI command */ + + hci_command_send(HCI_NETAPP_PING_REPORT, ptr, 0); + + /* Wait for command complete event */ + + SimpleLinkWaitEvent(HCI_NETAPP_PING_REPORT, &scRet); } #endif -//***************************************************************************** -// -//! netapp_ping_stop -//! -//! @param none -//! -//! @return On success, zero is returned. On error, -1 is returned. -//! -//! @brief Stop any ping request. -//! -//! -//***************************************************************************** +/****************************************************************************** + * Name: netapp_ping_stop + * + * Description: + * Stop any ping request. + * + * Input Parameters: + * None + * + * Returned Value: + * On success, zero is returned. On error, -1 is returned. + * + *****************************************************************************/ #ifndef CC3000_TINY_DRIVER long netapp_ping_stop(void) { - int8_t scRet; - uint8_t *ptr; - - scRet = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - - // Initiate a HCI command - hci_command_send(HCI_NETAPP_PING_STOP, ptr, 0); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_NETAPP_PING_STOP, &scRet); - - return(scRet); + int8_t scRet; + uint8_t *ptr; + + scRet = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + + /* Initiate a HCI command */ + + hci_command_send(HCI_NETAPP_PING_STOP, ptr, 0); + + /* Wait for command complete event */ + + SimpleLinkWaitEvent(HCI_NETAPP_PING_STOP, &scRet); + + return(scRet); } #endif -//***************************************************************************** -// -//! netapp_ipconfig -//! -//! @param[out] ipconfig This argument is a pointer to a -//! tNetappIpconfigRetArgs structure. This structure is -//! filled in with the network interface configuration. -//! tNetappIpconfigRetArgs:\n aucIP - ip address, -//! aucSubnetMask - mask, aucDefaultGateway - default -//! gateway address, aucDHCPServer - dhcp server address -//! aucDNSServer - dns server address, uaMacAddr - mac -//! address, uaSSID - connected AP ssid -//! -//! @return none -//! -//! @brief Obtain the CC3000 Network interface information. -//! Note that the information is available only after the WLAN -//! connection was established. Calling this function before -//! associated, will cause non-defined values to be returned. -//! -//! @note The function is useful for figuring out the IP Configuration of -//! the device when DHCP is used and for figuring out the SSID of -//! the Wireless network the device is associated with. -//! -//***************************************************************************** +/****************************************************************************** + * Name: netapp_ipconfig + * + * Description: + * Obtain the CC3000 Network interface information. Note that the information + * is available only after the WLAN connection was established. Calling this + * function before associated, will cause non-defined values to be returned. + * + * NOTE: The function is useful for figuring out the IP Configuration of the + * device when DHCP is used and for figuring out the SSID of the Wireless + * network the device is associated with. + * + * Input Parameters: + * ipconfig This argument is a pointer to a tNetappIpconfigRetArgs structure. + * This structure is filled in with the network interface configuration. + * + * tNetappIpconfigRetArgs: + * aucIP - ip address, + * aucSubnetMask - mask, + * aucDefaultGateway - default gateway address + * aucDHCPServer - dhcp server address + * aucDNSServer - dns server address + * uaMacAddr - mac + * address, uaSSID - connected AP ssid + * + * Returned Value: + * None + * + *****************************************************************************/ #ifndef CC3000_TINY_DRIVER -void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig ) +void netapp_ipconfig(tNetappIpconfigRetArgs * ipconfig) { - uint8_t *ptr; - - ptr = tSLInformation.pucTxCommandBuffer; - - // Initiate a HCI command - hci_command_send(HCI_NETAPP_IPCONFIG, ptr, 0); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_NETAPP_IPCONFIG, ipconfig ); - + uint8_t *ptr; + + ptr = tSLInformation.pucTxCommandBuffer; + + /* Initiate a HCI command */ + + hci_command_send(HCI_NETAPP_IPCONFIG, ptr, 0); + + /* Wait for command complete event */ + + SimpleLinkWaitEvent(HCI_NETAPP_IPCONFIG, ipconfig); } #else -void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig ) +void netapp_ipconfig(tNetappIpconfigRetArgs * ipconfig) { - } #endif -//***************************************************************************** -// -//! netapp_arp_flush -//! -//! @param none -//! -//! @return none -//! -//! @brief Flushes ARP table -//! -//***************************************************************************** +/****************************************************************************** + * Name: netapp_arp_flush + * + * Description: + * Flushes ARP table + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + *****************************************************************************/ #ifndef CC3000_TINY_DRIVER long netapp_arp_flush(void) { - int8_t scRet; - uint8_t *ptr; - - scRet = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - - // Initiate a HCI command - hci_command_send(HCI_NETAPP_ARP_FLUSH, ptr, 0); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_NETAPP_ARP_FLUSH, &scRet); - - return(scRet); + int8_t scRet; + uint8_t *ptr; + + scRet = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + + /* Initiate a HCI command */ + + hci_command_send(HCI_NETAPP_ARP_FLUSH, ptr, 0); + + /* Wait for command complete event */ + + SimpleLinkWaitEvent(HCI_NETAPP_ARP_FLUSH, &scRet); + + return scRet; } #endif -//***************************************************************************** -// -//! netapp_set_debug_level -//! -//! @param[in] level debug level. Bitwise [0-8], -//! 0(disable)or 1(enable).\n Bitwise map: 0 - Critical -//! message, 1 information message, 2 - core messages, 3 - -//! HCI messages, 4 - Network stack messages, 5 - wlan -//! messages, 6 - wlan driver messages, 7 - epprom messages, -//! 8 - general messages. Default: 0x13f. Saved: no -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Debug messages sent via the UART debug channel, this function -//! enable/disable the debug level -//! -//***************************************************************************** - +/****************************************************************************** + * Name: netapp_set_debug_level + * + * Description: + * Debug messages sent via the UART debug channel, this function enable/disable + * the debug level + * + * Input Parameters: + * level debug level. Bitwise [0-8], 0(disable)or 1(enable). + * Bitwise map: + * 0 - Critical message + * 1 - information message + * 2 - core messages + * 3 - HCI messages + * 4 - Network stack messages + * 5 - wlan messages + * 6 - wlan driver messages + * 7 - epprom messages, + * 8 - general messages. + * Default: 0x13f. Saved: no + * + * Returned Value: + * On success, zero is returned. On error, -1 is returned + * + *****************************************************************************/ #ifndef CC3000_TINY_DRIVER long netapp_set_debug_level(unsigned long ulLevel) { - int8_t scRet; - uint8_t *ptr, *args; + int8_t scRet; + uint8_t *ptr, *args; + + scRet = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_CMD); - scRet = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); + /* Fill in temporary command buffer */ - // - // Fill in temporary command buffer - // - args = UINT32_TO_STREAM(args, ulLevel); + args = UINT32_TO_STREAM(args, ulLevel); + /* Initiate a HCI command */ - // - // Initiate a HCI command - // - hci_command_send(HCI_NETAPP_SET_DEBUG_LEVEL, ptr, NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN); + hci_command_send(HCI_NETAPP_SET_DEBUG_LEVEL, ptr, NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN); - // - // Wait for command complete event - // - SimpleLinkWaitEvent(HCI_NETAPP_SET_DEBUG_LEVEL, &scRet); + /* Wait for command complete event */ - return(scRet); + SimpleLinkWaitEvent(HCI_NETAPP_SET_DEBUG_LEVEL, &scRet); + return scRet; } #endif diff --git a/nuttx/drivers/wireless/cc3000/nvmem.c b/nuttx/drivers/wireless/cc3000/nvmem.c index 779d4304e..4ab057f85 100644 --- a/nuttx/drivers/wireless/cc3000/nvmem.c +++ b/nuttx/drivers/wireless/cc3000/nvmem.c @@ -1,340 +1,350 @@ /***************************************************************************** -* -* nvmem.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ - -//***************************************************************************** -// -//! \addtogroup nvmem_api -//! @{ -// -//***************************************************************************** + * nvmem.c - CC3000 Host Driver Implementation. + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +/****************************************************************************** + * Included Files + ******************************************************************************/ #include #include + #include #include -#include +#include #include -//***************************************************************************** -// -// Prototypes for the structures for APIs. -// -//***************************************************************************** +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ -#define NVMEM_READ_PARAMS_LEN (12) -#define NVMEM_CREATE_PARAMS_LEN (8) +#define NVMEM_READ_PARAMS_LEN (12) +#define NVMEM_CREATE_PARAMS_LEN (8) #define NVMEM_WRITE_PARAMS_LEN (16) -//***************************************************************************** -// -//! nvmem_read -//! -//! @param ulFileId nvmem file id:\n -//! NVMEM_NVS_FILEID, NVMEM_NVS_SHADOW_FILEID, -//! NVMEM_WLAN_CONFIG_FILEID, NVMEM_WLAN_CONFIG_SHADOW_FILEID, -//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, -//! NVMEM_MAC_FILEID, NVMEM_FRONTEND_VARS_FILEID, -//! NVMEM_IP_CONFIG_FILEID, NVMEM_IP_CONFIG_SHADOW_FILEID, -//! NVMEM_BOOTLOADER_SP_FILEID, NVMEM_RM_FILEID, -//! and user files 12-15. -//! @param ulLength number of bytes to read -//! @param ulOffset ulOffset in file from where to read -//! @param buff output buffer pointer -//! -//! @return number of bytes read, otherwise error. -//! -//! @brief Reads data from the file referred by the ulFileId parameter. -//! Reads data from file ulOffset till length. Err if the file can't -//! be used, is invalid, or if the read is out of bounds. -//! -//***************************************************************************** - -signed long -nvmem_read(unsigned long ulFileId, unsigned long ulLength, unsigned long ulOffset, uint8_t *buff) +/****************************************************************************** + * Public Functions + ******************************************************************************/ +/****************************************************************************** + * Name: nvmem_read + * + * Description: + * Reads data from the file referred by the ulFileId parameter. Reads data + * from file ulOffset till length. Err if the file can't be used, is + * invalid, or if the read is out of bounds. + * + * Input Parameters: + * ulFileId nvmem file id: + * NVMEM_NVS_FILEID, NVMEM_NVS_SHADOW_FILEID, + * NVMEM_WLAN_CONFIG_FILEID, NVMEM_WLAN_CONFIG_SHADOW_FILEID, + * NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, + * NVMEM_MAC_FILEID, NVMEM_FRONTEND_VARS_FILEID, + * NVMEM_IP_CONFIG_FILEID, NVMEM_IP_CONFIG_SHADOW_FILEID, + * NVMEM_BOOTLOADER_SP_FILEID, NVMEM_RM_FILEID, + * and user files 12-15. + * ulLength number of bytes to read + * ulOffset ulOffset in file from where to read + * buff output buffer pointer + * + * Returned Value: + * Number of bytes read, otherwise error. + * + *****************************************************************************/ + +signed long nvmem_read(unsigned long ulFileId, unsigned long ulLength, + unsigned long ulOffset, uint8_t *buff) { - uint8_t ucStatus = 0xFF; - uint8_t *ptr; - uint8_t *args; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, ulFileId); - args = UINT32_TO_STREAM(args, ulLength); - args = UINT32_TO_STREAM(args, ulOffset); - - // Initiate a HCI command - hci_command_send(HCI_CMND_NVMEM_READ, ptr, NVMEM_READ_PARAMS_LEN); - SimpleLinkWaitEvent(HCI_CMND_NVMEM_READ, &ucStatus); - - // In case there is data - read it - even if an error code is returned - // Note: It is the user responsibility to ignore the data in case of an error code - - // Wait for the data in a synchronous way. Here we assume that the buffer is - // big enough to store also parameters of nvmem - - SimpleLinkWaitData(buff, 0, 0); - - return(ucStatus); + uint8_t ucStatus = 0xff; + uint8_t *ptr; + uint8_t *args; + + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_CMD); + + /* Fill in HCI packet structure */ + + args = UINT32_TO_STREAM(args, ulFileId); + args = UINT32_TO_STREAM(args, ulLength); + args = UINT32_TO_STREAM(args, ulOffset); + + /* Initiate a HCI command */ + + hci_command_send(HCI_CMND_NVMEM_READ, ptr, NVMEM_READ_PARAMS_LEN); + SimpleLinkWaitEvent(HCI_CMND_NVMEM_READ, &ucStatus); + + /* In case there is data - read it - even if an error code is returned + * Note: It is the user responsibility to ignore the data in case of an + * error code + */ + + /* Wait for the data in a synchronous way. Here we assume that the buffer is + * big enough to store also parameters of nvmem + */ + + SimpleLinkWaitData(buff, 0, 0); + + return ucStatus; } -//***************************************************************************** -// -//! nvmem_write -//! -//! @param ulFileId nvmem file id:\n -//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, -//! NVMEM_MAC_FILEID, NVMEM_BOOTLOADER_SP_FILEID, -//! and user files 12-15. -//! @param ulLength number of bytes to write -//! @param ulEntryOffset offset in file to start write operation from -//! @param buff data to write -//! -//! @return on success 0, error otherwise. -//! -//! @brief Write data to nvmem. -//! writes data to file referred by the ulFileId parameter. -//! Writes data to file ulOffset till ulLength.The file id will be -//! marked invalid till the write is done. The file entry doesn't -//! need to be valid - only allocated. -//! -//***************************************************************************** - -signed long -nvmem_write(unsigned long ulFileId, unsigned long ulLength, unsigned long - ulEntryOffset, uint8_t *buff) +/****************************************************************************** + * Name: nvmem_write + * + * Description: + * Write data to nvmem. Writes data to file referred by the ulFileId + * parameter. Writes data to file ulOffset till ulLength. The file id will be + * marked invalid till the write is done. The file entry doesn't need to be + * valid - only allocated. + * + * Input Parameters: + * ulFileId nvmem file id: + * NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, + * NVMEM_MAC_FILEID, NVMEM_BOOTLOADER_SP_FILEID, + * and user files 12-15. + * ulLength number of bytes to write + * ulEntryOffset offset in file to start write operation from + * buff data to write + * + * Returned Value: + * On success 0, error otherwise. + * + *****************************************************************************/ + +signed long nvmem_write(unsigned long ulFileId, unsigned long ulLength, + unsigned long ulEntryOffset, uint8_t *buff) { - long iRes; - uint8_t *ptr; - uint8_t *args; - - iRes = EFAIL; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, ulFileId); - args = UINT32_TO_STREAM(args, 12); - args = UINT32_TO_STREAM(args, ulLength); - args = UINT32_TO_STREAM(args, ulEntryOffset); - - memcpy((ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE + - NVMEM_WRITE_PARAMS_LEN),buff,ulLength); - - // Initiate a HCI command but it will come on data channel - hci_data_command_send(HCI_CMND_NVMEM_WRITE, ptr, NVMEM_WRITE_PARAMS_LEN, - ulLength); - - SimpleLinkWaitEvent(HCI_EVNT_NVMEM_WRITE, &iRes); - - return(iRes); -} + long iRes; + uint8_t *ptr; + uint8_t *args; + + iRes = EFAIL; + + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE); + + /* Fill in HCI packet structure */ + + args = UINT32_TO_STREAM(args, ulFileId); + args = UINT32_TO_STREAM(args, 12); + args = UINT32_TO_STREAM(args, ulLength); + args = UINT32_TO_STREAM(args, ulEntryOffset); + + memcpy((ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE + + NVMEM_WRITE_PARAMS_LEN),buff,ulLength); + + /* Initiate a HCI command but it will come on data channel */ + + hci_data_command_send(HCI_CMND_NVMEM_WRITE, ptr, NVMEM_WRITE_PARAMS_LEN, + ulLength); + + SimpleLinkWaitEvent(HCI_EVNT_NVMEM_WRITE, &iRes); + return iRes; +} -//***************************************************************************** -// -//! nvmem_set_mac_address -//! -//! @param mac mac address to be set -//! -//! @return on success 0, error otherwise. -//! -//! @brief Write MAC address to EEPROM. -//! mac address as appears over the air (OUI first) -//! -//***************************************************************************** +/****************************************************************************** + * Name: nvmem_set_mac_address + * + * Description: + * Write MAC address to EEPROM. mac address as appears over the air (OUI + * first) + * + * Input Parameters: + * mac mac address to be set + * + * Returned Value: + * On success 0, error otherwise. + * + *****************************************************************************/ uint8_t nvmem_set_mac_address(uint8_t *mac) { - return nvmem_write(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac); + return nvmem_write(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac); } -//***************************************************************************** -// -//! nvmem_get_mac_address -//! -//! @param[out] mac mac address -//! -//! @return on success 0, error otherwise. -//! -//! @brief Read MAC address from EEPROM. -//! mac address as appears over the air (OUI first) -//! -//***************************************************************************** +/****************************************************************************** + * Name: nvmem_get_mac_address + * + * Description: + * Read MAC address from EEPROM. mac address as appears over the air (OUI + * first) + * + * Input Parameters: + * mac mac address + * + * Returned Value: + * On success 0, error otherwise. + * + *****************************************************************************/ uint8_t nvmem_get_mac_address(uint8_t *mac) { - return nvmem_read(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac); + return nvmem_read(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac); } -//***************************************************************************** -// -//! nvmem_write_patch -//! -//! @param ulFileId nvmem file id:\n -//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, -//! @param spLength number of bytes to write -//! @param spData SP data to write -//! -//! @return on success 0, error otherwise. -//! -//! @brief program a patch to a specific file ID. -//! The SP data is assumed to be organized in 2-dimensional. -//! Each line is SP_PORTION_SIZE bytes long. Actual programming is -//! applied in SP_PORTION_SIZE bytes portions. -//! -//***************************************************************************** - -uint8_t nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, const uint8_t *spData) +/****************************************************************************** + * Name: nvmem_write_patch + * + * Description: + * Program a patch to a specific file ID. The SP data is assumed to be + * organized in 2-dimensional. Each line is SP_PORTION_SIZE bytes long. + * Actual programming is applied in SP_PORTION_SIZE bytes portions. + * + * Input Parameters: + * ulFileId nvmem file id: + * NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, + * spLength number of bytes to write + * spData SP data to write + * + * Returned Value: + * On success 0, error otherwise. + * + *****************************************************************************/ + +uint8_t nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, + const uint8_t *spData) { - uint8_t status = 0; - uint16_t offset = 0; - uint8_t* spDataPtr = (uint8_t*)spData; - - while ((status == 0) && (spLength >= SP_PORTION_SIZE)) - { - status = nvmem_write(ulFileId, SP_PORTION_SIZE, offset, spDataPtr); - offset += SP_PORTION_SIZE; - spLength -= SP_PORTION_SIZE; - spDataPtr += SP_PORTION_SIZE; - } - - if (status !=0) - { - // NVMEM error occurred - return status; - } - - if (spLength != 0) - { - // if reached here, a reminder is left - status = nvmem_write(ulFileId, spLength, offset, spDataPtr); - } - - return status; + uint8_t status = 0; + uint16_t offset = 0; + uint8_t *spDataPtr = (uint8_t*)spData; + + while ((status == 0) && (spLength >= SP_PORTION_SIZE)) + { + status = nvmem_write(ulFileId, SP_PORTION_SIZE, offset, spDataPtr); + offset += SP_PORTION_SIZE; + spLength -= SP_PORTION_SIZE; + spDataPtr += SP_PORTION_SIZE; + } + + if (status !=0) + { + /* NVMEM error occurred */ + + return status; + } + + if (spLength != 0) + { + /* if reached here, a reminder is left */ + + status = nvmem_write(ulFileId, spLength, offset, spDataPtr); + } + + return status; } -//***************************************************************************** -// -//! nvmem_read_sp_version -//! -//! @param[out] patchVer first number indicates package ID and the second -//! number indicates package build number -//! -//! @return on success 0, error otherwise. -//! -//! @brief Read patch version. read package version (WiFi FW patch, -//! driver-supplicant-NS patch, bootloader patch) -//! -//***************************************************************************** +/****************************************************************************** + * Name: nvmem_read_sp_version + * + * Description: + * Read patch version. read package version (WiFi FW patch, + * driver-supplicant-NS patch, bootloader patch) + * + * Input Parameters: + * patchVer first number indicates package ID and the second + * number indicates package build number + * + * Returned Value: + * On success 0, error otherwise. + * + *****************************************************************************/ #ifndef CC3000_TINY_DRIVER uint8_t nvmem_read_sp_version(uint8_t* patchVer) { - uint8_t *ptr; - // 1st byte is the status and the rest is the SP version - uint8_t retBuf[5]; - - ptr = tSLInformation.pucTxCommandBuffer; - - // Initiate a HCI command, no args are required - hci_command_send(HCI_CMND_READ_SP_VERSION, ptr, 0); - SimpleLinkWaitEvent(HCI_CMND_READ_SP_VERSION, retBuf); - - // package ID - *patchVer = retBuf[3]; - // package build number - *(patchVer+1) = retBuf[4]; - - return(retBuf[0]); + uint8_t *ptr; + /* 1st byte is the status and the rest is the SP version */ + uint8_t retBuf[5]; + + ptr = tSLInformation.pucTxCommandBuffer; + + /* Initiate a HCI command, no args are required */ + + hci_command_send(HCI_CMND_READ_SP_VERSION, ptr, 0); + SimpleLinkWaitEvent(HCI_CMND_READ_SP_VERSION, retBuf); + + /* Package ID */ + + *patchVer = retBuf[3]; + + /* Package build number */ + + *(patchVer+1) = retBuf[4]; + + return retBuf[0]; } #endif -//***************************************************************************** -// -//! nvmem_create_entry -//! -//! @param ulFileId nvmem file Id:\n -//! * NVMEM_AES128_KEY_FILEID: 12 -//! * NVMEM_SHARED_MEM_FILEID: 13 -//! * and fileIDs 14 and 15 -//! @param ulNewLen entry ulLength -//! -//! @return on success 0, error otherwise. -//! -//! @brief Create new file entry and allocate space on the NVMEM. -//! Applies only to user files. -//! Modify the size of file. -//! If the entry is unallocated - allocate it to size -//! ulNewLen (marked invalid). -//! If it is allocated then deallocate it first. -//! To just mark the file as invalid without resizing - -//! set ulNewLen=0. -//! -//***************************************************************************** - -signed long -nvmem_create_entry(unsigned long ulFileId, unsigned long ulNewLen) +/****************************************************************************** + * Name: nvmem_create_entry + * + * Description: + * Create new file entry and allocate space on the NVMEM. Applies only to + * user files. Modify the size of file. If the entry is unallocated - + * allocate it to size ulNewLen (marked invalid). If it is allocated then + * deallocate it first. To just mark the file as invalid without resizing - + * Set ulNewLen=0. + * + * Input Parameters: + * ulFileId nvmem file Id: + * * NVMEM_AES128_KEY_FILEID: 12 + * * NVMEM_SHARED_MEM_FILEID: 13 + * * and fileIDs 14 and 15 + * ulNewLen entry ulLength + * + * Returned Value: + * On success 0, error otherwise. + * + *****************************************************************************/ + +signed long nvmem_create_entry(unsigned long ulFileId, unsigned long ulNewLen) { - uint8_t *ptr; - uint8_t *args; - uint16_t retval; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, ulFileId); - args = UINT32_TO_STREAM(args, ulNewLen); - - // Initiate a HCI command - hci_command_send(HCI_CMND_NVMEM_CREATE_ENTRY,ptr, NVMEM_CREATE_PARAMS_LEN); - - SimpleLinkWaitEvent(HCI_CMND_NVMEM_CREATE_ENTRY, &retval); - - return(retval); -} + uint8_t *ptr; + uint8_t *args; + uint16_t retval; + + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_CMD); + + /*( Fill in HCI packet structure */ + args = UINT32_TO_STREAM(args, ulFileId); + args = UINT32_TO_STREAM(args, ulNewLen); + /* Initiate a HCI command */ -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** + hci_command_send(HCI_CMND_NVMEM_CREATE_ENTRY,ptr, NVMEM_CREATE_PARAMS_LEN); + SimpleLinkWaitEvent(HCI_CMND_NVMEM_CREATE_ENTRY, &retval); + + return retval; +} diff --git a/nuttx/drivers/wireless/cc3000/socket.c b/nuttx/drivers/wireless/cc3000/socket.c index 8e6c873ff..878065b39 100644 --- a/nuttx/drivers/wireless/cc3000/socket.c +++ b/nuttx/drivers/wireless/cc3000/socket.c @@ -1,1169 +1,1244 @@ /***************************************************************************** -* -* socket.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ - -//***************************************************************************** -// -//! \addtogroup socket_api -//! @{ -// -//***************************************************************************** + * socket.c - CC3000 Host Driver Implementation. + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +/***************************************************************************** + * Included Files + *****************************************************************************/ #include #include #include #include -#include +#include #include #include +/***************************************************************************** + * Pre-processor Definitions + *****************************************************************************/ +/* Enable this flag if and only if you must comply with BSD socket close() + * function + */ -//Enable this flag if and only if you must comply with BSD socket -//close() function #ifdef _API_USE_BSD_CLOSE - #define close(sd) closesocket(sd) +# define close(sd) closesocket(sd) #endif -//Enable this flag if and only if you must comply with BSD socket read() and -//write() functions +/* Enable this flag if and only if you must comply with BSD socket read() and + * write() functions + */ + #ifdef _API_USE_BSD_READ_WRITE - #define read(sd, buf, len, flags) recv(sd, buf, len, flags) - #define write(sd, buf, len, flags) send(sd, buf, len, flags) +# define read(sd, buf, len, flags) recv(sd, buf, len, flags) +# define write(sd, buf, len, flags) send(sd, buf, len, flags) #endif -#define SOCKET_OPEN_PARAMS_LEN (12) -#define SOCKET_CLOSE_PARAMS_LEN (4) -#define SOCKET_ACCEPT_PARAMS_LEN (4) -#define SOCKET_BIND_PARAMS_LEN (20) -#define SOCKET_LISTEN_PARAMS_LEN (8) -#define SOCKET_GET_HOST_BY_NAME_PARAMS_LEN (9) -#define SOCKET_CONNECT_PARAMS_LEN (20) -#define SOCKET_SELECT_PARAMS_LEN (44) -#define SOCKET_SET_SOCK_OPT_PARAMS_LEN (20) -#define SOCKET_GET_SOCK_OPT_PARAMS_LEN (12) -#define SOCKET_RECV_FROM_PARAMS_LEN (12) -#define SOCKET_SENDTO_PARAMS_LEN (24) -#define SOCKET_MDNS_ADVERTISE_PARAMS_LEN (12) +#define SOCKET_OPEN_PARAMS_LEN (12) +#define SOCKET_CLOSE_PARAMS_LEN (4) +#define SOCKET_ACCEPT_PARAMS_LEN (4) +#define SOCKET_BIND_PARAMS_LEN (20) +#define SOCKET_LISTEN_PARAMS_LEN (8) +#define SOCKET_GET_HOST_BY_NAME_PARAMS_LEN (9) +#define SOCKET_CONNECT_PARAMS_LEN (20) +#define SOCKET_SELECT_PARAMS_LEN (44) +#define SOCKET_SET_SOCK_OPT_PARAMS_LEN (20) +#define SOCKET_GET_SOCK_OPT_PARAMS_LEN (12) +#define SOCKET_RECV_FROM_PARAMS_LEN (12) +#define SOCKET_SENDTO_PARAMS_LEN (24) +#define SOCKET_MDNS_ADVERTISE_PARAMS_LEN (12) +/* The legnth of arguments for the SEND command: sd + buff_offset + len + flags, + * while size of each parameter is 32 bit - so the total length is 16 bytes; + */ -// The legnth of arguments for the SEND command: sd + buff_offset + len + flags, -// while size of each parameter is 32 bit - so the total length is 16 bytes; +#define HCI_CMND_SEND_ARG_LENGTH (16) -#define HCI_CMND_SEND_ARG_LENGTH (16) +#define SELECT_TIMEOUT_MIN_MICRO_SECONDS 5000 +#define HEADERS_SIZE_DATA (SPI_HEADER_SIZE + 5) -#define SELECT_TIMEOUT_MIN_MICRO_SECONDS 5000 +#define SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE \ + (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE) + +#define MDNS_DEVICE_SERVICE_MAX_LENGTH (32) -#define HEADERS_SIZE_DATA (SPI_HEADER_SIZE + 5) - -#define SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE) - -#define MDNS_DEVICE_SERVICE_MAX_LENGTH (32) - - -//***************************************************************************** -// -//! HostFlowControlConsumeBuff -//! -//! @param sd socket descriptor -//! -//! @return 0 in case there are buffers available, -//! -1 in case of bad socket -//! -2 if there are no free buffers present (only when -//! SEND_NON_BLOCKING is enabled) -//! -//! @brief if SEND_NON_BLOCKING not define - block until have free buffer -//! becomes available, else return immediately with correct status -//! regarding the buffers available. -// -//***************************************************************************** -int -HostFlowControlConsumeBuff(int sd) +/***************************************************************************** + * Public Functions + *****************************************************************************/ +/***************************************************************************** + * Name: HostFlowControlConsumeBuff + * + * Input Parameters: + * sd socket descriptor + * + * Returned Value: + * 0 in case there are buffers available, + * -1 in case of bad socket + * -2 if there are no free buffers present (only when + * SEND_NON_BLOCKING is enabled) + * + * Decription: + * if SEND_NON_BLOCKING not define - block until have free buffer + * becomes available, else return immediately with correct status + * regarding the buffers available. + * + *****************************************************************************/ + +int HostFlowControlConsumeBuff(int sd) { #ifndef SEND_NON_BLOCKING - /* wait in busy loop */ - do - { - // In case last transmission failed then we will return the last failure - // reason here. - // Note that the buffer will not be allocated in this case - if (tSLInformation.slTransmitDataError != 0) - { - errno = tSLInformation.slTransmitDataError; - tSLInformation.slTransmitDataError = 0; - return errno; - } - - if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd)) - return -1; - } while(0 == tSLInformation.usNumberOfFreeBuffers); - - tSLInformation.usNumberOfFreeBuffers--; - - return 0; + /* Wait in busy loop */ + + do + { + /* In case last transmission failed then we will return the last failure + * reason here. + * Note that the buffer will not be allocated in this case + */ + + if (tSLInformation.slTransmitDataError != 0) + { + errno = tSLInformation.slTransmitDataError; + tSLInformation.slTransmitDataError = 0; + return errno; + } + + if (SOCKET_STATUS_ACTIVE != get_socket_active_status(sd)) + { + return -1; + } + } while (0 == tSLInformation.usNumberOfFreeBuffers); + + tSLInformation.usNumberOfFreeBuffers--; + + return 0; #else - - // In case last transmission failed then we will return the last failure - // reason here. - // Note that the buffer will not be allocated in this case - if (tSLInformation.slTransmitDataError != 0) - { - errno = tSLInformation.slTransmitDataError; - tSLInformation.slTransmitDataError = 0; - return errno; - } - if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd)) - return -1; - - //If there are no available buffers, return -2. It is recommended to use - // select or receive to see if there is any buffer occupied with received data - // If so, call receive() to release the buffer. - if(0 == tSLInformation.usNumberOfFreeBuffers) - { - return -2; - } - else - { - tSLInformation.usNumberOfFreeBuffers--; - return 0; - } + + /* In case last transmission failed then we will return the last failure + * reason here. + * Note that the buffer will not be allocated in this case + */ + + if (tSLInformation.slTransmitDataError != 0) + { + errno = tSLInformation.slTransmitDataError; + tSLInformation.slTransmitDataError = 0; + return errno; + } + + if (SOCKET_STATUS_ACTIVE != get_socket_active_status(sd)) + { + return -1; + } + + /* If there are no available buffers, return -2. It is recommended to use + * select or receive to see if there is any buffer occupied with received data + * If so, call receive() to release the buffer. + */ + + if (0 == tSLInformation.usNumberOfFreeBuffers) + { + return -2; + } + else + { + tSLInformation.usNumberOfFreeBuffers--; + return 0; + } #endif } -//***************************************************************************** -// -//! socket -//! -//! @param domain selects the protocol family which will be used for -//! communication. On this version only AF_INET is supported -//! @param type specifies the communication semantics. On this version -//! only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW are supported -//! @param protocol specifies a particular protocol to be used with the -//! socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are -//! supported. -//! -//! @return On success, socket handle that is used for consequent socket -//! operations. On error, -1 is returned. -//! -//! @brief create an endpoint for communication -//! The socket function creates a socket that is bound to a specific -//! transport service provider. This function is called by the -//! application layer to obtain a socket handle. -// -//***************************************************************************** - -int -socket(long domain, long type, long protocol) +/***************************************************************************** + * Name: socket + * + * Input Parameters: + * domain selects the protocol family which will be used for + * communication. On this version only AF_INET is supported + * type specifies the communication semantics. On this version + * only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW are supported + * protocol specifies a particular protocol to be used with the + * socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are + * supported. + * + * Returned Value: + * On success, socket handle that is used for consequent socket + * operations. On error, -1 is returned. + * + * Decription: + * create an endpoint for communication + * The socket function creates a socket that is bound to a specific + * transport service provider. This function is called by the + * application layer to obtain a socket handle. + * + *****************************************************************************/ + +int socket(long domain, long type, long protocol) { - long ret; - uint8_t *ptr, *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, domain); - args = UINT32_TO_STREAM(args, type); - args = UINT32_TO_STREAM(args, protocol); - - // Initiate a HCI command - hci_command_send(HCI_CMND_SOCKET, ptr, SOCKET_OPEN_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_SOCKET, &ret); - - // Process the event - errno = ret; - - set_socket_active_status(ret, SOCKET_STATUS_ACTIVE); - - return(ret); + long ret; + uint8_t *ptr, *args; + + ret = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_CMD); + + /* Fill in HCI packet structure */ + + args = UINT32_TO_STREAM(args, domain); + args = UINT32_TO_STREAM(args, type); + args = UINT32_TO_STREAM(args, protocol); + + /* Initiate a HCI command */ + + hci_command_send(HCI_CMND_SOCKET, ptr, SOCKET_OPEN_PARAMS_LEN); + + /* Since we are in blocking state - wait for event complete */ + + SimpleLinkWaitEvent(HCI_CMND_SOCKET, &ret); + + /* Process the event */ + + errno = ret; + + set_socket_active_status(ret, SOCKET_STATUS_ACTIVE); + + return ret; } -//***************************************************************************** -// -//! closesocket -//! -//! @param sd socket handle. -//! -//! @return On success, zero is returned. On error, -1 is returned. -//! -//! @brief The socket function closes a created socket. -// -//***************************************************************************** - -long -closesocket(long sd) +/***************************************************************************** + * Name: closesocket + * + * Input Parameters: + * sd socket handle. + * + * Returned Value: + * On success, zero is returned. On error, -1 is returned. + * + * Decription: + * The socket function closes a created socket. + * + *****************************************************************************/ + +long closesocket(long sd) { - long ret; - uint8_t *ptr, *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, sd); - - // Initiate a HCI command - hci_command_send(HCI_CMND_CLOSE_SOCKET, - ptr, SOCKET_CLOSE_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_CLOSE_SOCKET, &ret); - errno = ret; - - // since 'close' call may result in either OK (and then it closed) or error - // mark this socket as invalid - set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); - - return(ret); + long ret; + uint8_t *ptr, *args; + + ret = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_CMD); + + /* Fill in HCI packet structure */ + + args = UINT32_TO_STREAM(args, sd); + + /* Initiate a HCI command */ + + hci_command_send(HCI_CMND_CLOSE_SOCKET, + ptr, SOCKET_CLOSE_PARAMS_LEN); + + /* Since we are in blocking state - wait for event complete */ + + SimpleLinkWaitEvent(HCI_CMND_CLOSE_SOCKET, &ret); + errno = ret; + + /* Since 'close' call may result in either OK (and then it closed) or error + * mark this socket as invalid + */ + + set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); + + return ret; } -//***************************************************************************** -// -//! accept -//! -//! @param[in] sd socket descriptor (handle) -//! @param[out] addr the argument addr is a pointer to a sockaddr structure -//! This structure is filled in with the address of the -//! peer socket, as known to the communications layer. -//! determined. The exact format of the address returned -//! addr is by the socket's address sockaddr. -//! On this version only AF_INET is supported. -//! This argument returns in network order. -//! @param[out] addrlen the addrlen argument is a value-result argument: -//! it should initially contain the size of the structure -//! pointed to by addr. -//! -//! @return For socket in blocking mode: -//! On success, socket handle. on failure negative -//! For socket in non-blocking mode: -//! - On connection establishment, socket handle -//! - On connection pending, SOC_IN_PROGRESS (-2) -//! - On failure, SOC_ERROR (-1) -//! -//! @brief accept a connection on a socket: -//! This function is used with connection-based socket types -//! (SOCK_STREAM). It extracts the first connection request on the -//! queue of pending connections, creates a new connected socket, and -//! returns a new file descriptor referring to that socket. -//! The newly created socket is not in the listening state. -//! The original socket sd is unaffected by this call. -//! The argument sd is a socket that has been created with socket(), -//! bound to a local address with bind(), and is listening for -//! connections after a listen(). The argument addr is a pointer -//! to a sockaddr structure. This structure is filled in with the -//! address of the peer socket, as known to the communications layer. -//! The exact format of the address returned addr is determined by the -//! socket's address family. The addrlen argument is a value-result -//! argument: it should initially contain the size of the structure -//! pointed to by addr, on return it will contain the actual -//! length (in bytes) of the address returned. -//! -//! @sa socket ; bind ; listen -// -//***************************************************************************** - -long -accept(long sd, sockaddr *addr, socklen_t *addrlen) +/***************************************************************************** + * Name: accept + * + * Input Parameters: + * sd socket descriptor (handle) + * addr the argument addr is a pointer to a sockaddr structure + * This structure is filled in with the address of the + * peer socket, as known to the communications layer. + * determined. The exact format of the address returned + * addr is by the socket's address sockaddr. + * On this version only AF_INET is supported. + * This argument returns in network order. + * addrlen The addrlen argument is a value-result argument: + * it should initially contain the size of the structure + * pointed to by addr. + * + * Returned Value: + * For socket in blocking mode: + * On success, socket handle. on failure negative + * For socket in non-blocking mode: + * - On connection establishment, socket handle + * - On connection pending, SOC_IN_PROGRESS (-2) + * - On failure, SOC_ERROR (-1) + * + * Decription: + * accept a connection on a socket: + * This function is used with connection-based socket types + * (SOCK_STREAM). It extracts the first connection request on the + * queue of pending connections, creates a new connected socket, and + * returns a new file descriptor referring to that socket. + * The newly created socket is not in the listening state. + * The original socket sd is unaffected by this call. + * The argument sd is a socket that has been created with socket(), + * bound to a local address with bind(), and is listening for + * connections after a listen(). The argument addr is a pointer + * to a sockaddr structure. This structure is filled in with the + * address of the peer socket, as known to the communications layer. + * The exact format of the address returned addr is determined by the + * socket's address family. The addrlen argument is a value-result + * argument: it should initially contain the size of the structure + * pointed to by addr, on return it will contain the actual + * length (in bytes) of the address returned. + * + *****************************************************************************/ + +long accept(long sd, sockaddr *addr, socklen_t *addrlen) { - long ret; - uint8_t *ptr, *args; - tBsdReturnParams tAcceptReturnArguments; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - - // Initiate a HCI command - hci_command_send(HCI_CMND_ACCEPT, - ptr, SOCKET_ACCEPT_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_ACCEPT, &tAcceptReturnArguments); - - - // need specify return parameters!!! - memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN); - *addrlen = ASIC_ADDR_LEN; - errno = tAcceptReturnArguments.iStatus; - ret = errno; - - // if succeeded, iStatus = new socket descriptor. otherwise - error number - if(M_IS_VALID_SD(ret)) - { - set_socket_active_status(ret, SOCKET_STATUS_ACTIVE); - } - else - { - set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); - } - - return(ret); + long ret; + uint8_t *ptr, *args; + tBsdReturnParams tAcceptReturnArguments; + + ret = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_CMD); + + /* Fill in temporary command buffer */ + + args = UINT32_TO_STREAM(args, sd); + + /* Initiate a HCI command */ + + hci_command_send(HCI_CMND_ACCEPT, + ptr, SOCKET_ACCEPT_PARAMS_LEN); + + /* Since we are in blocking state - wait for event complete */ + + SimpleLinkWaitEvent(HCI_CMND_ACCEPT, &tAcceptReturnArguments); + + + /* Need specify return parameters!!! */ + + memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN); + *addrlen = ASIC_ADDR_LEN; + errno = tAcceptReturnArguments.iStatus; + ret = errno; + + /* if succeeded, iStatus = new socket descriptor. otherwise - error number */ + + if (M_IS_VALID_SD(ret)) + { + set_socket_active_status(ret, SOCKET_STATUS_ACTIVE); + } + else + { + set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); + } + + return ret; } -//***************************************************************************** -// -//! bind -//! -//! @param[in] sd socket descriptor (handle) -//! @param[out] addr specifies the destination address. On this version -//! only AF_INET is supported. -//! @param[out] addrlen contains the size of the structure pointed to by addr. -//! -//! @return On success, zero is returned. On error, -1 is returned. -//! -//! @brief assign a name to a socket -//! This function gives the socket the local address addr. -//! addr is addrlen bytes long. Traditionally, this is called when a -//! socket is created with socket, it exists in a name space (address -//! family) but has no name assigned. -//! It is necessary to assign a local address before a SOCK_STREAM -//! socket may receive connections. -//! -//! @sa socket ; accept ; listen -// -//***************************************************************************** - -long -bind(long sd, const sockaddr *addr, long addrlen) +/***************************************************************************** + * Name: bind + * + * Input Parameters: + * sd socket descriptor (handle) + * addr specifies the destination address. On this version + * only AF_INET is supported. + * addrlen contains the size of the structure pointed to by addr. + * + * Returned Value: + * On success, zero is returned. On error, -1 is returned. + * + * Decription: + * assign a name to a socket + * This function gives the socket the local address addr. + * addr is addrlen bytes long. Traditionally, this is called when a + * socket is created with socket, it exists in a name space (address + * family) but has no name assigned. + * It is necessary to assign a local address before a SOCK_STREAM + * socket may receive connections. + * + *****************************************************************************/ + +long bind(long sd, const sockaddr *addr, long addrlen) { - long ret; - uint8_t *ptr, *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - addrlen = ASIC_ADDR_LEN; - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, 0x00000008); - args = UINT32_TO_STREAM(args, addrlen); - ARRAY_TO_STREAM(args, ((uint8_t *)addr), addrlen); - - // Initiate a HCI command - hci_command_send(HCI_CMND_BIND, - ptr, SOCKET_BIND_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_BIND, &ret); - - errno = ret; - - return(ret); + long ret; + uint8_t *ptr, *args; + + ret = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_CMD); + + addrlen = ASIC_ADDR_LEN; + + /* Fill in temporary command buffer */ + + args = UINT32_TO_STREAM(args, sd); + args = UINT32_TO_STREAM(args, 0x00000008); + args = UINT32_TO_STREAM(args, addrlen); + ARRAY_TO_STREAM(args, ((uint8_t *)addr), addrlen); + + /* Initiate a HCI command */ + + hci_command_send(HCI_CMND_BIND, + ptr, SOCKET_BIND_PARAMS_LEN); + + /* Since we are in blocking state - wait for event complete */ + + SimpleLinkWaitEvent(HCI_CMND_BIND, &ret); + + errno = ret; + + return ret; } -//***************************************************************************** -// -//! listen -//! -//! @param[in] sd socket descriptor (handle) -//! @param[in] backlog specifies the listen queue depth. On this version -//! backlog is not supported. -//! @return On success, zero is returned. On error, -1 is returned. -//! -//! @brief listen for connections on a socket -//! The willingness to accept incoming connections and a queue -//! limit for incoming connections are specified with listen(), -//! and then the connections are accepted with accept. -//! The listen() call applies only to sockets of type SOCK_STREAM -//! The backlog parameter defines the maximum length the queue of -//! pending connections may grow to. -//! -//! @sa socket ; accept ; bind -//! -//! @note On this version, backlog is not supported -// -//***************************************************************************** - -long -listen(long sd, long backlog) +/***************************************************************************** + * Name: listen + * + * Input Parameters: + * sd socket descriptor (handle) + * backlog specifies the listen queue depth. On this version + * backlog is not supported. + * + * Returned Value: + * On success, zero is returned. On error, -1 is returned. + * + * Decription: + * listen for connections on a socket + * The willingness to accept incoming connections and a queue + * limit for incoming connections are specified with listen(), + * and then the connections are accepted with accept. + * The listen() call applies only to sockets of type SOCK_STREAM + * The backlog parameter defines the maximum length the queue of + * pending connections may grow to. + * + * NOTE: On this version, backlog is not supported + * + *****************************************************************************/ + +long listen(long sd, long backlog) { - long ret; - uint8_t *ptr, *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, backlog); - - // Initiate a HCI command - hci_command_send(HCI_CMND_LISTEN, - ptr, SOCKET_LISTEN_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_LISTEN, &ret); - errno = ret; - - return(ret); + long ret; + uint8_t *ptr, *args; + + ret = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_CMD); + + /* Fill in temporary command buffer */ + + args = UINT32_TO_STREAM(args, sd); + args = UINT32_TO_STREAM(args, backlog); + + /* Initiate a HCI command */ + + hci_command_send(HCI_CMND_LISTEN, + ptr, SOCKET_LISTEN_PARAMS_LEN); + + /* Since we are in blocking state - wait for event complete */ + + SimpleLinkWaitEvent(HCI_CMND_LISTEN, &ret); + errno = ret; + + return ret; } -//***************************************************************************** -// -//! gethostbyname -//! -//! @param[in] hostname host name -//! @param[in] usNameLen name length -//! @param[out] out_ip_addr This parameter is filled in with host IP address. -//! In case that host name is not resolved, -//! out_ip_addr is zero. -//! @return On success, positive is returned. On error, negative is returned -//! -//! @brief Get host IP by name. Obtain the IP Address of machine on network, -//! by its name. -//! -//! @note On this version, only blocking mode is supported. Also note that -//! the function requires DNS server to be configured prior to its usage. -// -//***************************************************************************** +/***************************************************************************** + * Name: gethostbyname + * + * Input Parameters: + * hostname host name + * usNameLen name length + * out_ip_addr This parameter is filled in with host IP address. + * In case that host name is not resolved, + * out_ip_addr is zero. + * + * Returned Value: + * On success, positive is returned. On error, negative is returned + * + * Decription: + * Get host IP by name. Obtain the IP Address of machine on network, + * by its name. + * + * NOTE: On this version, only blocking mode is supported. Also note that + * the function requires DNS server to be configured prior to its + * usage. + * + *****************************************************************************/ #ifndef CC3000_TINY_DRIVER -int -gethostbyname(char * hostname, uint16_t usNameLen, - unsigned long* out_ip_addr) +int gethostbyname(char * hostname, uint16_t usNameLen, unsigned long* out_ip_addr) { - tBsdGethostbynameParams ret; - uint8_t *ptr, *args; - - errno = EFAIL; - - if (usNameLen > HOSTNAME_MAX_LENGTH) - { - return errno; - } - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, 8); - args = UINT32_TO_STREAM(args, usNameLen); - ARRAY_TO_STREAM(args, hostname, usNameLen); - - // Initiate a HCI command - hci_command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN - + usNameLen - 1); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_EVNT_BSD_GETHOSTBYNAME, &ret); - - errno = ret.retVal; - - (*((long*)out_ip_addr)) = ret.outputAddress; - - return (errno); - + tBsdGethostbynameParams ret; + uint8_t *ptr, *args; + + errno = EFAIL; + + if (usNameLen > HOSTNAME_MAX_LENGTH) + { + return errno; + } + + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); + + /* Fill in HCI packet structure */ + + args = UINT32_TO_STREAM(args, 8); + args = UINT32_TO_STREAM(args, usNameLen); + ARRAY_TO_STREAM(args, hostname, usNameLen); + + /* Initiate a HCI command */ + + hci_command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN + + usNameLen - 1); + + /* Since we are in blocking state - wait for event complete */ + + SimpleLinkWaitEvent(HCI_EVNT_BSD_GETHOSTBYNAME, &ret); + + errno = ret.retVal; + + (*((long*)out_ip_addr)) = ret.outputAddress; + + return errno; } #endif -//***************************************************************************** -// -//! connect -//! -//! @param[in] sd socket descriptor (handle) -//! @param[in] addr specifies the destination addr. On this version -//! only AF_INET is supported. -//! @param[out] addrlen contains the size of the structure pointed to by addr -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief initiate a connection on a socket -//! Function connects the socket referred to by the socket descriptor -//! sd, to the address specified by addr. The addrlen argument -//! specifies the size of addr. The format of the address in addr is -//! determined by the address space of the socket. If it is of type -//! SOCK_DGRAM, this call specifies the peer with which the socket is -//! to be associated; this address is that to which datagrams are to be -//! sent, and the only address from which datagrams are to be received. -//! If the socket is of type SOCK_STREAM, this call attempts to make a -//! connection to another socket. The other socket is specified by -//! address, which is an address in the communications space of the -//! socket. Note that the function implements only blocking behavior -//! thus the caller will be waiting either for the connection -//! establishment or for the connection establishment failure. -//! -//! @sa socket -// -//***************************************************************************** - -long -connect(long sd, const sockaddr *addr, long addrlen) +/***************************************************************************** + * Name: connect + * + * Input Parameters: + * sd socket descriptor (handle) + * addr specifies the destination addr. On this version + * only AF_INET is supported. + * addrlen contains the size of the structure pointed to by addr + * + * Returned Value: + * On success, zero is returned. On error, -1 is returned + * + * Decription: + * initiate a connection on a socket + * Function connects the socket referred to by the socket descriptor + * sd, to the address specified by addr. The addrlen argument + * specifies the size of addr. The format of the address in addr is + * determined by the address space of the socket. If it is of type + * SOCK_DGRAM, this call specifies the peer with which the socket is + * to be associated; this address is that to which datagrams are to be + * sent, and the only address from which datagrams are to be received. + * If the socket is of type SOCK_STREAM, this call attempts to make a + * connection to another socket. The other socket is specified by + * address, which is an address in the communications space of the + * socket. Note that the function implements only blocking behavior + * thus the caller will be waiting either for the connection + * establishment or for the connection establishment failure. + * + *****************************************************************************/ + +long connect(long sd, const sockaddr *addr, long addrlen) { - long int ret; - uint8_t *ptr, *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); - addrlen = 8; - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, 0x00000008); - args = UINT32_TO_STREAM(args, addrlen); - ARRAY_TO_STREAM(args, ((uint8_t *)addr), addrlen); - - // Initiate a HCI command - hci_command_send(HCI_CMND_CONNECT, - ptr, SOCKET_CONNECT_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_CONNECT, &ret); - - errno = ret; - - return((long)ret); + long int ret; + uint8_t *ptr, *args; + + ret = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); + addrlen = 8; + + /* Fill in temporary command buffer */ + + args = UINT32_TO_STREAM(args, sd); + args = UINT32_TO_STREAM(args, 0x00000008); + args = UINT32_TO_STREAM(args, addrlen); + ARRAY_TO_STREAM(args, ((uint8_t *)addr), addrlen); + + /* Initiate a HCI command */ + + hci_command_send(HCI_CMND_CONNECT, + ptr, SOCKET_CONNECT_PARAMS_LEN); + + /* Since we are in blocking state - wait for event complete */ + + SimpleLinkWaitEvent(HCI_CMND_CONNECT, &ret); + + errno = ret; + + return (long)ret; } +/***************************************************************************** + * Name: select + * + * Input Parameters: + * nfds the highest-numbered file descriptor in any of the + * three sets, plus 1. + * writesds socket descriptors list for write monitoring + * readsds socket descriptors list for read monitoring + * exceptsds socket descriptors list for exception monitoring + * timeout is an upper bound on the amount of time elapsed + * before select() returns. Null means infinity + * timeout. The minimum timeout is 5 milliseconds, + * less than 5 milliseconds will be set + * automatically to 5 milliseconds. + * + * Returned Value: + * On success, select() returns the number of file descriptors + * contained in the three returned descriptor sets (that is, the + * total number of bits that are set in readfds, writefds, + * exceptfds) which may be zero if the timeout expires before + * anything interesting happens. + * On error, -1 is returned. + * *readsds - return the sockets on which Read request will + * return without delay with valid data. + * *writesds - return the sockets on which Write request + * will return without delay. + * *exceptsds - return the sockets which closed recently. + * + * Decription: + * Monitor socket activity + * Select allow a program to monitor multiple file descriptors, + * waiting until one or more of the file descriptors become + * "ready" for some class of I/O operation + * + * NOTE: If the timeout value set to less than 5ms it will automatically set + * to 5ms to prevent overload of the system + * + *****************************************************************************/ -//***************************************************************************** -// -//! select -//! -//! @param[in] nfds the highest-numbered file descriptor in any of the -//! three sets, plus 1. -//! @param[out] writesds socket descriptors list for write monitoring -//! @param[out] readsds socket descriptors list for read monitoring -//! @param[out] exceptsds socket descriptors list for exception monitoring -//! @param[in] timeout is an upper bound on the amount of time elapsed -//! before select() returns. Null means infinity -//! timeout. The minimum timeout is 5 milliseconds, -//! less than 5 milliseconds will be set -//! automatically to 5 milliseconds. -//! @return On success, select() returns the number of file descriptors -//! contained in the three returned descriptor sets (that is, the -//! total number of bits that are set in readfds, writefds, -//! exceptfds) which may be zero if the timeout expires before -//! anything interesting happens. -//! On error, -1 is returned. -//! *readsds - return the sockets on which Read request will -//! return without delay with valid data. -//! *writesds - return the sockets on which Write request -//! will return without delay. -//! *exceptsds - return the sockets which closed recently. -//! -//! @brief Monitor socket activity -//! Select allow a program to monitor multiple file descriptors, -//! waiting until one or more of the file descriptors become -//! "ready" for some class of I/O operation -//! -//! @Note If the timeout value set to less than 5ms it will automatically set -//! to 5ms to prevent overload of the system -//! -//! @sa socket -// -//***************************************************************************** - -int -select(long nfds, TICC3000fd_set *readsds, TICC3000fd_set *writesds, TICC3000fd_set *exceptsds, - struct timeval *timeout) +int select(long nfds, TICC3000fd_set *readsds, TICC3000fd_set *writesds, + TICC3000fd_set *exceptsds, struct timeval *timeout) { - uint8_t *ptr, *args; - tBsdSelectRecvParams tParams; - unsigned long is_blocking; - - if( timeout == NULL) - { - is_blocking = 1; /* blocking , infinity timeout */ - } - else - { - is_blocking = 0; /* no blocking, timeout */ - } - - // Fill in HCI packet structure - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, nfds); - args = UINT32_TO_STREAM(args, 0x00000014); - args = UINT32_TO_STREAM(args, 0x00000014); - args = UINT32_TO_STREAM(args, 0x00000014); - args = UINT32_TO_STREAM(args, 0x00000014); - args = UINT32_TO_STREAM(args, is_blocking); - args = UINT32_TO_STREAM(args, ((readsds) ? *(unsigned long*)readsds : 0)); - args = UINT32_TO_STREAM(args, ((writesds) ? *(unsigned long*)writesds : 0)); - args = UINT32_TO_STREAM(args, ((exceptsds) ? *(unsigned long*)exceptsds : 0)); - - if (timeout) - { - if ( 0 == timeout->tv_sec && timeout->tv_usec < - SELECT_TIMEOUT_MIN_MICRO_SECONDS) - { - timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS; - } - args = UINT32_TO_STREAM(args, timeout->tv_sec); - args = UINT32_TO_STREAM(args, timeout->tv_usec); - } - - // Initiate a HCI command - hci_command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_EVNT_SELECT, &tParams); - - // Update actually read FD - if (tParams.iStatus >= 0) - { - if (readsds) - { - memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd)); - } - - if (writesds) - { - memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd)); - } - - if (exceptsds) - { - memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd)); - } - - return(tParams.iStatus); - - } - else - { - errno = tParams.iStatus; - return(-1); - } + uint8_t *ptr, *args; + tBsdSelectRecvParams tParams; + unsigned long is_blocking; + + if (timeout == NULL) + { + is_blocking = 1; /* blocking , infinity timeout */ + } + else + { + is_blocking = 0; /* no blocking, timeout */ + } + + /* Fill in HCI packet structure */ + + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_CMD); + + /* Fill in temporary command buffer */ + + args = UINT32_TO_STREAM(args, nfds); + args = UINT32_TO_STREAM(args, 0x00000014); + args = UINT32_TO_STREAM(args, 0x00000014); + args = UINT32_TO_STREAM(args, 0x00000014); + args = UINT32_TO_STREAM(args, 0x00000014); + args = UINT32_TO_STREAM(args, is_blocking); + args = UINT32_TO_STREAM(args, ((readsds) ? *(unsigned long*)readsds : 0)); + args = UINT32_TO_STREAM(args, ((writesds) ? *(unsigned long*)writesds : 0)); + args = UINT32_TO_STREAM(args, ((exceptsds) ? *(unsigned long*)exceptsds : 0)); + + if (timeout) + { + if (0 == timeout->tv_sec && timeout->tv_usec < + SELECT_TIMEOUT_MIN_MICRO_SECONDS) + { + timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS; + } + + args = UINT32_TO_STREAM(args, timeout->tv_sec); + args = UINT32_TO_STREAM(args, timeout->tv_usec); + } + + /* Initiate a HCI command */ + + hci_command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN); + + /* Since we are in blocking state - wait for event complete */ + + SimpleLinkWaitEvent(HCI_EVNT_SELECT, &tParams); + + /* Update actually read FD */ + + if (tParams.iStatus >= 0) + { + if (readsds) + { + memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd)); + } + + if (writesds) + { + memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd)); + } + + if (exceptsds) + { + memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd)); + } + + return tParams.iStatus; + } + else + { + errno = tParams.iStatus; + return -1; + } } -//***************************************************************************** -// -//! setsockopt -//! -//! @param[in] sd socket handle -//! @param[in] level defines the protocol level for this option -//! @param[in] optname defines the option name to Interrogate -//! @param[in] optval specifies a value for the option -//! @param[in] optlen specifies the length of the option value -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief set socket options -//! This function manipulate the options associated with a socket. -//! Options may exist at multiple protocol levels; they are always -//! present at the uppermost socket level. -//! When manipulating socket options the level at which the option -//! resides and the name of the option must be specified. -//! To manipulate options at the socket level, level is specified as -//! SOL_SOCKET. To manipulate options at any other level the protocol -//! number of the appropriate protocol controlling the option is -//! supplied. For example, to indicate that an option is to be -//! interpreted by the TCP protocol, level should be set to the -//! protocol number of TCP; -//! The parameters optval and optlen are used to access optval - -//! use for setsockopt(). For getsockopt() they identify a buffer -//! in which the value for the requested option(s) are to -//! be returned. For getsockopt(), optlen is a value-result -//! parameter, initially containing the size of the buffer -//! pointed to by option_value, and modified on return to -//! indicate the actual size of the value returned. If no option -//! value is to be supplied or returned, option_value may be NULL. -//! -//! @Note On this version the following two socket options are enabled: -//! The only protocol level supported in this version -//! is SOL_SOCKET (level). -//! 1. SOCKOPT_RECV_TIMEOUT (optname) -//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout -//! in milliseconds. -//! In that case optval should be pointer to unsigned long. -//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on -//! or off. -//! In that case optval should be SOCK_ON or SOCK_OFF (optval). -//! -//! @sa getsockopt -// -//***************************************************************************** +/***************************************************************************** + * Name: setsockopt + * + * Input Parameters: + * sd socket handle + * level defines the protocol level for this option + * optname defines the option name to Interrogate + * optval specifies a value for the option + * optlen specifies the length of the option value + * + * Returned Value: + * On success, zero is returned. On error, -1 is returned + * + * Decription: + * set socket options + * This function manipulate the options associated with a socket. + * Options may exist at multiple protocol levels; they are always + * present at the uppermost socket level. + * When manipulating socket options the level at which the option + * resides and the name of the option must be specified. + * To manipulate options at the socket level, level is specified as + * SOL_SOCKET. To manipulate options at any other level the protocol + * number of the appropriate protocol controlling the option is + * supplied. For example, to indicate that an option is to be + * interpreted by the TCP protocol, level should be set to the + * protocol number of TCP; + * The parameters optval and optlen are used to access optval - + * use for setsockopt(). For getsockopt() they identify a buffer + * in which the value for the requested option(s) are to + * be returned. For getsockopt(), optlen is a value-result + * parameter, initially containing the size of the buffer + * pointed to by option_value, and modified on return to + * indicate the actual size of the value returned. If no option + * value is to be supplied or returned, option_value may be NULL. + * + * NOTE: On this version the following two socket options are enabled: + * The only protocol level supported in this version + * is SOL_SOCKET (level). + * 1. SOCKOPT_RECV_TIMEOUT (optname) + * SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout + * in milliseconds. + * In that case optval should be pointer to unsigned long. + * 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on + * or off. + * In that case optval should be SOCK_ON or SOCK_OFF (optval). + * + *****************************************************************************/ #ifndef CC3000_TINY_DRIVER -int -setsockopt(long sd, long level, long optname, const void *optval, - socklen_t optlen) +int setsockopt(long sd, long level, long optname, const void *optval, socklen_t optlen) { - int ret; - uint8_t *ptr, *args; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, level); - args = UINT32_TO_STREAM(args, optname); - args = UINT32_TO_STREAM(args, 0x00000008); - args = UINT32_TO_STREAM(args, optlen); - ARRAY_TO_STREAM(args, ((uint8_t *)optval), optlen); - - // Initiate a HCI command - hci_command_send(HCI_CMND_SETSOCKOPT, - ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN + optlen); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_SETSOCKOPT, &ret); - - if (ret >= 0) - { - return (0); - } - else - { - errno = ret; - return ret; - } + int ret; + uint8_t *ptr, *args; + + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_CMD); + + /* Fill in temporary command buffer */ + + args = UINT32_TO_STREAM(args, sd); + args = UINT32_TO_STREAM(args, level); + args = UINT32_TO_STREAM(args, optname); + args = UINT32_TO_STREAM(args, 0x00000008); + args = UINT32_TO_STREAM(args, optlen); + ARRAY_TO_STREAM(args, ((uint8_t *)optval), optlen); + + /* Initiate a HCI command */ + + hci_command_send(HCI_CMND_SETSOCKOPT, + ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN + optlen); + + /* Since we are in blocking state - wait for event complete */ + + SimpleLinkWaitEvent(HCI_CMND_SETSOCKOPT, &ret); + + if (ret >= 0) + { + return 0; + } + else + { + errno = ret; + return ret; + } } #endif -//***************************************************************************** -// -//! getsockopt -//! -//! @param[in] sd socket handle -//! @param[in] level defines the protocol level for this option -//! @param[in] optname defines the option name to Interrogate -//! @param[out] optval specifies a value for the option -//! @param[out] optlen specifies the length of the option value -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief set socket options -//! This function manipulate the options associated with a socket. -//! Options may exist at multiple protocol levels; they are always -//! present at the uppermost socket level. -//! When manipulating socket options the level at which the option -//! resides and the name of the option must be specified. -//! To manipulate options at the socket level, level is specified as -//! SOL_SOCKET. To manipulate options at any other level the protocol -//! number of the appropriate protocol controlling the option is -//! supplied. For example, to indicate that an option is to be -//! interpreted by the TCP protocol, level should be set to the -//! protocol number of TCP; -//! The parameters optval and optlen are used to access optval - -//! use for setsockopt(). For getsockopt() they identify a buffer -//! in which the value for the requested option(s) are to -//! be returned. For getsockopt(), optlen is a value-result -//! parameter, initially containing the size of the buffer -//! pointed to by option_value, and modified on return to -//! indicate the actual size of the value returned. If no option -//! value is to be supplied or returned, option_value may be NULL. -//! -//! @Note On this version the following two socket options are enabled: -//! The only protocol level supported in this version -//! is SOL_SOCKET (level). -//! 1. SOCKOPT_RECV_TIMEOUT (optname) -//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout -//! in milliseconds. -//! In that case optval should be pointer to unsigned long. -//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on -//! or off. -//! In that case optval should be SOCK_ON or SOCK_OFF (optval). -//! -//! @sa setsockopt -// -//***************************************************************************** - -int -getsockopt (long sd, long level, long optname, void *optval, socklen_t *optlen) +/***************************************************************************** + * Name: getsockopt + * + * Input Parameters: + * sd socket handle + * level defines the protocol level for this option + * optname defines the option name to Interrogate + * optval specifies a value for the option + * optlen specifies the length of the option value + * + * Returned Value: + * On success, zero is returned. On error, -1 is returned + * + * Decription: + * set socket options + * This function manipulate the options associated with a socket. + * Options may exist at multiple protocol levels; they are always + * present at the uppermost socket level. + * When manipulating socket options the level at which the option + * resides and the name of the option must be specified. + * To manipulate options at the socket level, level is specified as + * SOL_SOCKET. To manipulate options at any other level the protocol + * number of the appropriate protocol controlling the option is + * supplied. For example, to indicate that an option is to be + * interpreted by the TCP protocol, level should be set to the + * protocol number of TCP; + * The parameters optval and optlen are used to access optval - + * use for setsockopt(). For getsockopt() they identify a buffer + * in which the value for the requested option(s) are to + * be returned. For getsockopt(), optlen is a value-result + * parameter, initially containing the size of the buffer + * pointed to by option_value, and modified on return to + * indicate the actual size of the value returned. If no option + * value is to be supplied or returned, option_value may be NULL. + * + * NOTE: On this version the following two socket options are enabled: + * The only protocol level supported in this version + * is SOL_SOCKET (level). + * 1. SOCKOPT_RECV_TIMEOUT (optname) + * SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout + * in milliseconds. + * In that case optval should be pointer to unsigned long. + * 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on + * or off. + * In that case optval should be SOCK_ON or SOCK_OFF (optval). + * + *****************************************************************************/ + +int getsockopt (long sd, long level, long optname, void *optval, socklen_t *optlen) { - uint8_t *ptr, *args; - tBsdGetSockOptReturnParams tRetParams; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, level); - args = UINT32_TO_STREAM(args, optname); - - // Initiate a HCI command - hci_command_send(HCI_CMND_GETSOCKOPT, - ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_GETSOCKOPT, &tRetParams); - - if (((int8_t)tRetParams.iStatus) >= 0) - { - *optlen = 4; - memcpy(optval, tRetParams.ucOptValue, 4); - return (0); - } - else - { - errno = tRetParams.iStatus; - return errno; - } + uint8_t *ptr, *args; + tBsdGetSockOptReturnParams tRetParams; + + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_CMD); + + /* Fill in temporary command buffer */ + + args = UINT32_TO_STREAM(args, sd); + args = UINT32_TO_STREAM(args, level); + args = UINT32_TO_STREAM(args, optname); + + /* Initiate a HCI command */ + + hci_command_send(HCI_CMND_GETSOCKOPT, + ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN); + + /* Since we are in blocking state - wait for event complete */ + + SimpleLinkWaitEvent(HCI_CMND_GETSOCKOPT, &tRetParams); + + if (((int8_t)tRetParams.iStatus) >= 0) + { + *optlen = 4; + memcpy(optval, tRetParams.ucOptValue, 4); + return 0; + } + else + { + errno = tRetParams.iStatus; + return errno; + } } -//***************************************************************************** -// -//! simple_link_recv -//! -//! @param sd socket handle -//! @param buf read buffer -//! @param len buffer length -//! @param flags indicates blocking or non-blocking operation -//! @param from pointer to an address structure indicating source address -//! @param fromlen source address structure size -//! -//! @return Return the number of bytes received, or -1 if an error -//! occurred -//! -//! @brief Read data from socket -//! Return the length of the message on successful completion. -//! If a message is too long to fit in the supplied buffer, -//! excess bytes may be discarded depending on the type of -//! socket the message is received from -// -//***************************************************************************** -int -simple_link_recv(long sd, void *buf, long len, long flags, sockaddr *from, - socklen_t *fromlen, long opcode) +/***************************************************************************** + * Name: simple_link_recv + * + * Input Parameters: + * sd socket handle + * buf read buffer + * len buffer length + * flags indicates blocking or non-blocking operation + * from pointer to an address structure indicating source address + * fromlen source address structure size + * + * Returned Value: + * Return the number of bytes received, or -1 if an error + * occurred + * + * Decription: + * Read data from socket + * Return the length of the message on successful completion. + * If a message is too long to fit in the supplied buffer, + * excess bytes may be discarded depending on the type of + * socket the message is received from + * + *****************************************************************************/ + +int simple_link_recv(long sd, void *buf, long len, long flags, sockaddr *from, + socklen_t *fromlen, long opcode) { - uint8_t *ptr, *args; - tBsdReadReturnParams tSocketReadEvent; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, len); - args = UINT32_TO_STREAM(args, flags); - - // Generate the read command, and wait for the - hci_command_send(opcode, ptr, SOCKET_RECV_FROM_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(opcode, &tSocketReadEvent); - - // In case the number of bytes is more then zero - read data - if (tSocketReadEvent.iNumberOfBytes > 0) - { - // Wait for the data in a synchronous way. Here we assume that the bug is - // big enough to store also parameters of receive from too.... - SimpleLinkWaitData((uint8_t *)buf, (uint8_t *)from, (uint8_t *)fromlen); - } - - errno = tSocketReadEvent.iNumberOfBytes; - - return(tSocketReadEvent.iNumberOfBytes); + uint8_t *ptr, *args; + tBsdReadReturnParams tSocketReadEvent; + + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_CMD); + + /* Fill in HCI packet structure */ + + args = UINT32_TO_STREAM(args, sd); + args = UINT32_TO_STREAM(args, len); + args = UINT32_TO_STREAM(args, flags); + + /* Generate the read command, and wait for the */ + + hci_command_send(opcode, ptr, SOCKET_RECV_FROM_PARAMS_LEN); + + /* Since we are in blocking state - wait for event complete */ + + SimpleLinkWaitEvent(opcode, &tSocketReadEvent); + + /* In case the number of bytes is more then zero - read data */ + + if (tSocketReadEvent.iNumberOfBytes > 0) + { + /* Wait for the data in a synchronous way. Here we assume that the bug is + * big enough to store also parameters of receive from too.... + */ + + SimpleLinkWaitData((uint8_t *)buf, (uint8_t *)from, (uint8_t *)fromlen); + } + + errno = tSocketReadEvent.iNumberOfBytes; + + return tSocketReadEvent.iNumberOfBytes; } -//***************************************************************************** -// -//! recv -//! -//! @param[in] sd socket handle -//! @param[out] buf Points to the buffer where the message should be stored -//! @param[in] len Specifies the length in bytes of the buffer pointed to -//! by the buffer argument. -//! @param[in] flags Specifies the type of message reception. -//! On this version, this parameter is not supported. -//! -//! @return Return the number of bytes received, or -1 if an error -//! occurred -//! -//! @brief function receives a message from a connection-mode socket -//! -//! @sa recvfrom -//! -//! @Note On this version, only blocking mode is supported. -// -//***************************************************************************** - -int -recv(long sd, void *buf, long len, long flags) +/***************************************************************************** + * Name: recv + * + * Input Parameters: + * sd socket handle + * buf Points to the buffer where the message should be stored + * len Specifies the length in bytes of the buffer pointed to + * by the buffer argument. + * flags Specifies the type of message reception. + * On this version, this parameter is not supported. + * + * Returned Value: + * Return the number of bytes received, or -1 if an error + * occurred + * + * Decription: + * function receives a message from a connection-mode socket + * + * NOTE: On this version, only blocking mode is supported. + * + *****************************************************************************/ + +int recv(long sd, void *buf, long len, long flags) { - return(simple_link_recv(sd, buf, len, flags, NULL, NULL, HCI_CMND_RECV)); + return(simple_link_recv(sd, buf, len, flags, NULL, NULL, HCI_CMND_RECV)); } -//***************************************************************************** -// -//! recvfrom -//! -//! @param[in] sd socket handle -//! @param[out] buf Points to the buffer where the message should be stored -//! @param[in] len Specifies the length in bytes of the buffer pointed to -//! by the buffer argument. -//! @param[in] flags Specifies the type of message reception. -//! On this version, this parameter is not supported. -//! @param[in] from pointer to an address structure indicating the source -//! address: sockaddr. On this version only AF_INET is -//! supported. -//! @param[in] fromlen source address tructure size -//! -//! @return Return the number of bytes received, or -1 if an error -//! occurred -//! -//! @brief read data from socket -//! function receives a message from a connection-mode or -//! connectionless-mode socket. Note that raw sockets are not -//! supported. -//! -//! @sa recv -//! -//! @Note On this version, only blocking mode is supported. -// -//***************************************************************************** -int -recvfrom(long sd, void *buf, long len, long flags, sockaddr *from, - socklen_t *fromlen) +/***************************************************************************** + * Name: recvfrom + * + * Input Parameters: + * sd socket handle + * buf Points to the buffer where the message should be stored + * len Specifies the length in bytes of the buffer pointed to + * by the buffer argument. + * flags Specifies the type of message reception. + * On this version, this parameter is not supported. + * from pointer to an address structure indicating the source + * address: sockaddr. On this version only AF_INET is + * supported. + * fromlen source address tructure size + * + * Returned Value: + * Return the number of bytes received, or -1 if an error + * occurred + * + * Decription: + * read data from socket + * function receives a message from a connection-mode or + * connectionless-mode socket. Note that raw sockets are not + * supported. + * + * NOTE: On this version, only blocking mode is supported. + * + *****************************************************************************/ + +int recvfrom(long sd, void *buf, long len, long flags, sockaddr *from, + socklen_t *fromlen) { - return(simple_link_recv(sd, buf, len, flags, from, fromlen, - HCI_CMND_RECVFROM)); + return(simple_link_recv(sd, buf, len, flags, from, fromlen, + HCI_CMND_RECVFROM)); } -//***************************************************************************** -// -//! simple_link_send -//! -//! @param sd socket handle -//! @param buf write buffer -//! @param len buffer length -//! @param flags On this version, this parameter is not supported -//! @param to pointer to an address structure indicating destination -//! address -//! @param tolen destination address structure size -//! -//! @return Return the number of bytes transmitted, or -1 if an error -//! occurred, or -2 in case there are no free buffers available -//! (only when SEND_NON_BLOCKING is enabled) -//! -//! @brief This function is used to transmit a message to another -//! socket -// -//***************************************************************************** -int -simple_link_send(long sd, const void *buf, long len, long flags, - const sockaddr *to, long tolen, long opcode) -{ - uint8_t uArgSize = 0, addrlen; - uint8_t *ptr, *pDataPtr = NULL, *args; - unsigned long addr_offset = 0; - int res; - tBsdReadReturnParams tSocketSendEvent; - - // Check the bsd_arguments - if (0 != (res = HostFlowControlConsumeBuff(sd))) - { - return res; - } - - //Update the number of sent packets - tSLInformation.NumberOfSentPackets++; - - // Allocate a buffer and construct a packet and send it over spi - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_DATA); - - // Update the offset of data and parameters according to the command - switch(opcode) - { - case HCI_CMND_SENDTO: - { - addr_offset = len + sizeof(len) + sizeof(len); - addrlen = 8; - uArgSize = SOCKET_SENDTO_PARAMS_LEN; - pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN; - break; - } - - case HCI_CMND_SEND: - { - tolen = 0; - to = NULL; - uArgSize = HCI_CMND_SEND_ARG_LENGTH; - pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH; - break; - } - - default: - { - break; - } - } - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd)); - args = UINT32_TO_STREAM(args, len); - args = UINT32_TO_STREAM(args, flags); - - if (opcode == HCI_CMND_SENDTO) - { - args = UINT32_TO_STREAM(args, addr_offset); - args = UINT32_TO_STREAM(args, addrlen); - } - - // Copy the data received from user into the TX Buffer - ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)buf), len); - - // In case we are using SendTo, copy the to parameters - if (opcode == HCI_CMND_SENDTO) - { - ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)to), tolen); - } - - // Initiate a HCI command - hci_data_send(opcode, ptr, uArgSize, len,(uint8_t*)to, tolen); - - if (opcode == HCI_CMND_SENDTO) - SimpleLinkWaitEvent(HCI_EVNT_SENDTO, &tSocketSendEvent); - else - SimpleLinkWaitEvent(HCI_EVNT_SEND, &tSocketSendEvent); - - return (len); +/***************************************************************************** + * Name: simple_link_send + * + * Input Parameters: + * sd socket handle + * buf write buffer + * len buffer length + * flags On this version, this parameter is not supported + * to pointer to an address structure indicating destination + * address + * tolen destination address structure size + * + * Returned Value: + * Return the number of bytes transmitted, or -1 if an error + * occurred, or -2 in case there are no free buffers available + * (only when SEND_NON_BLOCKING is enabled) + * + * Decription: + * This function is used to transmit a message to another + * socket + * + *****************************************************************************/ + +int simple_link_send(long sd, const void *buf, long len, long flags, + const sockaddr *to, long tolen, long opcode) +{ + tBsdReadReturnParams tSocketSendEvent; + uint8_t uArgSize = 0, addrlen; + uint8_t *ptr, *pDataPtr = NULL, *args; + unsigned long addr_offset = 0; + int res; + + /* Check the bsd_arguments */ + + if (0 != (res = HostFlowControlConsumeBuff(sd))) + { + return res; + } + + /* Update the number of sent packets */ + + tSLInformation.NumberOfSentPackets++; + + /* Allocate a buffer and construct a packet and send it over spi */ + + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_DATA); + + /* Update the offset of data and parameters according to the command */ + + switch(opcode) + { + case HCI_CMND_SENDTO: + { + addr_offset = len + sizeof(len) + sizeof(len); + addrlen = 8; + uArgSize = SOCKET_SENDTO_PARAMS_LEN; + pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN; + break; + } + + case HCI_CMND_SEND: + { + tolen = 0; + to = NULL; + uArgSize = HCI_CMND_SEND_ARG_LENGTH; + pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH; + break; + } + + default: + { + break; + } + } + + /* Fill in temporary command buffer */ + + args = UINT32_TO_STREAM(args, sd); + args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd)); + args = UINT32_TO_STREAM(args, len); + args = UINT32_TO_STREAM(args, flags); + + if (opcode == HCI_CMND_SENDTO) + { + args = UINT32_TO_STREAM(args, addr_offset); + args = UINT32_TO_STREAM(args, addrlen); + } + + /* Copy the data received from user into the TX Buffer */ + + ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)buf), len); + + /* In case we are using SendTo, copy the to parameters */ + + if (opcode == HCI_CMND_SENDTO) + { + ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)to), tolen); + } + + /* Initiate a HCI command */ + + hci_data_send(opcode, ptr, uArgSize, len,(uint8_t*)to, tolen); + + if (opcode == HCI_CMND_SENDTO) + { + SimpleLinkWaitEvent(HCI_EVNT_SENDTO, &tSocketSendEvent); + } + else + { + SimpleLinkWaitEvent(HCI_EVNT_SEND, &tSocketSendEvent); + } + + return len; } +/***************************************************************************** + * Name: send + * + * Input Parameters: + * sd socket handle + * buf Points to a buffer containing the message to be sent + * len message size in bytes + * flags On this version, this parameter is not supported + * + * Returned Value: + * Return the number of bytes transmitted, or -1 if an + * error occurred + * + * Decription: + * Write data to TCP socket + * This function is used to transmit a message to another + * socket. + * + * NOTE: On this version, only blocking mode is supported. + * + *****************************************************************************/ -//***************************************************************************** -// -//! send -//! -//! @param sd socket handle -//! @param buf Points to a buffer containing the message to be sent -//! @param len message size in bytes -//! @param flags On this version, this parameter is not supported -//! -//! @return Return the number of bytes transmitted, or -1 if an -//! error occurred -//! -//! @brief Write data to TCP socket -//! This function is used to transmit a message to another -//! socket. -//! -//! @Note On this version, only blocking mode is supported. -//! -//! @sa sendto -// -//***************************************************************************** - -int -send(long sd, const void *buf, long len, long flags) +int send(long sd, const void *buf, long len, long flags) { - return(simple_link_send(sd, buf, len, flags, NULL, 0, HCI_CMND_SEND)); + return(simple_link_send(sd, buf, len, flags, NULL, 0, HCI_CMND_SEND)); } -//***************************************************************************** -// -//! sendto -//! -//! @param sd socket handle -//! @param buf Points to a buffer containing the message to be sent -//! @param len message size in bytes -//! @param flags On this version, this parameter is not supported -//! @param to pointer to an address structure indicating the destination -//! address: sockaddr. On this version only AF_INET is -//! supported. -//! @param tolen destination address structure size -//! -//! @return Return the number of bytes transmitted, or -1 if an -//! error occurred -//! -//! @brief Write data to TCP socket -//! This function is used to transmit a message to another -//! socket. -//! -//! @Note On this version, only blocking mode is supported. -//! -//! @sa send -// -//***************************************************************************** - -int -sendto(long sd, const void *buf, long len, long flags, const sockaddr *to, - socklen_t tolen) +/***************************************************************************** + * Name: sendto + * + * Input Parameters: + * sd socket handle + * buf Points to a buffer containing the message to be sent + * len message size in bytes + * flags On this version, this parameter is not supported + * to pointer to an address structure indicating the destination + * address: sockaddr. On this version only AF_INET is + * supported. + * tolen destination address structure size + * + * Returned Value: + * Return the number of bytes transmitted, or -1 if an + * error occurred + * + * Decription: + * Write data to TCP socket + * This function is used to transmit a message to another + * socket. + * + * NOTE: On this version, only blocking mode is supported. + * + *****************************************************************************/ + +int sendto(long sd, const void *buf, long len, long flags, const sockaddr *to, + socklen_t tolen) { - return(simple_link_send(sd, buf, len, flags, to, tolen, HCI_CMND_SENDTO)); + return(simple_link_send(sd, buf, len, flags, to, tolen, HCI_CMND_SENDTO)); } -//***************************************************************************** -// -//! mdnsAdvertiser -//! -//! @param[in] mdnsEnabled flag to enable/disable the mDNS feature -//! @param[in] deviceServiceName Service name as part of the published -//! canonical domain name -//! @param[in] deviceServiceNameLength Length of the service name -//! -//! -//! @return On success, zero is returned, return SOC_ERROR if socket was not -//! opened successfully, or if an error occurred. -//! -//! @brief Set CC3000 in mDNS advertiser mode in order to advertise itself. -// -//***************************************************************************** - -int -mdnsAdvertiser(uint16_t mdnsEnabled, char * deviceServiceName, uint16_t deviceServiceNameLength) +/***************************************************************************** + * Name: mdnsAdvertiser + * + * Input Parameters: + * mdnsEnabled flag to enable/disable the mDNS feature + * deviceServiceName Service name as part of the published + * canonical domain name + * deviceServiceNameLength Length of the service name + * + * Returned Value: + * On success, zero is returned, return SOC_ERROR if socket was not + * opened successfully, or if an error occurred. + * + * Decription: + * Set CC3000 in mDNS advertiser mode in order to advertise itself. + * NOTE: + *****************************************************************************/ + +int mdnsAdvertiser(uint16_t mdnsEnabled, char * deviceServiceName, + uint16_t deviceServiceNameLength) { - int ret; - uint8_t *pTxBuffer, *pArgs; - - if (deviceServiceNameLength > MDNS_DEVICE_SERVICE_MAX_LENGTH) - { - return EFAIL; - } - - pTxBuffer = tSLInformation.pucTxCommandBuffer; - pArgs = (pTxBuffer + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); - - // Fill in HCI packet structure - pArgs = UINT32_TO_STREAM(pArgs, mdnsEnabled); - pArgs = UINT32_TO_STREAM(pArgs, 8); - pArgs = UINT32_TO_STREAM(pArgs, deviceServiceNameLength); - ARRAY_TO_STREAM(pArgs, deviceServiceName, deviceServiceNameLength); - - // Initiate a HCI command - hci_command_send(HCI_CMND_MDNS_ADVERTISE, pTxBuffer, SOCKET_MDNS_ADVERTISE_PARAMS_LEN + deviceServiceNameLength); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_EVNT_MDNS_ADVERTISE, &ret); - - return ret; - + int ret; + uint8_t *pTxBuffer, *pArgs; + + if (deviceServiceNameLength > MDNS_DEVICE_SERVICE_MAX_LENGTH) + { + return EFAIL; + } + + pTxBuffer = tSLInformation.pucTxCommandBuffer; + pArgs = (pTxBuffer + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); + + /* Fill in HCI packet structure */ + + pArgs = UINT32_TO_STREAM(pArgs, mdnsEnabled); + pArgs = UINT32_TO_STREAM(pArgs, 8); + pArgs = UINT32_TO_STREAM(pArgs, deviceServiceNameLength); + ARRAY_TO_STREAM(pArgs, deviceServiceName, deviceServiceNameLength); + + /* Initiate a HCI command */ + + hci_command_send(HCI_CMND_MDNS_ADVERTISE, pTxBuffer, SOCKET_MDNS_ADVERTISE_PARAMS_LEN + deviceServiceNameLength); + + /* Since we are in blocking state - wait for event complete */ + + SimpleLinkWaitEvent(HCI_EVNT_MDNS_ADVERTISE, &ret); + + return ret; } diff --git a/nuttx/drivers/wireless/cc3000/spi.c b/nuttx/drivers/wireless/cc3000/spi.c index 78582cc62..08734a10a 100644 --- a/nuttx/drivers/wireless/cc3000/spi.c +++ b/nuttx/drivers/wireless/cc3000/spi.c @@ -1,64 +1,47 @@ /************************************************************************** -* -* spi. - SPI functions to connect an Arduidno to the TI CC3000 -* -* This code uses the Arduino hardware SPI library (or a bit-banged -* SPI for the Teensy 3.0) to send & receive data between the library -* API calls and the CC3000 hardware. Every -* -* Version 1.0.1b -* -* Copyright (C) 2013 Chris Magagna - cmagagna@yahoo.com -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Don't sue me if my code blows up your board and burns down your house -* -****************************************************************************/ + * spi. - SPI functions to connect an Arduidno to the TI CC3000 + * + * This code uses the Arduino hardware SPI library (or a bit-banged + * SPI for the Teensy 3.0) to send & receive data between the library + * API calls and the CC3000 hardware. Every + * + * Version 1.0.1b + * + * Copyright (C) 2013 Chris Magagna - cmagagna@yahoo.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Don't sue me if my code blows up your board and burns down your house + * + ****************************************************************************/ + +/***************************************************************************** + * Included Files + *****************************************************************************/ +#include +#include +#include +#include + +#include +#include +#include #include #include #include #include -#include -#include -#include -#include -#include -//#include - -// This flag lets the interrupt handler know if it should respond to -// the WL_SPI_IRQ pin going low or not -int16_t SPIInterruptsEnabled=0; - - -#define READ 3 -#define WRITE 1 +#include +#include "spi.h" -#define HI(value) (((value) & 0xFF00) >> 8) -#define LO(value) ((value) & 0x00FF) +#include +#include -#define HEADERS_SIZE_EVNT (SPI_HEADER_SIZE + 5) - -#define SPI_HEADER_SIZE (5) - -#define eSPI_STATE_POWERUP (0) -#define eSPI_STATE_INITIALIZED (1) -#define eSPI_STATE_IDLE (2) -#define eSPI_STATE_WRITE_IRQ (3) -#define eSPI_STATE_WRITE_FIRST_PORTION (4) -#define eSPI_STATE_WRITE_EOT (5) -#define eSPI_STATE_READ_IRQ (6) -#define eSPI_STATE_READ_FIRST_PORTION (7) -#define eSPI_STATE_READ_EOT (8) - -/* !!!HACK!!!*/ -#define KL_PORTA_ISFR 0x400490a0 -#define PIN16 16 -#define getreg32(a) (*(volatile uint32_t *)(a)) -#define putreg32(v,a) (*(volatile uint32_t *)(a) = (v)) +/***************************************************************************** + * Pre-processor Definitions + *****************************************************************************/ #undef SPI_DEBUG /* Define to enable debug */ #undef SPI_VERBOSE /* Define to enable verbose debug */ @@ -76,609 +59,187 @@ int16_t SPIInterruptsEnabled=0; # define spivdbg(x...) #endif -#ifdef CONFIG_KL_SPI0 -void kl_spi0select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, - bool selected) -{ - spivdbg("devid: %d CS: %s\n", - (int)devid, selected ? "assert" : "de-assert"); -} -#endif - -#ifdef CONFIG_KL_SPI1 -void kl_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, - bool selected) -{ - spivdbg("devid: %d CS: %s\n", - (int)devid, selected ? "assert" : "de-assert"); -} -#endif - -#ifdef CONFIG_KL_SPI0 -uint8_t kl_spi0status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) -{ - return 0; -} -#endif - -#ifdef CONFIG_KL_SPI1 -uint8_t kl_spi1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) -{ - return 0; -} -#endif - -typedef struct -{ - gcSpiHandleRx SPIRxHandler; - - uint16_t usTxPacketLength; - uint16_t usRxPacketLength; - unsigned long ulSpiState; - uint8_t *pTxPacket; - uint8_t *pRxPacket; - -} tSpiInformation; - -tSpiInformation sSpiInformation; - -// -// Static buffer for 5 bytes of SPI HEADER -// -uint8_t tSpiReadHeader[] = {READ, 0, 0, 0, 0}; - -// The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size) -// for the purpose of detection of the overrun. The location of the memory where the magic number -// resides shall never be written. In case it is written - the overrun occured and either recevie function -// or send function will stuck forever. -#define CC3000_BUFFER_MAGIC_NUMBER (0xDE) - -char spi_buffer[CC3000_RX_BUFFER_SIZE]; -uint8_t wlan_tx_buffer[CC3000_TX_BUFFER_SIZE]; - -struct spi_dev_s *spi = NULL; - -unsigned int SPIPump(uint8_t data) -{ - uint8_t rx; - - printf("SPIPump tx = 0x%X ", data); - - if (!spi) - { - spi = up_spiinitialize(1); - SPI_SETBITS(spi, 8); - SPI_SETMODE(spi, SPIDEV_MODE1); - } - - SPI_EXCHANGE(spi, &data, &rx, 1); - - printf(" rx = 0x%X\n", rx); - - return rx; -} - -//***************************************************************************** -// -//! This function enter point for write flow -//! -//! \param SpiPauseSpi -//! -//! \return none -//! -//! \brief The function triggers a user provided callback for -// -//***************************************************************************** - -void SpiPauseSpi(void) -{ - SPIInterruptsEnabled = 0; -} - -//***************************************************************************** -// -//! This function enter point for write flow -//! -//! \param SpiResumeSpi -//! -//! \return none -//! -//! \brief The function triggers a user provided callback for -// -//***************************************************************************** +static struct +{ + int cc3000fd; + gcSpiHandleRx pfRxHandler; + pthread_t unsoliced_thread; + bool run; + uint8_t rx_buffer[CC3000_RX_BUFFER_SIZE]; + +} spiconf; + +/***************************************************************************** + * Public Functions + *****************************************************************************/ + +/***************************************************************************** + * Name: SpiResumeSpi + * + * Description: + * Will re enable the SPI_IRQ'a ability to create interrupts. It is used to + * resume processing after the code passed to SpiOpen is Called + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + *****************************************************************************/ void SpiResumeSpi(void) { - SPIInterruptsEnabled = 1; -} - -//***************************************************************************** -// -//! This function enter point for write flow -//! -//! \param SpiTriggerRxProcessing -//! -//! \return none -//! -//! \brief The function triggers a user provided callback for -// -//***************************************************************************** -void SpiTriggerRxProcessing(void) -{ - // - // Trigger Rx processing - // - SpiPauseSpi(); - DeassertWlanCS(); - - // The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size) - // for the purpose of detection of the overrun. If the magic number is overriten - buffer overrun - // occurred - and we will stuck here forever! + DEBUGASSERT(spiconf.cc3000fd); - if (sSpiInformation.pRxPacket[CC3000_RX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) + if (ioctl(spiconf.cc3000fd,CC3000IOC_COMPLETE,0)) { - while (1) - ; + printf("ioctl:CC3000IOC_COMPLETE failed: %s\n", strerror(errno)); } - - sSpiInformation.ulSpiState = eSPI_STATE_IDLE; - sSpiInformation.SPIRxHandler(sSpiInformation.pRxPacket + SPI_HEADER_SIZE); -} - -//***************************************************************************** -// -//! This function enter point for write flow -//! -//! \param buffer -//! -//! \return none -//! -//! \brief ... -// -//***************************************************************************** - -void SpiReadDataSynchronous(uint8_t *data, uint16_t size) -{ - long i = 0; - uint8_t *data_to_send = tSpiReadHeader; - - for (i = 0; i < size; i ++) - { - data[i] = SPIPump(data_to_send[0]); - } -} - -//***************************************************************************** -// -//! This function enter point for write flow -//! -//! \param buffer -//! -//! \return none -//! -//! \brief ... -// -//***************************************************************************** - -void SpiWriteDataSynchronous(uint8_t *data, uint16_t size) -{ - while (size) - { - SPIPump(*data); - size --; - data++; - } -} - -//***************************************************************************** -// -//! This function enter point for write flow -//! -//! \param buffer -//! -//! \return none -//! -//! \brief ... -// -//***************************************************************************** -long SpiFirstWrite(uint8_t *ucBuf, uint16_t usLength) -{ - // - // workaround for first transaction - // - - AssertWlanCS(); - - usleep(70); - - // SPI writes first 4 bytes of data - - SpiWriteDataSynchronous(ucBuf, 4); - - usleep(70); - - SpiWriteDataSynchronous(ucBuf + 4, usLength - 4); - - sSpiInformation.ulSpiState = eSPI_STATE_IDLE; - - DeassertWlanCS(); - - //printf("Executed SpiFirstWrite!\n"); - - return(0); } -//***************************************************************************** -// -//! This function enter point for write flow -//! -//! \param buffer -//! -//! \return none -//! -//! \brief ... -// -//***************************************************************************** +/***************************************************************************** + * Name: SpiWrite + * + * Description: + * This function enter point for write flow + * + * Input Parameters: + * pUserBuffer + * usLength + * + * Returned Value: + * + *****************************************************************************/ long SpiWrite(uint8_t *pUserBuffer, uint16_t usLength) { - uint8_t ucPad = 0; - - // - // Figure out the total length of the packet in order to figure out if there is padding or not - // - - if(!(usLength & 0x0001)) + DEBUGASSERT(spiconf.cc3000fd); + return write(spiconf.cc3000fd,pUserBuffer,usLength) == usLength ? 0 : -errno; +} + +/***************************************************************************** + * Name: SpiRead + * + * Description: + * This function enter point for read flow. This function will block the + * caller untinlthere is data Available + * + * Input Parameters: + * pUserBuffer + * usLength + * + * Returned Value: + * + *****************************************************************************/ + +long SpiRead(uint8_t *pUserBuffer, uint16_t usLength) +{ + DEBUGASSERT(spiconf.cc3000fd); + return read(spiconf.cc3000fd,pUserBuffer,usLength); +} + +/***************************************************************************** + * Name: unsoliced_thread_func + * + * Description: + * This is the thread for unsolicited events. This function will block the + * caller untinlthere is data Available + * + * Input Parameters: + * parameter + * + * Returned Value: + * + *****************************************************************************/ + +static void *unsoliced_thread_func(void *parameter) +{ + char queuename[QUEUE_NAMELEN]; + int status = 0; + int nbytes = 0; + int minor = 0; + + ioctl(spiconf.cc3000fd, CC3000IOC_GETQUEID, (unsigned long)&minor); + snprintf(queuename, QUEUE_NAMELEN, QUEUE_FORMAT, minor); + mqd_t queue = mq_open(queuename,O_RDONLY); + + while(spiconf.run) { - ucPad++; - } - - pUserBuffer[0] = WRITE; - pUserBuffer[1] = HI(usLength + ucPad); - pUserBuffer[2] = LO(usLength + ucPad); - pUserBuffer[3] = 0; - pUserBuffer[4] = 0; - - usLength += (SPI_HEADER_SIZE + ucPad); - - // The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size) - // for the purpose of overrun detection. If the magic number is overwritten - buffer overrun - // occurred - and we will be stuck here forever! - - if (wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) - { - while (1) - ; - } - - if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP) - { - while (sSpiInformation.ulSpiState != eSPI_STATE_INITIALIZED) + memset(spiconf.rx_buffer,0,sizeof(spiconf.rx_buffer)); + nbytes = mq_receive(queue, spiconf.rx_buffer, CC3000_RX_BUFFER_SIZE, 0); + if (nbytes > 0) { + spiconf.pfRxHandler(spiconf.rx_buffer); } } - if (sSpiInformation.ulSpiState == eSPI_STATE_INITIALIZED) - { - // - // This is time for first TX/RX transactions over SPI: - // the IRQ is down - so need to send read buffer size command - // - - SpiFirstWrite(pUserBuffer, usLength); - } - else - { - // - // We need to prevent here race that can occur in case two back to back packets are sent to the - // device, so the state will move to IDLE and once again to not IDLE due to IRQ - // - - tSLInformation.WlanInterruptDisable(); - - while (sSpiInformation.ulSpiState != eSPI_STATE_IDLE) - { - ; - } - - sSpiInformation.ulSpiState = eSPI_STATE_WRITE_IRQ; - sSpiInformation.pTxPacket = pUserBuffer; - sSpiInformation.usTxPacketLength = usLength; - - // - // Assert the CS line and wait till SSI IRQ line is active and then initialize write operation - // - - AssertWlanCS(); - - // - // Re-enable IRQ - if it was not disabled - this is not a problem... - // - - tSLInformation.WlanInterruptEnable(); - - // - // check for a missing interrupt between the CS assertion and enabling back the interrupts - // - - if (tSLInformation.ReadWlanInterruptPin() == 0) - { - SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength); - - sSpiInformation.ulSpiState = eSPI_STATE_IDLE; - - DeassertWlanCS(); - } - } - - - // - // Due to the fact that we are currently implementing a blocking situation - // here we will wait till end of transaction - // - - while (eSPI_STATE_IDLE != sSpiInformation.ulSpiState) - ; - - return(0); -} - -//***************************************************************************** -// -//! This function processes received SPI Header and in accordance with it - continues reading -//! the packet -//! -//! \param None -//! -//! \return None -//! -//! \brief ... -// -//***************************************************************************** - -long SpiReadDataCont(void) -{ - long data_to_recv; - uint8_t *evnt_buff, type; - - // - //determine what type of packet we have - // - - evnt_buff = sSpiInformation.pRxPacket; - data_to_recv = 0; - STREAM_TO_UINT8((char *)(evnt_buff + SPI_HEADER_SIZE), HCI_PACKET_TYPE_OFFSET, type); - - switch(type) - { - case HCI_TYPE_DATA: - { - // - // We need to read the rest of data.. - // - - STREAM_TO_UINT16((char *)(evnt_buff + SPI_HEADER_SIZE), HCI_DATA_LENGTH_OFFSET, data_to_recv); - - if (!((HEADERS_SIZE_EVNT + data_to_recv) & 1)) - { - data_to_recv++; - } - - if (data_to_recv) - { - SpiReadDataSynchronous(evnt_buff + 10, data_to_recv); - } - break; - } - - case HCI_TYPE_EVNT: - { - // - // Calculate the rest length of the data - // - - STREAM_TO_UINT8((char *)(evnt_buff + SPI_HEADER_SIZE), HCI_EVENT_LENGTH_OFFSET, data_to_recv); - - data_to_recv -= 1; - - // - // Add padding byte if needed - // - - if ((HEADERS_SIZE_EVNT + data_to_recv) & 1) - { - data_to_recv++; - } - - if (data_to_recv) - { - SpiReadDataSynchronous(evnt_buff + 10, data_to_recv); - } - - sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT; - break; - } - } - - return (0); -} - -//***************************************************************************** -// -//! This function enter point for write flow -//! -//! \param SSIContReadOperation -//! -//! \return none -//! -//! \brief The function triggers a user provided callback for -// -//***************************************************************************** - -void SSIContReadOperation(void) -{ - // - // The header was read - continue with the payload read - // - if (!SpiReadDataCont()) - { - // - // All the data was read - finalize handling by switching to teh task - // and calling from task Event Handler - // - - SpiTriggerRxProcessing(); - } -} - -//***************************************************************************** -// -//! This function enter point for read flow: first we read minimal 5 SPI header bytes and 5 Event -//! Data bytes -//! -//! \param buffer -//! -//! \return none -//! -//! \brief ... -// -//***************************************************************************** -void SpiReadHeader(void) -{ - SpiReadDataSynchronous(sSpiInformation.pRxPacket, 10); -} - -//***************************************************************************** -// -//! The IntSpiGPIOHandler interrupt handler -//! -//! \param none -//! -//! \return none -//! -//! \brief GPIO A interrupt handler. When the external SSI WLAN device is -//! ready to interact with Host CPU it generates an interrupt signal. -//! After that Host CPU has registrated this interrupt request -//! it set the corresponding /CS in active state. -// -//***************************************************************************** -//#pragma vector=PORT2_VECTOR -//__interrupt void IntSpiGPIOHandler(void) -int CC3000InterruptHandler(int irq, void *context) -{ - uint32_t regval = 0; - - regval = getreg32(KL_PORTA_ISFR); - if (regval & (1 << PIN16)) - { - //printf("\nAn interrupt was issued!\n"); - - if (!SPIInterruptsEnabled) - { - goto out; - } - - //printf("\nSPIInterrupt was enabled!\n"); - - if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP) - { - /* This means IRQ line was low call a callback of HCI Layer to inform on event */ - - sSpiInformation.ulSpiState = eSPI_STATE_INITIALIZED; - } - else if (sSpiInformation.ulSpiState == eSPI_STATE_IDLE) - { - sSpiInformation.ulSpiState = eSPI_STATE_READ_IRQ; - - /* IRQ line goes down - start reception */ - - AssertWlanCS(); - - // - // Wait for TX/RX Complete which will come as DMA interrupt - // - - SpiReadHeader(); - - sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT; - - SSIContReadOperation(); - } - else if (sSpiInformation.ulSpiState == eSPI_STATE_WRITE_IRQ) - { - SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength); - - sSpiInformation.ulSpiState = eSPI_STATE_IDLE; - - DeassertWlanCS(); - } - else - { - } - -out: - regval = (1 << PIN16); - putreg32(regval, KL_PORTA_ISFR); - } - - return 0; -} - -//***************************************************************************** -// -//! SpiClose -//! -//! \param none -//! -//! \return none -//! -//! \brief Cofigure the SSI -// -//***************************************************************************** + mq_close(queue); + pthread_exit((pthread_addr_t)status); + return (pthread_addr_t)status; +} + +/***************************************************************************** + * Name: SpiOpen + * + * Description: + * Configure the SPI + * + * Input Parameters: + * pfRxHandler the Rx handler for SPI + * + * Returned Value: + * None + * + *****************************************************************************/ void SpiOpen(gcSpiHandleRx pfRxHandler) { - sSpiInformation.ulSpiState = eSPI_STATE_POWERUP; - - memset(spi_buffer, 0, sizeof(spi_buffer)); - memset(wlan_tx_buffer, 0, sizeof(spi_buffer)); - - sSpiInformation.SPIRxHandler = pfRxHandler; - sSpiInformation.usTxPacketLength = 0; - sSpiInformation.pTxPacket = NULL; - sSpiInformation.pRxPacket = (uint8_t *)spi_buffer; - sSpiInformation.usRxPacketLength = 0; - spi_buffer[CC3000_RX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER; - wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER; + pthread_attr_t attr; + int status; - // - // Enable interrupt on the GPIO pin of WLAN IRQ - // - tSLInformation.WlanInterruptEnable(); -} - -//***************************************************************************** -// -//! SpiClose -//! -//! \param none -//! -//! \return none -//! -//! \brief Cofigure the SSI -// -//***************************************************************************** + DEBUGASSERT(spiconf.cc3000fd == 0); + int fd = open("/dev/wireless0",O_RDWR|O_BINARY); + if (fd > 0) + { + spiconf.pfRxHandler = pfRxHandler; + spiconf.cc3000fd = fd; + spiconf.run = true; + + status = pthread_attr_init(&attr); + DEBUGASSERT(status == 0) + + status = pthread_create(&spiconf.unsoliced_thread, &attr, + unsoliced_thread_func, NULL); + DEBUGASSERT(status == 0) + } +} + +/***************************************************************************** + * Name: SpiClose + * + * Description: + * Configure the SPI + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + *****************************************************************************/ void SpiClose(void) { - if (sSpiInformation.pRxPacket) - { - sSpiInformation.pRxPacket = 0; - } + if (spiconf.cc3000fd) + { + int status; + spiconf.run = false; - // - // Disable Interrupt in GPIOA module... - // + pthread_cancel(spiconf.unsoliced_thread); + pthread_join(spiconf.unsoliced_thread, (pthread_addr_t*)&status); - tSLInformation.WlanInterruptDisable(); + close(spiconf.cc3000fd); + spiconf.cc3000fd = 0; + } } diff --git a/nuttx/drivers/wireless/cc3000/spi.h b/nuttx/drivers/wireless/cc3000/spi.h index bf68b3eb1..dd7fcaf18 100644 --- a/nuttx/drivers/wireless/cc3000/spi.h +++ b/nuttx/drivers/wireless/cc3000/spi.h @@ -1,45 +1,50 @@ /************************************************************************** -* -* ArduinoCC3000SPI.h - SPI functions to connect an Arduidno to the TI -* CC3000 -* -* This code uses the Arduino hardware SPI library (or a bit-banged -* SPI for the Teensy 3.0) to send & receive data between the library -* API calls and the CC3000 hardware. Every -* -* Version 1.0.1b -* -* Copyright (C) 2013 Chris Magagna - cmagagna@yahoo.com -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Don't sue me if my code blows up your board and burns down your house -* -****************************************************************************/ - + * ArduinoCC3000SPI.h - SPI functions to connect an Arduidno to the TI + * CC3000 + * + * This code uses the Arduino hardware SPI library (or a bit-banged + * SPI for the Teensy 3.0) to send & receive data between the library + * API calls and the CC3000 hardware. Every + * + * Version 1.0.1b + * + * Copyright (C) 2013 Chris Magagna - cmagagna@yahoo.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Don't sue me if my code blows up your board and burns down your house + * + ****************************************************************************/ + +#ifndef __DRIVERS_WIRELESS_CC3000_SPI_H +#define __DRIVERS_WIRELESS_CC3000_SPI_H + +#include + +/***************************************************************************** + * Public Types + *****************************************************************************/ +typedef void (*gcSpiHandleRx)(void *p); +/***************************************************************************** + * Public Data + *****************************************************************************/ -typedef void (*gcSpiHandleRx)(void *p); +extern uint16_t SPIInterruptsEnabled; +extern uint8_t wlan_tx_buffer[]; -//***************************************************************************** -// -// Prototypes for the APIs. -// -//***************************************************************************** +/***************************************************************************** + * Public Function Prototypes + *****************************************************************************/ void SpiOpen(gcSpiHandleRx pfRxHandler); - void SpiClose(void); - long SpiWrite(uint8_t *pUserBuffer, uint16_t usLength); - +long SpiRead(uint8_t *pUserBuffer, uint16_t usLength); void SpiResumeSpi(void); - int CC3000InterruptHandler(int irq, void *context); -int16_t SPIInterruptsEnabled; - -uint8_t wlan_tx_buffer[]; +#endif /* __DRIVERS_WIRELESS_CC3000_SPI_H */ diff --git a/nuttx/drivers/wireless/cc3000/spi_version.h b/nuttx/drivers/wireless/cc3000/spi_version.h index 44ff64397..0ca1516f9 100644 --- a/nuttx/drivers/wireless/cc3000/spi_version.h +++ b/nuttx/drivers/wireless/cc3000/spi_version.h @@ -1,53 +1,41 @@ -/***************************************************************************** -* -* spi_version.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -#ifndef __SPI_VERSION_H__ -#define __SPI_VERSION_H__ - -#define SPI_VERSION_NUMBER 7 - -#endif // __VERSION_H__ - - - - - - - - - - - - - +/***************************************************************************** +* +* spi_version.h - CC3000 Host Driver Implementation. +* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the +* distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*****************************************************************************/ + +#ifndef __DRIVERS_WIRELESS_CC3000_SPI_VERSION_H +#define __DRIVERS_WIRELESS_CC3000_SPI_VERSION_H + +#define SPI_VERSION_NUMBER 7 + +#endif /* __DRIVERS_WIRELESS_CC3000_SPI_VERSION_H */ diff --git a/nuttx/drivers/wireless/cc3000/wlan.c b/nuttx/drivers/wireless/cc3000/wlan.c index 38f8f2b70..7b084e0ae 100644 --- a/nuttx/drivers/wireless/cc3000/wlan.c +++ b/nuttx/drivers/wireless/cc3000/wlan.c @@ -1,1251 +1,1297 @@ /***************************************************************************** -* -* wlan.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ - -//***************************************************************************** -// -//! \addtogroup wlan_api -//! @{ -// -//***************************************************************************** + * wlan.c - CC3000 Host Driver Implementation. + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +/***************************************************************************** + * Included Files + *****************************************************************************/ + +#include +#include +#include + #include + +#include #include #include -#include -#include +#include "spi.h" +#include #include #include #include +/***************************************************************************** + * Preprocessor Definitions + *****************************************************************************/ -volatile sSimplLinkInformation tSLInformation; +#define SMART_CONFIG_PROFILE_SIZE 67 /* 67 = 32 (max ssid) + 32 (max key) + + * 1 (SSID length) + 1 (security type) + + * 1 (key length) */ +/* Patches type */ -#define SMART_CONFIG_PROFILE_SIZE 67 // 67 = 32 (max ssid) + 32 (max key) + 1 (SSID length) + 1 (security type) + 1 (key length) +#define PATCHES_HOST_TYPE_WLAN_DRIVER 0x01 +#define PATCHES_HOST_TYPE_WLAN_FW 0x02 +#define PATCHES_HOST_TYPE_BOOTLOADER 0x03 +#define SL_SET_SCAN_PARAMS_INTERVAL_LIST_SIZE (16) +#define SL_SIMPLE_CONFIG_PREFIX_LENGTH (3) +#define ETH_ALEN (6) +#define MAXIMAL_SSID_LENGTH (32) + +#define SL_PATCHES_REQUEST_DEFAULT (0) +#define SL_PATCHES_REQUEST_FORCE_HOST (1) +#define SL_PATCHES_REQUEST_FORCE_NONE (2) + +#define WLAN_SEC_UNSEC (0) +#define WLAN_SEC_WEP (1) +#define WLAN_SEC_WPA (2) +#define WLAN_SEC_WPA2 (3) + +#define WLAN_SL_INIT_START_PARAMS_LEN (1) +#define WLAN_PATCH_PARAMS_LENGTH (8) +#define WLAN_SET_CONNECTION_POLICY_PARAMS_LEN (12) +#define WLAN_DEL_PROFILE_PARAMS_LEN (4) +#define WLAN_SET_MASK_PARAMS_LEN (4) +#define WLAN_SET_SCAN_PARAMS_LEN (100) +#define WLAN_GET_SCAN_RESULTS_PARAMS_LEN (4) +#define WLAN_ADD_PROFILE_NOSEC_PARAM_LEN (24) +#define WLAN_ADD_PROFILE_WEP_PARAM_LEN (36) +#define WLAN_ADD_PROFILE_WPA_PARAM_LEN (44) +#define WLAN_CONNECT_PARAM_LEN (29) +#define WLAN_SMART_CONFIG_START_PARAMS_LEN (4) + +/***************************************************************************** + * Public Data + *****************************************************************************/ + +volatile sSimplLinkInformation tSLInformation; #ifndef CC3000_UNENCRYPTED_SMART_CONFIG -uint8_t akey[AES128_KEY_SIZE]; +uint8_t akey[AES128_KEY_SIZE]; uint8_t profileArray[SMART_CONFIG_PROFILE_SIZE]; -#endif //CC3000_UNENCRYPTED_SMART_CONFIG - -/* patches type */ -#define PATCHES_HOST_TYPE_WLAN_DRIVER 0x01 -#define PATCHES_HOST_TYPE_WLAN_FW 0x02 -#define PATCHES_HOST_TYPE_BOOTLOADER 0x03 - -#define SL_SET_SCAN_PARAMS_INTERVAL_LIST_SIZE (16) -#define SL_SIMPLE_CONFIG_PREFIX_LENGTH (3) -#define ETH_ALEN (6) -#define MAXIMAL_SSID_LENGTH (32) - -#define SL_PATCHES_REQUEST_DEFAULT (0) -#define SL_PATCHES_REQUEST_FORCE_HOST (1) -#define SL_PATCHES_REQUEST_FORCE_NONE (2) - - -#define WLAN_SEC_UNSEC (0) -#define WLAN_SEC_WEP (1) -#define WLAN_SEC_WPA (2) -#define WLAN_SEC_WPA2 (3) - - -#define WLAN_SL_INIT_START_PARAMS_LEN (1) -#define WLAN_PATCH_PARAMS_LENGTH (8) -#define WLAN_SET_CONNECTION_POLICY_PARAMS_LEN (12) -#define WLAN_DEL_PROFILE_PARAMS_LEN (4) -#define WLAN_SET_MASK_PARAMS_LEN (4) -#define WLAN_SET_SCAN_PARAMS_LEN (100) -#define WLAN_GET_SCAN_RESULTS_PARAMS_LEN (4) -#define WLAN_ADD_PROFILE_NOSEC_PARAM_LEN (24) -#define WLAN_ADD_PROFILE_WEP_PARAM_LEN (36) -#define WLAN_ADD_PROFILE_WPA_PARAM_LEN (44) -#define WLAN_CONNECT_PARAM_LEN (29) -#define WLAN_SMART_CONFIG_START_PARAMS_LEN (4) - - - - -//***************************************************************************** -// -//! SimpleLink_Init_Start -//! -//! @param usPatchesAvailableAtHost flag to indicate if patches available -//! from host or from EEPROM. Due to the -//! fact the patches are burn to the EEPROM -//! using the patch programmer utility, the -//! patches will be available from the EEPROM -//! and not from the host. -//! -//! @return none -//! -//! @brief Send HCI_CMND_SIMPLE_LINK_START to CC3000 -// -//***************************************************************************** +#endif /* CC3000_UNENCRYPTED_SMART_CONFIG */ + +/***************************************************************************** + * Public Functions + *****************************************************************************/ +/***************************************************************************** + * Name: SimpleLink_Init_Start + * + * Input Parameters: + * usPatchesAvailableAtHost flag to indicate if patches available + * from host or from EEPROM. Due to the + * fact the patches are burn to the EEPROM + * using the patch programmer utility, the + * patches will be available from the EEPROM + * and not from the host. + * + * Returned Value: + * None + * + * Description: + * Send HCI_CMND_SIMPLE_LINK_START to CC3000 + * + *****************************************************************************/ + static void SimpleLink_Init_Start(uint16_t usPatchesAvailableAtHost) { - uint8_t *ptr; - uint8_t *args; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (uint8_t *)(ptr + HEADERS_SIZE_CMD); - - UINT8_TO_STREAM(args, ((usPatchesAvailableAtHost) ? SL_PATCHES_REQUEST_FORCE_HOST : SL_PATCHES_REQUEST_DEFAULT)); - - // IRQ Line asserted - send HCI_CMND_SIMPLE_LINK_START to CC3000 - hci_command_send(HCI_CMND_SIMPLE_LINK_START, ptr, WLAN_SL_INIT_START_PARAMS_LEN); - - SimpleLinkWaitEvent(HCI_CMND_SIMPLE_LINK_START, 0); -} + uint8_t *ptr; + uint8_t *args; + + ptr = tSLInformation.pucTxCommandBuffer; + args = (uint8_t *)(ptr + HEADERS_SIZE_CMD); + + UINT8_TO_STREAM(args, ((usPatchesAvailableAtHost) ? SL_PATCHES_REQUEST_FORCE_HOST : SL_PATCHES_REQUEST_DEFAULT)); + /* IRQ Line asserted - send HCI_CMND_SIMPLE_LINK_START to CC3000 */ + hci_command_send(HCI_CMND_SIMPLE_LINK_START, ptr, WLAN_SL_INIT_START_PARAMS_LEN); -//***************************************************************************** -// -//! wlan_init -//! -//! @param sWlanCB Asynchronous events callback. -//! 0 no event call back. -//! -call back parameters: -//! 1) event_type: HCI_EVNT_WLAN_UNSOL_CONNECT connect event, -//! HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event, -//! HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE config done, -//! HCI_EVNT_WLAN_UNSOL_DHCP dhcp report, -//! HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report OR -//! HCI_EVNT_WLAN_KEEPALIVE keepalive. -//! 2) data: pointer to extra data that received by the event -//! (NULL no data). -//! 3) length: data length. -//! -Events with extra data: -//! HCI_EVNT_WLAN_UNSOL_DHCP: 4 bytes IP, 4 bytes Mask, -//! 4 bytes default gateway, 4 bytes DHCP server and 4 bytes -//! for DNS server. -//! HCI_EVNT_WLAN_ASYNC_PING_REPORT: 4 bytes Packets sent, -//! 4 bytes Packets received, 4 bytes Min round time, -//! 4 bytes Max round time and 4 bytes for Avg round time. -//! -//! @param sFWPatches 0 no patch or pointer to FW patches -//! @param sDriverPatches 0 no patch or pointer to driver patches -//! @param sBootLoaderPatches 0 no patch or pointer to bootloader patches -//! @param sReadWlanInterruptPin init callback. the callback read wlan -//! interrupt status. -//! @param sWlanInterruptEnable init callback. the callback enable wlan -//! interrupt. -//! @param sWlanInterruptDisable init callback. the callback disable wlan -//! interrupt. -//! @param sWriteWlanPin init callback. the callback write value -//! to device pin. -//! -//! @return none -//! -//! @sa wlan_set_event_mask , wlan_start , wlan_stop -//! -//! @brief Initialize wlan driver -//! -//! @warning This function must be called before ANY other wlan driver function -// -//***************************************************************************** - -void wlan_init( tWlanCB sWlanCB, - tFWPatches sFWPatches, - tDriverPatches sDriverPatches, - tBootLoaderPatches sBootLoaderPatches, - tWlanReadInteruptPin sReadWlanInterruptPin, - tWlanInterruptEnable sWlanInterruptEnable, - tWlanInterruptDisable sWlanInterruptDisable, - tWriteWlanPin sWriteWlanPin) + SimpleLinkWaitEvent(HCI_CMND_SIMPLE_LINK_START, 0); +} + +/***************************************************************************** + * Name: wlan_init + * + * Input Parameters: + * sWlanCB Asynchronous events callback. + * 0 no event call back. + * - call back parameters: + * 1) event_type: HCI_EVNT_WLAN_UNSOL_CONNECT connect event, + * HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event, + * HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE config done, + * HCI_EVNT_WLAN_UNSOL_DHCP dhcp report, + * HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report OR + * HCI_EVNT_WLAN_KEEPALIVE keepalive. + * 2) data: pointer to extra data that received by the event + * (NULL no data). + * 3) length: data length. + * - Events with extra data: + * HCI_EVNT_WLAN_UNSOL_DHCP: 4 bytes IP, 4 bytes Mask, + * 4 bytes default gateway, 4 bytes DHCP server and 4 bytes + * for DNS server. + * HCI_EVNT_WLAN_ASYNC_PING_REPORT: 4 bytes Packets sent, + * 4 bytes Packets received, 4 bytes Min round time, + * 4 bytes Max round time and 4 bytes for Avg round time. + * + * sFWPatches 0 no patch or pointer to FW patches + * sDriverPatches 0 no patch or pointer to driver patches + * sBootLoaderPatches 0 no patch or pointer to bootloader patches + * sReadWlanInterruptPin init callback. the callback read wlan + * interrupt status. + * sWlanInterruptEnable init callback. the callback enable wlan + * interrupt. + * sWlanInterruptDisable init callback. the callback disable wlan + * interrupt. + * sWriteWlanPin init callback. the callback write value + * to device pin. + * + * Returned Value: + * None + * + * Description: + * Initialize wlan driver + * + * WARNING: This function must be called before ANY other wlan driver function + * + *****************************************************************************/ + +void wlan_init(tWlanCB sWlanCB, tFWPatches sFWPatches, + tDriverPatches sDriverPatches, + tBootLoaderPatches sBootLoaderPatches, + tWlanReadInteruptPin sReadWlanInterruptPin, + tWlanInterruptEnable sWlanInterruptEnable, + tWlanInterruptDisable sWlanInterruptDisable, + tWriteWlanPin sWriteWlanPin) { - - tSLInformation.sFWPatches = sFWPatches; - tSLInformation.sDriverPatches = sDriverPatches; - tSLInformation.sBootLoaderPatches = sBootLoaderPatches; - - // init io callback - tSLInformation.ReadWlanInterruptPin = sReadWlanInterruptPin; - tSLInformation.WlanInterruptEnable = sWlanInterruptEnable; - tSLInformation.WlanInterruptDisable = sWlanInterruptDisable; - tSLInformation.WriteWlanPin = sWriteWlanPin; - - //init asynchronous events callback - tSLInformation.sWlanCB= sWlanCB; - - // By default TX Complete events are routed to host too - tSLInformation.InformHostOnTxComplete = 1; + tSLInformation.sFWPatches = sFWPatches; + tSLInformation.sDriverPatches = sDriverPatches; + tSLInformation.sBootLoaderPatches = sBootLoaderPatches; + + /* Init I/O callback */ + + tSLInformation.ReadWlanInterruptPin = sReadWlanInterruptPin; + tSLInformation.WlanInterruptEnable = sWlanInterruptEnable; + tSLInformation.WlanInterruptDisable = sWlanInterruptDisable; + tSLInformation.WriteWlanPin = sWriteWlanPin; + + /* Init asynchronous events callback */ + + tSLInformation.sWlanCB= sWlanCB; + + /* By default TX Complete events are routed to host too */ + + tSLInformation.InformHostOnTxComplete = 1; } -//***************************************************************************** -// -//! SpiReceiveHandler -//! -//! @param pvBuffer - pointer to the received data buffer -//! The function triggers Received event/data processing -//! -//! @param Pointer to the received data -//! @return none -//! -//! @brief The function triggers Received event/data processing. It is -//! called from the SPI library to receive the data -// -//***************************************************************************** +/***************************************************************************** + * Name: SpiReceiveHandler + * + * Input Parameters: + * pvBuffer - pointer to the received data buffer + * + * Returned Value: + * None + * + * Description: + * The function triggers Received event/data processing. It is + * called from the SPI library to receive the data + * + *****************************************************************************/ + void SpiReceiveHandler(void *pvBuffer) -{ - tSLInformation.usEventOrDataReceived = 1; - tSLInformation.pucReceivedData = (uint8_t *)pvBuffer; - - hci_unsolicited_event_handler(); +{ + tSLInformation.usEventOrDataReceived = 1; + tSLInformation.pucReceivedData = (uint8_t *)pvBuffer; + + hci_unsolicited_event_handler(); } +/***************************************************************************** + * Name: wlan_start + * + * Input Parameters: + * usPatchesAvailableAtHost - flag to indicate if patches available + * from host or from EEPROM. Due to the + * fact the patches are burn to the EEPROM + * using the patch programmer utility, the + * patches will be available from the EEPROM + * and not from the host. + * + * Returned Value: + * None + * + * Description: + * Start WLAN device. This function asserts the enable pin of + * the device (WLAN_EN), starting the HW initialization process. + * The function blocked until device Initialization is completed. + * Function also configure patches (FW, driver or bootloader) + * and calls appropriate device callbacks. + * + * NOTE: Prior calling the function wlan_init shall be called. + * WARNING: This function must be called after wlan_init and before any + * other wlan API + * + *****************************************************************************/ -//***************************************************************************** -// -//! wlan_start -//! -//! @param usPatchesAvailableAtHost - flag to indicate if patches available -//! from host or from EEPROM. Due to the -//! fact the patches are burn to the EEPROM -//! using the patch programmer utility, the -//! patches will be available from the EEPROM -//! and not from the host. -//! -//! @return none -//! -//! @brief Start WLAN device. This function asserts the enable pin of -//! the device (WLAN_EN), starting the HW initialization process. -//! The function blocked until device Initialization is completed. -//! Function also configure patches (FW, driver or bootloader) -//! and calls appropriate device callbacks. -//! -//! @Note Prior calling the function wlan_init shall be called. -//! @Warning This function must be called after wlan_init and before any -//! other wlan API -//! @sa wlan_init , wlan_stop -//! -// -//***************************************************************************** - -void -wlan_start(uint16_t usPatchesAvailableAtHost) +void wlan_start(uint16_t usPatchesAvailableAtHost) { - - unsigned long ulSpiIRQState; - - tSLInformation.NumberOfSentPackets = 0; - tSLInformation.NumberOfReleasedPackets = 0; - tSLInformation.usRxEventOpcode = 0; - tSLInformation.usNumberOfFreeBuffers = 0; - tSLInformation.usSlBufferLength = 0; - tSLInformation.usBufferSize = 0; - tSLInformation.usRxDataPending = 0; - tSLInformation.slTransmitDataError = 0; - tSLInformation.usEventOrDataReceived = 0; - tSLInformation.pucReceivedData = 0; - - // Allocate the memory for the RX/TX data transactions - tSLInformation.pucTxCommandBuffer = (uint8_t *)wlan_tx_buffer; - - // init spi - SpiOpen(SpiReceiveHandler); - - // Check the IRQ line - ulSpiIRQState = tSLInformation.ReadWlanInterruptPin(); - - // ASIC 1273 chip enable: toggle WLAN EN line - tSLInformation.WriteWlanPin( WLAN_ENABLE ); - - if (ulSpiIRQState) - { - // wait till the IRQ line goes low - while(tSLInformation.ReadWlanInterruptPin() != 0) - { - } - } - else - { - // wait till the IRQ line goes high and than low - while(tSLInformation.ReadWlanInterruptPin() == 0) - { - } - - while(tSLInformation.ReadWlanInterruptPin() != 0) - { - } - } - - SimpleLink_Init_Start(usPatchesAvailableAtHost); - - // Read Buffer's size and finish - hci_command_send(HCI_CMND_READ_BUFFER_SIZE, tSLInformation.pucTxCommandBuffer, 0); - SimpleLinkWaitEvent(HCI_CMND_READ_BUFFER_SIZE, 0); + unsigned long ulSpiIRQState; + + tSLInformation.NumberOfSentPackets = 0; + tSLInformation.NumberOfReleasedPackets = 0; + tSLInformation.usRxEventOpcode = 0; + tSLInformation.usNumberOfFreeBuffers = 0; + tSLInformation.usSlBufferLength = 0; + tSLInformation.usBufferSize = 0; + tSLInformation.usRxDataPending = 0; + tSLInformation.slTransmitDataError = 0; + tSLInformation.usEventOrDataReceived = 0; + tSLInformation.pucReceivedData = 0; + + /* Allocate the memory for the RX/TX data transactions */ + + tSLInformation.pucTxCommandBuffer = (uint8_t *)wlan_tx_buffer; + + /* Init spi */ + + SpiOpen(SpiReceiveHandler); + + /* Check the IRQ line */ + + ulSpiIRQState = tSLInformation.ReadWlanInterruptPin(); + + /* ASIC 1273 chip enable: toggle WLAN EN line */ + + tSLInformation.WriteWlanPin(WLAN_ENABLE); + + if (ulSpiIRQState) + { + /* Wait till the IRQ line goes low */ + + while (tSLInformation.ReadWlanInterruptPin() != 0) + { + } + } + else + { + /* Wait till the IRQ line goes high and than low */ + + while (tSLInformation.ReadWlanInterruptPin() == 0) + { + } + + while (tSLInformation.ReadWlanInterruptPin() != 0) + { + } + } + + SimpleLink_Init_Start(usPatchesAvailableAtHost); + + /* Read Buffer's size and finish */ + + hci_command_send(HCI_CMND_READ_BUFFER_SIZE, tSLInformation.pucTxCommandBuffer, 0); + SimpleLinkWaitEvent(HCI_CMND_READ_BUFFER_SIZE, 0); } +/***************************************************************************** + * Name: wlan_stop + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Description: + * Stop WLAN device by putting it into reset state. + * + *****************************************************************************/ -//***************************************************************************** -// -//! wlan_stop -//! -//! @param none -//! -//! @return none -//! -//! @brief Stop WLAN device by putting it into reset state. -//! -//! @sa wlan_start -// -//***************************************************************************** - -void -wlan_stop(void) +void wlan_stop(void) { - // ASIC 1273 chip disable - tSLInformation.WriteWlanPin( WLAN_DISABLE ); - - // Wait till IRQ line goes high... - while(tSLInformation.ReadWlanInterruptPin() == 0) - { - } - - // Free the used by WLAN Driver memory - if (tSLInformation.pucTxCommandBuffer) - { - tSLInformation.pucTxCommandBuffer = 0; - } - - SpiClose(); + /* ASIC 1273 chip disable */ + + tSLInformation.WriteWlanPin(WLAN_DISABLE); + + /* Wait till IRQ line goes high... */ + + while (tSLInformation.ReadWlanInterruptPin() == 0) + { + } + + /* Free the used by WLAN Driver memory */ + + if (tSLInformation.pucTxCommandBuffer) + { + tSLInformation.pucTxCommandBuffer = 0; + } + + SpiClose(); } +/***************************************************************************** + * Name: wlan_connect + * + * Input Parameters: + * sec_type security options: + * WLAN_SEC_UNSEC, + * WLAN_SEC_WEP (ASCII support only), + * WLAN_SEC_WPA or WLAN_SEC_WPA2 + * ssid up to 32 bytes and is ASCII SSID of the AP + * ssid_len length of the SSID + * bssid 6 bytes specified the AP bssid + * key up to 16 bytes specified the AP security key + * key_len key length + * + * Returned Value: + * On success, zero is returned. On error, negative is returned. + * Note that even though a zero is returned on success to trigger + * connection operation, it does not mean that CCC3000 is already + * connected. An asynchronous "Connected" event is generated when + * actual association process finishes and CC3000 is connected to + * the AP. If DHCP is set, An asynchronous "DHCP" event is + * generated when DHCP process is finish. + * + * Description: + * Connect to AP + * + * WARNING: Please Note that when connection to AP configured with security + * type WEP, please confirm that the key is set as ASCII and not + * as HEX. + * + *****************************************************************************/ -//***************************************************************************** -// -//! wlan_connect -//! -//! @param sec_type security options: -//! WLAN_SEC_UNSEC, -//! WLAN_SEC_WEP (ASCII support only), -//! WLAN_SEC_WPA or WLAN_SEC_WPA2 -//! @param ssid up to 32 bytes and is ASCII SSID of the AP -//! @param ssid_len length of the SSID -//! @param bssid 6 bytes specified the AP bssid -//! @param key up to 16 bytes specified the AP security key -//! @param key_len key length -//! -//! @return On success, zero is returned. On error, negative is returned. -//! Note that even though a zero is returned on success to trigger -//! connection operation, it does not mean that CCC3000 is already -//! connected. An asynchronous "Connected" event is generated when -//! actual association process finishes and CC3000 is connected to -//! the AP. If DHCP is set, An asynchronous "DHCP" event is -//! generated when DHCP process is finish. -//! -//! -//! @brief Connect to AP -//! @warning Please Note that when connection to AP configured with security -//! type WEP, please confirm that the key is set as ASCII and not -//! as HEX. -//! @sa wlan_disconnect -// -//***************************************************************************** - #ifndef CC3000_TINY_DRIVER -long -wlan_connect(unsigned long ulSecType, char *ssid, long ssid_len, - uint8_t *bssid, uint8_t *key, long key_len) +long wlan_connect(unsigned long ulSecType, char *ssid, long ssid_len, + uint8_t *bssid, uint8_t *key, long key_len) { - long ret; - uint8_t *ptr; - uint8_t *args; - uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0}; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in command buffer - args = UINT32_TO_STREAM(args, 0x0000001c); - args = UINT32_TO_STREAM(args, ssid_len); - args = UINT32_TO_STREAM(args, ulSecType); - args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len); - args = UINT32_TO_STREAM(args, key_len); - args = UINT16_TO_STREAM(args, 0); - - // padding shall be zeroed - if(bssid) - { - ARRAY_TO_STREAM(args, bssid, ETH_ALEN); - } - else - { - ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); - } - - ARRAY_TO_STREAM(args, ssid, ssid_len); - - if(key_len && key) - { - ARRAY_TO_STREAM(args, key, key_len); - } - - // Initiate a HCI command - hci_command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN + - ssid_len + key_len - 1); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_CONNECT, &ret); - errno = ret; - - return(ret); + long ret; + uint8_t *ptr; + uint8_t *args; + uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0}; + + ret = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_CMD); + + /* Fill in command buffer */ + + args = UINT32_TO_STREAM(args, 0x0000001c); + args = UINT32_TO_STREAM(args, ssid_len); + args = UINT32_TO_STREAM(args, ulSecType); + args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len); + args = UINT32_TO_STREAM(args, key_len); + args = UINT16_TO_STREAM(args, 0); + + /* Padding shall be zeroed */ + + if (bssid) + { + ARRAY_TO_STREAM(args, bssid, ETH_ALEN); + } + else + { + ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); + } + + ARRAY_TO_STREAM(args, ssid, ssid_len); + + if (key_len && key) + { + ARRAY_TO_STREAM(args, key, key_len); + } + + /* Initiate a HCI command */ + + hci_command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN + + ssid_len + key_len - 1); + + /* Wait for command complete event */ + + SimpleLinkWaitEvent(HCI_CMND_WLAN_CONNECT, &ret); + errno = ret; + + return ret; } #else -long -wlan_connect(char *ssid, long ssid_len) +long wlan_connect(char *ssid, long ssid_len) { - long ret; - uint8_t *ptr; - uint8_t *args; - uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0}; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in command buffer - args = UINT32_TO_STREAM(args, 0x0000001c); - args = UINT32_TO_STREAM(args, ssid_len); - args = UINT32_TO_STREAM(args, 0); - args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len); - args = UINT32_TO_STREAM(args, 0); - args = UINT16_TO_STREAM(args, 0); - - // padding shall be zeroed - ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); - ARRAY_TO_STREAM(args, ssid, ssid_len); - - // Initiate a HCI command - hci_command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN + - ssid_len - 1); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_CONNECT, &ret); - errno = ret; - - return(ret); + long ret; + uint8_t *ptr; + uint8_t *args; + uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0}; + + ret = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_CMD); + + /* Fill in command buffer */ + + args = UINT32_TO_STREAM(args, 0x0000001c); + args = UINT32_TO_STREAM(args, ssid_len); + args = UINT32_TO_STREAM(args, 0); + args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len); + args = UINT32_TO_STREAM(args, 0); + args = UINT16_TO_STREAM(args, 0); + + /* Padding shall be zeroed */ + + ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); + ARRAY_TO_STREAM(args, ssid, ssid_len); + + /* Initiate a HCI command */ + + hci_command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN + + ssid_len - 1); + + /* Wait for command complete event */ + + SimpleLinkWaitEvent(HCI_CMND_WLAN_CONNECT, &ret); + errno = ret; + + return ret; } #endif -//***************************************************************************** -// -//! wlan_disconnect -//! -//! @return 0 disconnected done, other CC3000 already disconnected -//! -//! @brief Disconnect connection from AP. -//! -//! @sa wlan_connect -// -//***************************************************************************** - -long -wlan_disconnect() +/***************************************************************************** + * Name: wlan_disconnect + * + * Input Parameters: + * None + * + * Returned Value: + * 0 disconnected done, other CC3000 already disconnected + * + * Description: + * Disconnect connection from AP. + * + *****************************************************************************/ + +long wlan_disconnect(void) { - long ret; - uint8_t *ptr; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - - hci_command_send(HCI_CMND_WLAN_DISCONNECT, ptr, 0); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_DISCONNECT, &ret); - errno = ret; - - return(ret); + long ret; + uint8_t *ptr; + + ret = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + + hci_command_send(HCI_CMND_WLAN_DISCONNECT, ptr, 0); + + /* Wait for command complete event */ + + SimpleLinkWaitEvent(HCI_CMND_WLAN_DISCONNECT, &ret); + errno = ret; + + return ret; } -//***************************************************************************** -// -//! wlan_ioctl_set_connection_policy -//! -//! @param should_connect_to_open_ap enable(1), disable(0) connect to any -//! available AP. This parameter corresponds to the configuration of -//! item # 3 in the brief description. -//! @param should_use_fast_connect enable(1), disable(0). if enabled, tries -//! to connect to the last connected AP. This parameter corresponds -//! to the configuration of item # 1 in the brief description. -//! @param auto_start enable(1), disable(0) auto connect -//! after reset and periodically reconnect if needed. This -//! configuration configures option 2 in the above description. -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief When auto is enabled, the device tries to connect according -//! the following policy: -//! 1) If fast connect is enabled and last connection is valid, -//! the device will try to connect to it without the scanning -//! procedure (fast). The last connection will be marked as -//! invalid, due to adding/removing profile. -//! 2) If profile exists, the device will try to connect it -//! (Up to seven profiles). -//! 3) If fast and profiles are not found, and open mode is -//! enabled, the device will try to connect to any AP. -//! * Note that the policy settings are stored in the CC3000 NVMEM. -//! -//! @sa wlan_add_profile , wlan_ioctl_del_profile -// -//***************************************************************************** - -long -wlan_ioctl_set_connection_policy(unsigned long should_connect_to_open_ap, - unsigned long ulShouldUseFastConnect, - unsigned long ulUseProfiles) +/***************************************************************************** + * Name: wlan_ioctl_set_connection_policy + * + * Input Parameters: + * should_connect_to_open_ap enable(1), disable(0) connect to any + * available AP. This parameter corresponds to the configuration of + * item # 3 in the brief description. + * should_use_fast_connect enable(1), disable(0). if enabled, tries + * to connect to the last connected AP. This parameter corresponds + * to the configuration of item # 1 in the brief description. + * auto_start enable(1), disable(0) auto connect + * after reset and periodically reconnect if needed. This + * configuration configures option 2 in the above description. + * + * Returned Value: + * On success, zero is returned. On error, -1 is returned + * + * Description: + * When auto is enabled, the device tries to connect according + * the following policy: + * 1) If fast connect is enabled and last connection is valid, + * the device will try to connect to it without the scanning + * procedure (fast). The last connection will be marked as + * invalid, due to adding/removing profile. + * 2) If profile exists, the device will try to connect it + * (Up to seven profiles). + * 3) If fast and profiles are not found, and open mode is + * enabled, the device will try to connect to any AP. + * * Note that the policy settings are stored in the CC3000 NVMEM. + * + *****************************************************************************/ + +long wlan_ioctl_set_connection_policy(unsigned long should_connect_to_open_ap, + unsigned long ulShouldUseFastConnect, + unsigned long ulUseProfiles) { - long ret; - uint8_t *ptr; - uint8_t *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (uint8_t *)(ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, should_connect_to_open_ap); - args = UINT32_TO_STREAM(args, ulShouldUseFastConnect); - args = UINT32_TO_STREAM(args, ulUseProfiles); - - // Initiate a HCI command - hci_command_send(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, - ptr, WLAN_SET_CONNECTION_POLICY_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, &ret); - - return(ret); + long ret; + uint8_t *ptr; + uint8_t *args; + + ret = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + args = (uint8_t *)(ptr + HEADERS_SIZE_CMD); + + /* Fill in HCI packet structure */ + + args = UINT32_TO_STREAM(args, should_connect_to_open_ap); + args = UINT32_TO_STREAM(args, ulShouldUseFastConnect); + args = UINT32_TO_STREAM(args, ulUseProfiles); + + /* Initiate a HCI command */ + + hci_command_send(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, + ptr, WLAN_SET_CONNECTION_POLICY_PARAMS_LEN); + + /* Wait for command complete event */ + + SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, &ret); + + return ret; } -//***************************************************************************** -// -//! wlan_add_profile -//! -//! @param ulSecType WLAN_SEC_UNSEC,WLAN_SEC_WEP,WLAN_SEC_WPA,WLAN_SEC_WPA2 -//! @param ucSsid ssid SSID up to 32 bytes -//! @param ulSsidLen ssid length -//! @param ucBssid bssid 6 bytes -//! @param ulPriority ulPriority profile priority. Lowest priority:0. -//! @param ulPairwiseCipher_Or_TxKeyLen key length for WEP security -//! @param ulGroupCipher_TxKeyIndex key index -//! @param ulKeyMgmt KEY management -//! @param ucPf_OrKey security key -//! @param ulPassPhraseLen security key length for WPA\WPA2 -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief When auto start is enabled, the device connects to -//! station from the profiles table. Up to 7 profiles are supported. -//! If several profiles configured the device choose the highest -//! priority profile, within each priority group, device will choose -//! profile based on security policy, signal strength, etc -//! parameters. All the profiles are stored in CC3000 NVMEM. -//! -//! @sa wlan_ioctl_del_profile -// -//***************************************************************************** +/***************************************************************************** + * Name: wlan_add_profile + * + * Input Parameters: + * ulSecType WLAN_SEC_UNSEC,WLAN_SEC_WEP,WLAN_SEC_WPA,WLAN_SEC_WPA2 + * ucSsid ssid SSID up to 32 bytes + * ulSsidLen ssid length + * ucBssid bssid 6 bytes + * ulPriority ulPriority profile priority. Lowest priority:0. + * ulPairwiseCipher_Or_TxKeyLen key length for WEP security + * ulGroupCipher_TxKeyIndex key index + * ulKeyMgmt KEY management + * ucPf_OrKey security key + * ulPassPhraseLen security key length for WPA\WPA2 + * + * Returned Value: + * On success, zero is returned. On error, -1 is returned + * + * Description: + * When auto start is enabled, the device connects to + * station from the profiles table. Up to 7 profiles are supported. + * If several profiles configured the device choose the highest + * priority profile, within each priority group, device will choose + * profile based on security policy, signal strength, etc + * parameters. All the profiles are stored in CC3000 NVMEM. + * + *****************************************************************************/ #ifndef CC3000_TINY_DRIVER -long -wlan_add_profile(unsigned long ulSecType, - uint8_t* ucSsid, - unsigned long ulSsidLen, - uint8_t *ucBssid, - unsigned long ulPriority, - unsigned long ulPairwiseCipher_Or_TxKeyLen, - unsigned long ulGroupCipher_TxKeyIndex, - unsigned long ulKeyMgmt, - uint8_t* ucPf_OrKey, - unsigned long ulPassPhraseLen) +long wlan_add_profile(unsigned long ulSecType, uint8_t* ucSsid, + unsigned long ulSsidLen, uint8_t *ucBssid, + unsigned long ulPriority, + unsigned long ulPairwiseCipher_Or_TxKeyLen, + unsigned long ulGroupCipher_TxKeyIndex, + unsigned long ulKeyMgmt, uint8_t* ucPf_OrKey, + unsigned long ulPassPhraseLen) { - uint16_t arg_len = 0; - long ret; - uint8_t *ptr; - long i = 0; - uint8_t *args; - uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0}; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - args = UINT32_TO_STREAM(args, ulSecType); - - // Setup arguments in accordance with the security type - switch (ulSecType) - { - //OPEN - case WLAN_SEC_UNSEC: - { - args = UINT32_TO_STREAM(args, 0x00000014); - args = UINT32_TO_STREAM(args, ulSsidLen); - args = UINT16_TO_STREAM(args, 0); - if(ucBssid) - { - ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN); - } - else - { - ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); - } - args = UINT32_TO_STREAM(args, ulPriority); - ARRAY_TO_STREAM(args, ucSsid, ulSsidLen); - - arg_len = WLAN_ADD_PROFILE_NOSEC_PARAM_LEN + ulSsidLen; - } - break; - - //WEP - case WLAN_SEC_WEP: - { - args = UINT32_TO_STREAM(args, 0x00000020); - args = UINT32_TO_STREAM(args, ulSsidLen); - args = UINT16_TO_STREAM(args, 0); - if(ucBssid) - { - ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN); - } - else - { - ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); - } - args = UINT32_TO_STREAM(args, ulPriority); - args = UINT32_TO_STREAM(args, 0x0000000C + ulSsidLen); - args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen); - args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex); - ARRAY_TO_STREAM(args, ucSsid, ulSsidLen); - - for(i = 0; i < 4; i++) - { - uint8_t *p = &ucPf_OrKey[i * ulPairwiseCipher_Or_TxKeyLen]; - - ARRAY_TO_STREAM(args, p, ulPairwiseCipher_Or_TxKeyLen); - } - - arg_len = WLAN_ADD_PROFILE_WEP_PARAM_LEN + ulSsidLen + - ulPairwiseCipher_Or_TxKeyLen * 4; - - } - break; - - //WPA - //WPA2 - case WLAN_SEC_WPA: - case WLAN_SEC_WPA2: - { - args = UINT32_TO_STREAM(args, 0x00000028); - args = UINT32_TO_STREAM(args, ulSsidLen); - args = UINT16_TO_STREAM(args, 0); - if(ucBssid) - { - ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN); - } - else - { - ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); - } - args = UINT32_TO_STREAM(args, ulPriority); - args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen); - args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex); - args = UINT32_TO_STREAM(args, ulKeyMgmt); - args = UINT32_TO_STREAM(args, 0x00000008 + ulSsidLen); - args = UINT32_TO_STREAM(args, ulPassPhraseLen); - ARRAY_TO_STREAM(args, ucSsid, ulSsidLen); - ARRAY_TO_STREAM(args, ucPf_OrKey, ulPassPhraseLen); - - arg_len = WLAN_ADD_PROFILE_WPA_PARAM_LEN + ulSsidLen + ulPassPhraseLen; - } - - break; - } - - // Initiate a HCI command - hci_command_send(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, - ptr, arg_len); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, &ret); - - return(ret); + uint16_t arg_len = 0; + long ret; + uint8_t *ptr; + long i = 0; + uint8_t *args; + uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0}; + + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_CMD); + + args = UINT32_TO_STREAM(args, ulSecType); + + /* Setup arguments in accordance with the security type */ + + switch (ulSecType) + { + /* OPEN */ + + case WLAN_SEC_UNSEC: + { + args = UINT32_TO_STREAM(args, 0x00000014); + args = UINT32_TO_STREAM(args, ulSsidLen); + args = UINT16_TO_STREAM(args, 0); + if (ucBssid) + { + ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN); + } + else + { + ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); + } + + args = UINT32_TO_STREAM(args, ulPriority); + ARRAY_TO_STREAM(args, ucSsid, ulSsidLen); + + arg_len = WLAN_ADD_PROFILE_NOSEC_PARAM_LEN + ulSsidLen; + } + break; + + /* WEP */ + + case WLAN_SEC_WEP: + { + args = UINT32_TO_STREAM(args, 0x00000020); + args = UINT32_TO_STREAM(args, ulSsidLen); + args = UINT16_TO_STREAM(args, 0); + if (ucBssid) + { + ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN); + } + else + { + ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); + } + + args = UINT32_TO_STREAM(args, ulPriority); + args = UINT32_TO_STREAM(args, 0x0000000C + ulSsidLen); + args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen); + args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex); + ARRAY_TO_STREAM(args, ucSsid, ulSsidLen); + + for (i = 0; i < 4; i++) + { + uint8_t *p = &ucPf_OrKey[i * ulPairwiseCipher_Or_TxKeyLen]; + + ARRAY_TO_STREAM(args, p, ulPairwiseCipher_Or_TxKeyLen); + } + + arg_len = WLAN_ADD_PROFILE_WEP_PARAM_LEN + ulSsidLen + + ulPairwiseCipher_Or_TxKeyLen * 4; + } + break; + + /*WPA, WPA2 */ + + case WLAN_SEC_WPA: + case WLAN_SEC_WPA2: + { + args = UINT32_TO_STREAM(args, 0x00000028); + args = UINT32_TO_STREAM(args, ulSsidLen); + args = UINT16_TO_STREAM(args, 0); + if (ucBssid) + { + ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN); + } + else + { + ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); + } + + args = UINT32_TO_STREAM(args, ulPriority); + args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen); + args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex); + args = UINT32_TO_STREAM(args, ulKeyMgmt); + args = UINT32_TO_STREAM(args, 0x00000008 + ulSsidLen); + args = UINT32_TO_STREAM(args, ulPassPhraseLen); + ARRAY_TO_STREAM(args, ucSsid, ulSsidLen); + ARRAY_TO_STREAM(args, ucPf_OrKey, ulPassPhraseLen); + + arg_len = WLAN_ADD_PROFILE_WPA_PARAM_LEN + ulSsidLen + ulPassPhraseLen; + } + break; + } + + /* Initiate a HCI command */ + + hci_command_send(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, + ptr, arg_len); + + /* Wait for command complete event */ + + SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, &ret); + + return ret; } #else -long -wlan_add_profile(unsigned long ulSecType, - uint8_t * ucSsid, - uint8_t ulSsidLen, - uint8_t *ucBssid, - unsigned long ulPriority, - unsigned long ulPairwiseCipher_Or_TxKeyLen, - unsigned long ulGroupCipher_TxKeyIndex, - unsigned long ulKeyMgmt, - uint8_t * ucPf_OrKey, - unsigned long ulPassPhraseLen) +long wlan_add_profile(unsigned long ulSecType, uint8_t * ucSsid, uint8_t ulSsidLen, + uint8_t *ucBssid, unsigned long ulPriority, + unsigned long ulPairwiseCipher_Or_TxKeyLen, + unsigned long ulGroupCipher_TxKeyIndex, + unsigned long ulKeyMgmt, uint8_t * ucPf_OrKey, + unsigned long ulPassPhraseLen) { - return -1; + return -1; } #endif -//***************************************************************************** -// -//! wlan_ioctl_del_profile -//! -//! @param index number of profile to delete -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Delete WLAN profile -//! -//! @Note In order to delete all stored profile, set index to 255. -//! -//! @sa wlan_add_profile -// -//***************************************************************************** - -long -wlan_ioctl_del_profile(unsigned long ulIndex) +/***************************************************************************** + * Name: wlan_ioctl_del_profile + * + * Input Parameters: + * index number of profile to delete + * + * Returned Value: + * On success, zero is returned. On error, -1 is returned + * + * Description: + * Delete WLAN profile + * + * @Note In order to delete all stored profile, set index to 255. + * + *****************************************************************************/ + +long wlan_ioctl_del_profile(unsigned long ulIndex) { - long ret; - uint8_t *ptr; - uint8_t *args; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (uint8_t *)(ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, ulIndex); - ret = EFAIL; - - // Initiate a HCI command - hci_command_send(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, - ptr, WLAN_DEL_PROFILE_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, &ret); - - return(ret); + long ret; + uint8_t *ptr; + uint8_t *args; + + ptr = tSLInformation.pucTxCommandBuffer; + args = (uint8_t *)(ptr + HEADERS_SIZE_CMD); + + /* Fill in HCI packet structure */ + + args = UINT32_TO_STREAM(args, ulIndex); + ret = EFAIL; + + /* Initiate a HCI command */ + + hci_command_send(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, + ptr, WLAN_DEL_PROFILE_PARAMS_LEN); + + /* Wait for command complete event */ + + SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, &ret); + + return ret; } -//***************************************************************************** -// -//! wlan_ioctl_get_scan_results -//! -//! @param[in] scan_timeout parameter not supported -//! @param[out] ucResults scan results (_wlan_full_scan_results_args_t) -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Gets entry from scan result table. -//! The scan results are returned one by one, and each entry -//! represents a single AP found in the area. The following is a -//! format of the scan result: -//! - 4 Bytes: number of networks found -//! - 4 Bytes: The status of the scan: 0 - aged results, -//! 1 - results valid, 2 - no results -//! - 42 bytes: Result entry, where the bytes are arranged as follows: -//! -//! - 1 bit isValid - is result valid or not -//! - 7 bits rssi - RSSI value; -//! - 2 bits: securityMode - security mode of the AP: -//! 0 - Open, 1 - WEP, 2 WPA, 3 WPA2 -//! - 6 bits: SSID name length -//! - 2 bytes: the time at which the entry has entered into -//! scans result table -//! - 32 bytes: SSID name -//! - 6 bytes: BSSID -//! -//! @Note scan_timeout, is not supported on this version. -//! -//! @sa wlan_ioctl_set_scan_params -// -//***************************************************************************** +/***************************************************************************** + * Name: wlan_ioctl_get_scan_results + * + * Input Parameters: + * scan_timeout parameter not supported + * ucResults scan results (_wlan_full_scan_results_args_t) + * + * Returned Value: + * On success, zero is returned. On error, -1 is returned + * + * Description: + * Gets entry from scan result table. + * The scan results are returned one by one, and each entry + * represents a single AP found in the area. The following is a + * format of the scan result: + * - 4 Bytes: number of networks found + * - 4 Bytes: The status of the scan: 0 - aged results, + * 1 - results valid, 2 - no results + * - 42 bytes: Result entry, where the bytes are arranged as follows: + * - 1 bit isValid - is result valid or not + * - 7 bits rssi - RSSI value; + * - 2 bits: securityMode - security mode of the AP: + * 0 - Open, 1 - WEP, 2 WPA, 3 WPA2 + * - 6 bits: SSID name length + * - 2 bytes: the time at which the entry has entered into + * scans result table + * - 32 bytes: SSID name + * - 6 bytes: BSSID + * + * NOTE: scan_timeout, is not supported on this version. + * + *****************************************************************************/ #ifndef CC3000_TINY_DRIVER -long -wlan_ioctl_get_scan_results(unsigned long ulScanTimeout, - uint8_t *ucResults) +long wlan_ioctl_get_scan_results(unsigned long ulScanTimeout, uint8_t *ucResults) { - uint8_t *ptr; - uint8_t *args; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, ulScanTimeout); - - // Initiate a HCI command - hci_command_send(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, - ptr, WLAN_GET_SCAN_RESULTS_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, ucResults); - - return(0); + uint8_t *ptr; + uint8_t *args; + + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_CMD); + + /* Fill in temporary command buffer */ + + args = UINT32_TO_STREAM(args, ulScanTimeout); + + /* Initiate a HCI command */ + + hci_command_send(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, + ptr, WLAN_GET_SCAN_RESULTS_PARAMS_LEN); + + /* Wait for command complete event */ + + SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, ucResults); + + return 0; } #endif -//***************************************************************************** -// -//! wlan_ioctl_set_scan_params -//! -//! @param uiEnable - start/stop application scan: -//! 1 = start scan with default interval value of 10 min. -//! in order to set a different scan interval value apply the value -//! in milliseconds. minimum 1 second. 0=stop). Wlan reset -//! (wlan_stop() wlan_start()) is needed when changing scan interval -//! value. Saved: No -//! @param uiMinDwellTime minimum dwell time value to be used for each -//! channel, in milliseconds. Saved: yes -//! Recommended Value: 100 (Default: 20) -//! @param uiMaxDwellTime maximum dwell time value to be used for each -//! channel, in milliseconds. Saved: yes -//! Recommended Value: 100 (Default: 30) -//! @param uiNumOfProbeRequests max probe request between dwell time. -//! Saved: yes. Recommended Value: 5 (Default:2) -//! @param uiChannelMask bitwise, up to 13 channels (0x1fff). -//! Saved: yes. Default: 0x7ff -//! @param uiRSSIThreshold RSSI threshold. Saved: yes (Default: -80) -//! @param uiSNRThreshold NSR threshold. Saved: yes (Default: 0) -//! @param uiDefaultTxPower probe Tx power. Saved: yes (Default: 205) -//! @param aiIntervalList pointer to array with 16 entries (16 channels) -//! each entry (unsigned long) holds timeout between periodic scan -//! (connection scan) - in millisecond. Saved: yes. Default 2000ms. -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief start and stop scan procedure. Set scan parameters. -//! -//! @Note uiDefaultTxPower, is not supported on this version. -//! -//! @sa wlan_ioctl_get_scan_results -// -//***************************************************************************** +/***************************************************************************** + * Name: wlan_ioctl_set_scan_params + * + * Input Parameters: + * uiEnable - start/stop application scan: + * 1 = start scan with default interval value of 10 min. + * in order to set a different scan interval value apply the value + * in milliseconds. minimum 1 second. 0=stop). Wlan reset + * (wlan_stop() wlan_start()) is needed when changing scan interval + * value. Saved: No + * uiMinDwellTime minimum dwell time value to be used for each + * channel, in milliseconds. Saved: yes + * Recommended Value: 100 (Default: 20) + * uiMaxDwellTime maximum dwell time value to be used for each + * channel, in milliseconds. Saved: yes + * Recommended Value: 100 (Default: 30) + * uiNumOfProbeRequests max probe request between dwell time. + * Saved: yes. Recommended Value: 5 (Default:2) + * uiChannelMask bitwise, up to 13 channels (0x1fff). + * Saved: yes. Default: 0x7ff + * uiRSSIThreshold RSSI threshold. Saved: yes (Default: -80) + * uiSNRThreshold NSR threshold. Saved: yes (Default: 0) + * uiDefaultTxPower probe Tx power. Saved: yes (Default: 205) + * aiIntervalList pointer to array with 16 entries (16 channels) + * each entry (unsigned long) holds timeout between periodic scan + * (connection scan) - in millisecond. Saved: yes. Default 2000ms. + * + * Returned Value: + * On success, zero is returned. On error, -1 is returned + * + * Description: + * start and stop scan procedure. Set scan parameters. + * + * @Note uiDefaultTxPower, is not supported on this version. + * + *****************************************************************************/ #ifndef CC3000_TINY_DRIVER -long -wlan_ioctl_set_scan_params(unsigned long uiEnable, unsigned long uiMinDwellTime, - unsigned long uiMaxDwellTime, - unsigned long uiNumOfProbeRequests, - unsigned long uiChannelMask,long iRSSIThreshold, - unsigned long uiSNRThreshold, - unsigned long uiDefaultTxPower, - unsigned long *aiIntervalList) +long wlan_ioctl_set_scan_params(unsigned long uiEnable, + unsigned long uiMinDwellTime, + unsigned long uiMaxDwellTime, + unsigned long uiNumOfProbeRequests, + unsigned long uiChannelMask,long iRSSIThreshold, + unsigned long uiSNRThreshold, + unsigned long uiDefaultTxPower, + unsigned long *aiIntervalList) { - unsigned long uiRes; - uint8_t *ptr; - uint8_t *args; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, 36); - args = UINT32_TO_STREAM(args, uiEnable); - args = UINT32_TO_STREAM(args, uiMinDwellTime); - args = UINT32_TO_STREAM(args, uiMaxDwellTime); - args = UINT32_TO_STREAM(args, uiNumOfProbeRequests); - args = UINT32_TO_STREAM(args, uiChannelMask); - args = UINT32_TO_STREAM(args, iRSSIThreshold); - args = UINT32_TO_STREAM(args, uiSNRThreshold); - args = UINT32_TO_STREAM(args, uiDefaultTxPower); - ARRAY_TO_STREAM(args, aiIntervalList, sizeof(unsigned long) * - SL_SET_SCAN_PARAMS_INTERVAL_LIST_SIZE); - - // Initiate a HCI command - hci_command_send(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM, - ptr, WLAN_SET_SCAN_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM, &uiRes); - - return(uiRes); + unsigned long uiRes; + uint8_t *ptr; + uint8_t *args; + + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_CMD); + + /* Fill in temporary command buffer */ + + args = UINT32_TO_STREAM(args, 36); + args = UINT32_TO_STREAM(args, uiEnable); + args = UINT32_TO_STREAM(args, uiMinDwellTime); + args = UINT32_TO_STREAM(args, uiMaxDwellTime); + args = UINT32_TO_STREAM(args, uiNumOfProbeRequests); + args = UINT32_TO_STREAM(args, uiChannelMask); + args = UINT32_TO_STREAM(args, iRSSIThreshold); + args = UINT32_TO_STREAM(args, uiSNRThreshold); + args = UINT32_TO_STREAM(args, uiDefaultTxPower); + ARRAY_TO_STREAM(args, aiIntervalList, sizeof(unsigned long) * + SL_SET_SCAN_PARAMS_INTERVAL_LIST_SIZE); + + /* Initiate a HCI command */ + + hci_command_send(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM, + ptr, WLAN_SET_SCAN_PARAMS_LEN); + + /* Wait for command complete event */ + + SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM, &uiRes); + + return uiRes; } #endif -//***************************************************************************** -// -//! wlan_set_event_mask -//! -//! @param mask mask option: -//! HCI_EVNT_WLAN_UNSOL_CONNECT connect event -//! HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event -//! HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE smart config done -//! HCI_EVNT_WLAN_UNSOL_INIT init done -//! HCI_EVNT_WLAN_UNSOL_DHCP dhcp event report -//! HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report -//! HCI_EVNT_WLAN_KEEPALIVE keepalive -//! HCI_EVNT_WLAN_TX_COMPLETE - disable information on end of transmission -//! Saved: no. -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Mask event according to bit mask. In case that event is -//! masked (1), the device will not send the masked event to host. -// -//***************************************************************************** - -long -wlan_set_event_mask(unsigned long ulMask) +/***************************************************************************** + * Name: wlan_set_event_mask + * + * Input Parameters: + * mask mask option: + * HCI_EVNT_WLAN_UNSOL_CONNECT connect event + * HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event + * HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE smart config done + * HCI_EVNT_WLAN_UNSOL_INIT init done + * HCI_EVNT_WLAN_UNSOL_DHCP dhcp event report + * HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report + * HCI_EVNT_WLAN_KEEPALIVE keepalive + * HCI_EVNT_WLAN_TX_COMPLETE - disable information on end of transmission + * Saved: no. + * + * Returned Value: + * On success, zero is returned. On error, -1 is returned + * + * Description: + * Mask event according to bit mask. In case that event is + * masked (1), the device will not send the masked event to host. + * + *****************************************************************************/ + +long wlan_set_event_mask(unsigned long ulMask) { - long ret; - uint8_t *ptr; - uint8_t *args; - - - if ((ulMask & HCI_EVNT_WLAN_TX_COMPLETE) == HCI_EVNT_WLAN_TX_COMPLETE) - { - tSLInformation.InformHostOnTxComplete = 0; - - // Since an event is a virtual event - i.e. it is not coming from CC3000 - // there is no need to send anything to the device if it was an only event - if (ulMask == HCI_EVNT_WLAN_TX_COMPLETE) - { - return 0; - } - - ulMask &= ~HCI_EVNT_WLAN_TX_COMPLETE; - ulMask |= HCI_EVNT_WLAN_UNSOL_BASE; - } - else - { - tSLInformation.InformHostOnTxComplete = 1; - } - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (uint8_t *)(ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, ulMask); - - // Initiate a HCI command - hci_command_send(HCI_CMND_EVENT_MASK, - ptr, WLAN_SET_MASK_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_EVENT_MASK, &ret); - - return(ret); + long ret; + uint8_t *ptr; + uint8_t *args; + + if ((ulMask & HCI_EVNT_WLAN_TX_COMPLETE) == HCI_EVNT_WLAN_TX_COMPLETE) + { + tSLInformation.InformHostOnTxComplete = 0; + + /* Since an event is a virtual event - i.e. it is not coming from CC3000 + * there is no need to send anything to the device if it was an only event + */ + + if (ulMask == HCI_EVNT_WLAN_TX_COMPLETE) + { + return 0; + } + + ulMask &= ~HCI_EVNT_WLAN_TX_COMPLETE; + ulMask |= HCI_EVNT_WLAN_UNSOL_BASE; + } + else + { + tSLInformation.InformHostOnTxComplete = 1; + } + + ret = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + args = (uint8_t *)(ptr + HEADERS_SIZE_CMD); + + /* Fill in HCI packet structure */ + + args = UINT32_TO_STREAM(args, ulMask); + + /* Initiate a HCI command */ + + hci_command_send(HCI_CMND_EVENT_MASK, + ptr, WLAN_SET_MASK_PARAMS_LEN); + + /* Wait for command complete event */ + + SimpleLinkWaitEvent(HCI_CMND_EVENT_MASK, &ret); + + return ret; } -//***************************************************************************** -// -//! wlan_ioctl_statusget -//! -//! @param none -//! -//! @return WLAN_STATUS_DISCONNECTED, WLAN_STATUS_SCANING, -//! STATUS_CONNECTING or WLAN_STATUS_CONNECTED -//! -//! @brief get wlan status: disconnected, scanning, connecting or connected -// -//***************************************************************************** +/***************************************************************************** + * Name: wlan_ioctl_statusget + * + * Input Parameters: + * None + * + * Returned Value: + * WLAN_STATUS_DISCONNECTED, WLAN_STATUS_SCANING, + * STATUS_CONNECTING or WLAN_STATUS_CONNECTED + * + * Description: + * get wlan status: disconnected, scanning, connecting or connected + * + *****************************************************************************/ #ifndef CC3000_TINY_DRIVER -long -wlan_ioctl_statusget(void) +long wlan_ioctl_statusget(void) { - long ret; - uint8_t *ptr; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - - hci_command_send(HCI_CMND_WLAN_IOCTL_STATUSGET, - ptr, 0); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_STATUSGET, &ret); - - return(ret); + long ret; + uint8_t *ptr; + + ret = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + + hci_command_send(HCI_CMND_WLAN_IOCTL_STATUSGET, + ptr, 0); + + /* Wait for command complete event */ + + SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_STATUSGET, &ret); + + return ret; } #endif -//***************************************************************************** -// -//! wlan_smart_config_start -//! -//! @param algoEncryptedFlag indicates whether the information is encrypted -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Start to acquire device profile. The device acquire its own -//! profile, if profile message is found. The acquired AP information -//! is stored in CC3000 EEPROM only in case AES128 encryption is used. -//! In case AES128 encryption is not used, a profile is created by -//! CC3000 internally. -//! -//! @Note An asynchronous event - Smart Config Done will be generated as soon -//! as the process finishes successfully. -//! -//! @sa wlan_smart_config_set_prefix , wlan_smart_config_stop -// -//***************************************************************************** - -long -wlan_smart_config_start(unsigned long algoEncryptedFlag) +/***************************************************************************** + * Name: wlan_smart_config_start + * + * Input Parameters: + * algoEncryptedFlag indicates whether the information is encrypted + * + * Returned Value: + * On success, zero is returned. On error, -1 is returned + * + * Description: + * Start to acquire device profile. The device acquire its own + * profile, if profile message is found. The acquired AP information + * is stored in CC3000 EEPROM only in case AES128 encryption is used. + * In case AES128 encryption is not used, a profile is created by + * CC3000 internally. + * + * @Note An asynchronous event - Smart Config Done will be generated as soon + * as the process finishes successfully. + * + *****************************************************************************/ + +long wlan_smart_config_start(unsigned long algoEncryptedFlag) { - long ret; - uint8_t *ptr; - uint8_t *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (uint8_t *)(ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, algoEncryptedFlag); - ret = EFAIL; - - hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, ptr, - WLAN_SMART_CONFIG_START_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, &ret); - - return(ret); + long ret; + uint8_t *ptr; + uint8_t *args; + + ret = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + args = (uint8_t *)(ptr + HEADERS_SIZE_CMD); + + /* Fill in HCI packet structure */ + + args = UINT32_TO_STREAM(args, algoEncryptedFlag); + ret = EFAIL; + + hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, ptr, + WLAN_SMART_CONFIG_START_PARAMS_LEN); + + /* Wait for command complete event */ + + SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, &ret); + + return ret; } -//***************************************************************************** -// -//! wlan_smart_config_stop -//! -//! @param algoEncryptedFlag indicates whether the information is encrypted -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Stop the acquire profile procedure -//! -//! @sa wlan_smart_config_start , wlan_smart_config_set_prefix -// -//***************************************************************************** - -long -wlan_smart_config_stop(void) +/***************************************************************************** + * Name: wlan_smart_config_stop + * + * Input Parameters: + * algoEncryptedFlag indicates whether the information is encrypted + * + * Returned Value: + * On success, zero is returned. On error, -1 is returned + * + * Description: + * Stop the acquire profile procedure + * + *****************************************************************************/ + +long wlan_smart_config_stop(void) { - long ret; - uint8_t *ptr; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - - hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, ptr, 0); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, &ret); - - return(ret); + long ret; + uint8_t *ptr; + + ret = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + + hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, ptr, 0); + + /* Wait for command complete event */ + + SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, &ret); + + return ret; } -//***************************************************************************** -// -//! wlan_smart_config_set_prefix -//! -//! @param newPrefix 3 bytes identify the SSID prefix for the Smart Config. -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Configure station ssid prefix. The prefix is used internally -//! in CC3000. It should always be TTT. -//! -//! @Note The prefix is stored in CC3000 NVMEM -//! -//! @sa wlan_smart_config_start , wlan_smart_config_stop -// -//***************************************************************************** - -long -wlan_smart_config_set_prefix(char* cNewPrefix) +/***************************************************************************** + * Name: wlan_smart_config_set_prefix + * + * Input Parameters: + * newPrefix 3 bytes identify the SSID prefix for the Smart Config. + * + * Returned Value: + * On success, zero is returned. On error, -1 is returned + * + * Description: + * Configure station ssid prefix. The prefix is used internally + * in CC3000. It should always be TTT. + * + * @Note The prefix is stored in CC3000 NVMEM + * + *****************************************************************************/ + +long wlan_smart_config_set_prefix(char* cNewPrefix) { - long ret; - uint8_t *ptr; - uint8_t *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - if (cNewPrefix == NULL) - return ret; - else // with the new Smart Config, prefix must be TTT - { - *cNewPrefix = 'T'; - *(cNewPrefix + 1) = 'T'; - *(cNewPrefix + 2) = 'T'; - } - - ARRAY_TO_STREAM(args, cNewPrefix, SL_SIMPLE_CONFIG_PREFIX_LENGTH); - - hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, ptr, - SL_SIMPLE_CONFIG_PREFIX_LENGTH); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, &ret); - - return(ret); -} + long ret; + uint8_t *ptr; + uint8_t *args; -//***************************************************************************** -// -//! wlan_smart_config_process -//! -//! @param none -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief process the acquired data and store it as a profile. The acquired -//! AP information is stored in CC3000 EEPROM encrypted. -//! The encrypted data is decrypted and stored as a profile. -//! behavior is as defined by connection policy. -// -//***************************************************************************** + ret = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_CMD); + if (cNewPrefix == NULL) + { + return ret; + } + + /* With the new Smart Config, prefix must be TTT */ + + else + { + *cNewPrefix = 'T'; + *(cNewPrefix + 1) = 'T'; + *(cNewPrefix + 2) = 'T'; + } + + ARRAY_TO_STREAM(args, cNewPrefix, SL_SIMPLE_CONFIG_PREFIX_LENGTH); + + hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, ptr, + SL_SIMPLE_CONFIG_PREFIX_LENGTH); + + /* Wait for command complete event */ + + SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, &ret); + + return ret; +} + +/***************************************************************************** + * Name: wlan_smart_config_process + * + * Input Parameters: + * None + * + * Returned Value: + * On success, zero is returned. On error, -1 is returned + * + * Description: + * process the acquired data and store it as a profile. The acquired + * AP information is stored in CC3000 EEPROM encrypted. + * The encrypted data is decrypted and stored as a profile. + * behavior is as defined by connection policy. + * + *****************************************************************************/ #ifndef CC3000_UNENCRYPTED_SMART_CONFIG -long -wlan_smart_config_process() +long wlan_smart_config_process() { - signed long returnValue; - unsigned long ssidLen, keyLen; - uint8_t *decKeyPtr; - uint8_t *ssidPtr; - - // read the key from EEPROM - fileID 12 - returnValue = aes_read_key(akey); - - if (returnValue != 0) - return returnValue; - - // read the received data from fileID #13 and parse it according to the followings: - // 1) SSID LEN - not encrypted - // 2) SSID - not encrypted - // 3) KEY LEN - not encrypted. always 32 bytes long - // 4) Security type - not encrypted - // 5) KEY - encrypted together with true key length as the first byte in KEY - // to elaborate, there are two corner cases: - // 1) the KEY is 32 bytes long. In this case, the first byte does not represent KEY length - // 2) the KEY is 31 bytes long. In this case, the first byte represent KEY length and equals 31 - returnValue = nvmem_read(NVMEM_SHARED_MEM_FILEID, SMART_CONFIG_PROFILE_SIZE, 0, profileArray); - - if (returnValue != 0) - return returnValue; - - ssidPtr = &profileArray[1]; - - ssidLen = profileArray[0]; - - decKeyPtr = &profileArray[profileArray[0] + 3]; - - aes_decrypt(decKeyPtr, akey); - if (profileArray[profileArray[0] + 1] > 16) - aes_decrypt((uint8_t *)(decKeyPtr + 16), akey); - - if (*(uint8_t *)(decKeyPtr +31) != 0) - { - if (*decKeyPtr == 31) - { - keyLen = 31; - decKeyPtr++; - } - else - { - keyLen = 32; - } - } - else - { - keyLen = *decKeyPtr; - decKeyPtr++; - } - - // add a profile - switch (profileArray[profileArray[0] + 2]) - { - case WLAN_SEC_UNSEC://None - { - returnValue = wlan_add_profile(profileArray[profileArray[0] + 2], // security type - ssidPtr, // SSID - ssidLen, // SSID length - NULL, // BSSID - 1, // Priority - 0, 0, 0, 0, 0); - - break; - } - - case WLAN_SEC_WEP://WEP - { - returnValue = wlan_add_profile(profileArray[profileArray[0] + 2], // security type - ssidPtr, // SSID - ssidLen, // SSID length - NULL, // BSSID - 1, // Priority - keyLen, // KEY length - 0, // KEY index - 0, - decKeyPtr, // KEY - 0); - - break; - } - - case WLAN_SEC_WPA://WPA - case WLAN_SEC_WPA2://WPA2 - { - returnValue = wlan_add_profile(WLAN_SEC_WPA2, // security type - ssidPtr, - ssidLen, - NULL, // BSSID - 1, // Priority - 0x18, // PairwiseCipher - 0x1e, // GroupCipher - 2, // KEY management - decKeyPtr, // KEY - keyLen); // KEY length - - break; - } - } - - return returnValue; + signed long returnValue; + unsigned long ssidLen, keyLen; + uint8_t *decKeyPtr; + uint8_t *ssidPtr; + + /* Read the key from EEPROM - fileID 12 */ + + returnValue = aes_read_key(akey); + + if (returnValue != 0) + { + return returnValue; + } + + /* Read the received data from fileID #13 and parse it according to the followings: + * 1) SSID LEN - not encrypted + * 2) SSID - not encrypted + * 3) KEY LEN - not encrypted. always 32 bytes long + * 4) Security type - not encrypted + * 5) KEY - encrypted together with true key length as the first byte in KEY + * to elaborate, there are two corner cases: + * 1) the KEY is 32 bytes long. In this case, the first byte does not represent + * KEY length + * 2) the KEY is 31 bytes long. In this case, the first byte represent KEY + * length and equals 31 + */ + + returnValue = nvmem_read(NVMEM_SHARED_MEM_FILEID, SMART_CONFIG_PROFILE_SIZE, + 0, profileArray); + + if (returnValue != 0) + { + return returnValue; + } + + ssidPtr = &profileArray[1]; + + ssidLen = profileArray[0]; + + decKeyPtr = &profileArray[profileArray[0] + 3]; + + aes_decrypt(decKeyPtr, akey); + if (profileArray[profileArray[0] + 1] > 16) + { + aes_decrypt((uint8_t *)(decKeyPtr + 16), akey); + } + + if (*(uint8_t *)(decKeyPtr +31) != 0) + { + if (*decKeyPtr == 31) + { + keyLen = 31; + decKeyPtr++; + } + else + { + keyLen = 32; + } + } + else + { + keyLen = *decKeyPtr; + decKeyPtr++; + } + + /* Add a profile */ + + switch (profileArray[profileArray[0] + 2]) + { + case WLAN_SEC_UNSEC: /* None */ + { + returnValue = wlan_add_profile(profileArray[profileArray[0] + 2], /* Security type */ + ssidPtr, /* SSID */ + ssidLen, /* SSID length */ + NULL, /* BSSID */ + 1, /* Priority */ + 0, 0, 0, 0, 0); + break; + } + + case WLAN_SEC_WEP: /* WEP */ + { + returnValue = wlan_add_profile(profileArray[profileArray[0] + 2], /* Security type */ + ssidPtr, /* SSID */ + ssidLen, /* SSID length */ + NULL, /* BSSID */ + 1, /* Priority */ + keyLen, /* KEY length */ + 0, /* KEY index */ + 0, + decKeyPtr, /* KEY */ + 0); + break; + } + + case WLAN_SEC_WPA: /* WPA */ + case WLAN_SEC_WPA2: /* WPA2 */ + { + returnValue = wlan_add_profile(WLAN_SEC_WPA2, /* Security type */ + ssidPtr, + ssidLen, + NULL, /* BSSID */ + 1, /* Priority */ + 0x18, /* PairwiseCipher */ + 0x1e, /* GroupCipher */ + 2, /* KEY management */ + decKeyPtr, /* KEY */ + keyLen); /* KEY length */ + break; + } + } + + return returnValue; } -#endif //CC3000_UNENCRYPTED_SMART_CONFIG - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** +#endif /* CC3000_UNENCRYPTED_SMART_CONFIG */ -- cgit v1.2.3