A Port of TI's Webserver for the CC3000
Revision 0:6ad60d78b315, committed 2013-09-14
- Comitter:
- dflet
- Date:
- Sat Sep 14 17:38:41 2013 +0000
- Child:
- 1:7a4efebd6e44
- Commit message:
- Mostly working will serve the default pages index.html and config.html, but config.html is not woring at present.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Board/Board.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,168 @@
+#include "mbed.h"
+
+DigitalOut ind1(LED1);
+DigitalOut ind2(LED2);
+DigitalOut ind3(LED3);
+DigitalOut ind4(LED4);
+
+
+
+
+//*****************************************************************************
+//
+//! turnLedOn
+//!
+//! @param ledNum is the LED Number
+//!
+//! @return none
+//!
+//! @brief Turns a specific LED on
+//
+//*****************************************************************************
+void turnLedOn(char ledNum)
+{
+ switch(ledNum)
+ {
+ case 1:
+ ind1 = 1;
+ break;
+ case 2:
+ ind2 = 1;
+ break;
+ case 3:
+ ind3 = 1;
+ break;
+ case 4:
+ ind4 = 1;
+ break;
+ case 5:
+ ind1 = 1;
+ break;
+ case 6:
+ ind4 = 1;
+ break;
+ case 7:
+
+ break;
+ case 8:
+
+ break;
+ }
+
+}
+
+//*****************************************************************************
+//
+//! turnLedOff
+//!
+//! @param ledNum is the LED Number
+//!
+//! @return none
+//!
+//! @brief Turns a specific LED Off
+//
+//*****************************************************************************
+void turnLedOff(char ledNum)
+{
+ switch(ledNum)
+ {
+ case 1:
+ ind1 = 0;
+ break;
+ case 2:
+ ind2 = 0;
+ break;
+ case 3:
+ ind3 = 0;
+ break;
+ case 4:
+ ind4 = 0;
+ break;
+ case 5:
+ ind1 = 0;
+ break;
+ case 6:
+ ind4 = 0;
+ break;
+ case 7:
+
+ break;
+ case 8:
+
+ break;
+ }
+}
+
+//*****************************************************************************
+//
+//! toggleLed
+//!
+//! @param ledNum is the LED Number
+//!
+//! @return none
+//!
+//! @brief Toggles a board LED
+//
+//*****************************************************************************
+
+void toggleLed(char ledNum)
+{
+ switch(ledNum)
+ {
+ case 1:
+ ind1 = 0;
+ break;
+ case 2:
+ ind2 = 0;
+ break;
+ case 3:
+ ind3 = 0;
+ break;
+ case 4:
+ ind4 = 0;
+ break;
+ case 5:
+ ind1 = 0;
+ break;
+ case 6:
+ ind4 = 0;
+ break;
+ case 7:
+
+ break;
+ case 8:
+
+ break;
+ }
+
+}
+
+/***************************************************************************//**
+ * @brief GetLEDStatus
+ * @param none
+ * @return A 1 byte containing the status of LEDS
+ ******************************************************************************/
+
+uint8_t GetLEDStatus()
+{
+ uint8_t status = 0;
+
+ if(ind1)
+ status |= (1 << 0);
+ if(ind2)
+ status |= (1 << 1);
+ if(ind3)
+ status |= ( 1<< 2);
+ if(ind4)
+ status |= (1 << 3);
+ //if(LED145678_PORT_OUT & BIT2)
+ // status |= (1 << 4);
+ //if(LED145678_PORT_OUT & BIT3)
+ // status |= (1 << 5);
+ //if(LED145678_PORT_OUT & BIT4)
+ // status |= (1 << 6);
+ //if(LED145678_PORT_OUT & BIT5)
+ // status |= (1 << 7);
+
+ return status;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Board/Board.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,36 @@
+#ifndef BOARD_H
+#define BOARD_H
+
+
+typedef enum
+{
+ NO_LED,
+ ind1,
+ ind2,
+ ind3,
+ ind4,
+ LED5,
+ LED6,
+ LED7,
+ LED8
+} ledEnum;
+
+typedef enum
+{
+ NO_LED_IND = NO_LED,
+ CC3000_ON_IND = ind1,
+ CC3000_ASSOCIATED_IND = ind2,
+ CC3000_IP_ALLOC_IND = ind3,
+ CC3000_SERVER_INIT_IND = ind4,
+ CC3000_CLIENT_CONNECTED_IND = ind4,
+ CC3000_SENDING_DATA_IND = ind3,
+ CC3000_UNUSED1_IND = LED7,
+ CC3000_FTC_IND = LED8
+} ledNames;
+
+void turnLedOn(char ledNum);
+void turnLedOff(char ledNum);
+void toggleLed(char ledNum);
+uint8_t GetLEDStatus(void);
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CC3000HostDriver/cc3000_common.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,165 @@
+/*****************************************************************************
+*
+* 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
+//! @{
+//
+//*****************************************************************************
+/******************************************************************************
+ *
+ * Include files
+ *
+ *****************************************************************************/
+#include "cc3000_common.h"
+#include "socket.h"
+#include "wlan.h"
+#include "evnt_handler.h"
+
+//*****************************************************************************
+//
+//! __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
+}
+
+
+
+//*****************************************************************************
+//
+//! 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.
+//
+//*****************************************************************************
+
+unsigned char* UINT32_TO_STREAM_f (unsigned char *p, unsigned long u32)
+{
+ *(p)++ = (unsigned char)(u32);
+ *(p)++ = (unsigned char)((u32) >> 8);
+ *(p)++ = (unsigned char)((u32) >> 16);
+ *(p)++ = (unsigned char)((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.
+//
+//*****************************************************************************
+
+unsigned char* UINT16_TO_STREAM_f (unsigned char *p, unsigned short u16)
+{
+ *(p)++ = (unsigned char)(u16);
+ *(p)++ = (unsigned char)((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.
+//
+//*****************************************************************************
+
+unsigned short STREAM_TO_UINT16_f(char* p, unsigned short offset)
+{
+ return (unsigned short)((unsigned short)((unsigned short)
+ (*(p + offset + 1)) << 8) + (unsigned short)(*(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.
+//
+//*****************************************************************************
+
+unsigned long STREAM_TO_UINT32_f(char* p, unsigned short 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.
+//! @}
+//
+//*****************************************************************************
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CC3000HostDriver/cc3000_common.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,358 @@
+/*****************************************************************************
+*
+* cc3000_common.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 __COMMON_H__
+#define __COMMON_H__
+
+//******************************************************************************
+// Include files
+//******************************************************************************
+#include <stdlib.h>
+#include <errno.h>
+#include <stdint.h>
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//*****************************************************************************
+// ERROR CODES
+//*****************************************************************************
+#define ESUCCESS 0
+#define EFAIL -1
+#define EERROR EFAIL
+
+//*****************************************************************************
+// COMMON DEFINES
+//*****************************************************************************
+#define ERROR_SOCKET_INACTIVE -57
+
+#define WLAN_ENABLE (1)
+#define WLAN_DISABLE (0)
+
+#define MAC_ADDR_LEN (6)
+
+#define SP_PORTION_SIZE (32)
+
+/*Defines for minimal and maximal RX buffer size. This size includes the spi
+ header and hci header.
+ The maximal buffer size derives from:
+ MTU + HCI header + SPI header + sendto() agrs size
+ The minimum buffer size derives from:
+ HCI header + SPI header + max args size
+
+ This buffer is used for receiving events and data.
+ The packet can not be longer than MTU size and CC3000 does not support
+ fragmentation. Note that the same buffer is used for reception of the data
+ and events from CC3000. That is why the minimum is defined.
+ The calculation for the actual size of buffer for reception is:
+ Given the maximal data size MAX_DATA that is expected to be received by
+ application, the required buffer is:
+ Using recv() or recvfrom():
+
+ max(CC3000_MINIMAL_RX_SIZE, MAX_DATA + HEADERS_SIZE_DATA + fromlen
+ + ucArgsize + 1)
+
+ Using gethostbyname() with minimal buffer size will limit the host name
+ returned to 99 bytes only.
+ The 1 is used for the overrun detection
+
+ Buffer size increased to 130 following the add_profile() with WEP security
+ which requires TX buffer size of 130 bytes:
+ HEADERS_SIZE_EVNT + WLAN_ADD_PROFILE_WEP_PARAM_LEN + MAX SSID LEN + 4 * MAX KEY LEN = 130
+ MAX SSID LEN = 32
+ MAX SSID LEN = 13 (with add_profile only ascii key setting is supported,
+ therfore maximum key size is 13)
+*/
+
+#define CC3000_MINIMAL_RX_SIZE (130 + 1)
+#define CC3000_MAXIMAL_RX_SIZE (1519 + 1)
+
+/*Defines for minimal and maximal TX buffer size.
+ This buffer is used for sending events and data.
+ The packet can not be longer than MTU size and CC3000 does not support
+ fragmentation. Note that the same buffer is used for transmission of the data
+ and commands. That is why the minimum is defined.
+ The calculation for the actual size of buffer for transmission is:
+ Given the maximal data size MAX_DATA, the required buffer is:
+ Using Sendto():
+
+ max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE
+ + SOCKET_SENDTO_PARAMS_LEN + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1)
+
+ Using Send():
+
+ max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE
+ + HCI_CMND_SEND_ARG_LENGTH + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1)
+
+ The 1 is used for the overrun detection */
+
+#define CC3000_MINIMAL_TX_SIZE (130 + 1)
+#define CC3000_MAXIMAL_TX_SIZE (1519 + 1)
+
+//TX and RX buffer sizes, allow to receive and transmit maximum data at length 8.
+#ifdef CC3000_TINY_DRIVER
+#define TINY_CC3000_MAXIMAL_RX_SIZE 44
+#define TINY_CC3000_MAXIMAL_TX_SIZE 59
+#endif
+
+/*In order to determine your preferred buffer size,
+ change CC3000_MAXIMAL_RX_SIZE and CC3000_MAXIMAL_TX_SIZE to a value between
+ the minimal and maximal specified above.
+ Note that the buffers are allocated by SPI.
+ In case you change the size of those buffers, you might need also to change
+ the linker file, since for example on MSP430 FRAM devices the buffers are
+ allocated in the FRAM section that is allocated manually and not by IDE.
+*/
+
+#ifndef CC3000_TINY_DRIVER
+
+ #define CC3000_RX_BUFFER_SIZE (CC3000_MAXIMAL_RX_SIZE)
+ #define CC3000_TX_BUFFER_SIZE (CC3000_MAXIMAL_TX_SIZE)
+
+//if defined TINY DRIVER we use smaller RX and TX buffer in order to minimize RAM consumption
+#else
+ #define CC3000_RX_BUFFER_SIZE (TINY_CC3000_MAXIMAL_RX_SIZE)
+ #define CC3000_TX_BUFFER_SIZE (TINY_CC3000_MAXIMAL_TX_SIZE)
+
+#endif
+
+//*****************************************************************************
+// Compound Types
+//*****************************************************************************
+typedef long time_t_;
+typedef unsigned long clock_t_;
+typedef long suseconds_t;
+
+typedef struct timeval timeval;
+
+struct timeval
+{
+ time_t_ tv_sec; /* seconds */
+ suseconds_t tv_usec; /* microseconds */
+};
+
+typedef char *(*tFWPatches)(unsigned long *usLength);
+
+typedef char *(*tDriverPatches)(unsigned long *usLength);
+
+typedef char *(*tBootLoaderPatches)(unsigned long *usLength);
+
+typedef void (*tWlanCB)(long event_type, char * data, unsigned char length );
+
+typedef int (*tWlanReadInteruptPin)(void);
+
+typedef void (*tWlanInterruptEnable)(void);
+
+typedef void (*tWlanInterruptDisable)(void);
+
+typedef void (*tWriteWlanPin)(unsigned char val);
+
+typedef struct
+{
+ unsigned short usRxEventOpcode;
+ unsigned short usEventOrDataReceived;
+ unsigned char *pucReceivedData;
+ unsigned char *pucTxCommandBuffer;
+
+ tFWPatches sFWPatches;
+ tDriverPatches sDriverPatches;
+ tBootLoaderPatches sBootLoaderPatches;
+ tWlanCB sWlanCB;
+ tWlanReadInteruptPin ReadWlanInterruptPin;
+ tWlanInterruptEnable WlanInterruptEnable;
+ tWlanInterruptDisable WlanInterruptDisable;
+ tWriteWlanPin WriteWlanPin;
+
+ signed long slTransmitDataError;
+ unsigned short usNumberOfFreeBuffers;
+ unsigned short usSlBufferLength;
+ unsigned short usBufferSize;
+ unsigned short usRxDataPending;
+
+ unsigned long NumberOfSentPackets;
+ unsigned long NumberOfReleasedPackets;
+
+ unsigned char InformHostOnTxComplete;
+}sSimplLinkInformation;
+
+extern volatile sSimplLinkInformation tSLInformation;
+
+
+//*****************************************************************************
+// Prototypes for the APIs.
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//
+//! 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.
+//
+//*****************************************************************************
+
+extern void SimpleLinkWaitEvent(unsigned short usOpcode, void *pRetParams);
+
+//*****************************************************************************
+//
+//! 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.
+//
+//*****************************************************************************
+
+extern void SimpleLinkWaitData(unsigned char *pBuf, unsigned char *from, unsigned char *fromlen);
+
+//*****************************************************************************
+//
+//! 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.
+//
+//*****************************************************************************
+
+extern unsigned char* UINT32_TO_STREAM_f (unsigned char *p, unsigned long u32);
+
+//*****************************************************************************
+//
+//! 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.
+//
+//*****************************************************************************
+
+extern unsigned char* UINT16_TO_STREAM_f (unsigned char *p, unsigned short u16);
+
+//*****************************************************************************
+//
+//! 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.
+//
+//*****************************************************************************
+
+extern unsigned short STREAM_TO_UINT16_f(char* p, unsigned short 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.
+//
+//*****************************************************************************
+
+extern unsigned long STREAM_TO_UINT32_f(char* p, unsigned short offset);
+
+
+//*****************************************************************************
+// COMMON MACROs
+//*****************************************************************************
+
+
+//This macro is used for copying 8 bit to stream while converting to little endian format.
+#define UINT8_TO_STREAM(_p, _val) {*(_p)++ = (_val);}
+//This macro is used for copying 16 bit to stream while converting to little endian format.
+#define UINT16_TO_STREAM(_p, _u16) (UINT16_TO_STREAM_f(_p, _u16))
+//This macro is used for copying 32 bit to stream while converting to little endian format.
+#define UINT32_TO_STREAM(_p, _u32) (UINT32_TO_STREAM_f(_p, _u32))
+//This macro is used for copying a specified value length bits (l) to stream while converting to little endian format.
+#define ARRAY_TO_STREAM(p, a, l) {register short _i; for (_i = 0; _i < l; _i++) *(p)++ = ((unsigned char *) a)[_i];}
+//This macro is used for copying received stream to 8 bit in little endian format.
+#define STREAM_TO_UINT8(_p, _offset, _u8) {_u8 = (unsigned char)(*(_p + _offset));}
+//This macro is used for copying received stream to 16 bit in little endian format.
+#define STREAM_TO_UINT16(_p, _offset, _u16) {_u16 = STREAM_TO_UINT16_f(_p, _offset);}
+//This macro is used for copying received stream to 32 bit in little endian format.
+#define STREAM_TO_UINT32(_p, _offset, _u32) {_u32 = STREAM_TO_UINT32_f(_p, _offset);}
+#define STREAM_TO_STREAM(p, a, l) {register short _i; for (_i = 0; _i < l; _i++) *(a)++= ((unsigned char *) p)[_i];}
+
+
+
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // __COMMON_H__
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CC3000HostDriver/evnt_handler.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,844 @@
+/*****************************************************************************
+*
+* 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
+//******************************************************************************
+
+#include "cc3000_common.h"
+#include "string.h"
+#include "hci.h"
+#include "evnt_handler.h"
+#include "wlan.h"
+#include "socket.h"
+#include "netapp.h"
+#include "spi.h"
+
+
+
+//*****************************************************************************
+// COMMON DEFINES
+//*****************************************************************************
+
+#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)
+
+
+
+//*****************************************************************************
+// GLOBAL VARAIABLES
+//*****************************************************************************
+
+unsigned long socket_active_status = SOCKET_STATUS_INIT_VAL;
+
+
+//*****************************************************************************
+// Prototypes for the static functions
+//*****************************************************************************
+
+static long hci_event_unsol_flowcontrol_handler(char *pEvent);
+
+static void update_socket_active_status(char *resp_params);
+
+
+//*****************************************************************************
+//
+//! 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;
+ }
+}
+
+
+
+//*****************************************************************************
+//
+//! 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
+//
+//*****************************************************************************
+
+
+unsigned char *
+hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen)
+{
+ unsigned char *pucReceivedData, ucArgsize;
+ unsigned short usLength;
+ unsigned char *pucReceivedParams;
+ unsigned short usReceivedEventOpcode = 0;
+ unsigned long retValue32;
+ unsigned char * RecvParams;
+ unsigned char *RetParams;
+
+
+ while (1)
+ {
+ //printf("Looping...\r\n");
+ 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 = (unsigned char *)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
+ ,*(unsigned char *)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
+ ,*(unsigned char *)pRetParams);
+ pRetParams = ((char *)pRetParams) + 1;
+ STREAM_TO_UINT32((char *)pucReceivedParams, 0, retValue32);
+ UINT32_TO_STREAM((unsigned char *)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((unsigned char *)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((unsigned char *)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((unsigned char *)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;
+ }
+ }
+ }
+
+}
+
+//*****************************************************************************
+//
+//! 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:
+ {
+ unsigned char params[NETAPP_IPCONFIG_MAC_OFFSET + 1]; // extra byte is for the status
+ unsigned char *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:
+ {
+ data = (char *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
+ if( tSLInformation.sWlanCB )
+ {
+ tSLInformation.sWlanCB(event_type, data, 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);
+}
+
+//*****************************************************************************
+//
+//! 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)
+{
+ unsigned long res = 0;
+ unsigned char *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
+//
+//*****************************************************************************
+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 */
+ }
+}
+
+
+//*****************************************************************************
+//
+//! 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)
+{
+
+ long temp, value;
+ unsigned short i;
+ unsigned short 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)
+{
+ 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)
+{
+ 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);
+ }
+}
+
+
+//*****************************************************************************
+//
+//! 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(unsigned short 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);
+}
+
+//*****************************************************************************
+//
+//! 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(unsigned char *pBuf, unsigned char *from,
+ unsigned char *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);
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CC3000HostDriver/evnt_handler.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,167 @@
+/*****************************************************************************
+*
+* evnt_handler.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 __EVENT_HANDLER_H__
+#define __EVENT_HANDLER_H__
+#include "hci.h"
+#include "socket.h"
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//*****************************************************************************
+//
+// Prototypes for the APIs.
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+//! 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
+//
+//*****************************************************************************
+extern unsigned char *hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen);
+
+//*****************************************************************************
+//
+//! 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
+//
+//*****************************************************************************
+extern long hci_unsol_event_handler(char *event_hdr);
+
+//*****************************************************************************
+//
+//! 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.
+//
+//*****************************************************************************
+extern long hci_unsolicited_event_handler(void);
+
+#define M_BSD_RESP_PARAMS_OFFSET(hci_event_hdr)((char *)(hci_event_hdr) + HCI_EVENT_HEADER_SIZE)
+
+#define SOCKET_STATUS_ACTIVE 0
+#define SOCKET_STATUS_INACTIVE 1
+/* Init socket_active_status = 'all ones': init all sockets with SOCKET_STATUS_INACTIVE.
+ Will be changed by 'set_socket_active_status' upon 'connect' and 'accept' calls */
+#define SOCKET_STATUS_INIT_VAL 0xFFFF
+#define M_IS_VALID_SD(sd) ((0 <= (sd)) && ((sd) <= 7))
+#define M_IS_VALID_STATUS(status) (((status) == SOCKET_STATUS_ACTIVE)||((status) == SOCKET_STATUS_INACTIVE))
+
+extern unsigned long socket_active_status;
+
+extern void set_socket_active_status(long Sd, long Status);
+extern long get_socket_active_status(long Sd);
+
+typedef struct _bsd_accept_return_t
+{
+ long iSocketDescriptor;
+ long iStatus;
+ sockaddr tSocketAddress;
+
+} tBsdReturnParams;
+
+
+typedef struct _bsd_read_return_t
+{
+ long iSocketDescriptor;
+ long iNumberOfBytes;
+ unsigned long uiFlags;
+} tBsdReadReturnParams;
+
+#define BSD_RECV_FROM_FROMLEN_OFFSET (4)
+#define BSD_RECV_FROM_FROM_OFFSET (16)
+
+
+typedef struct _bsd_select_return_t
+{
+ long iStatus;
+ unsigned long uiRdfd;
+ unsigned long uiWrfd;
+ unsigned long uiExfd;
+} tBsdSelectRecvParams;
+
+
+typedef struct _bsd_getsockopt_return_t
+{
+ unsigned char ucOptValue[4];
+ char iStatus;
+} tBsdGetSockOptReturnParams;
+
+typedef struct _bsd_gethostbyname_return_t
+{
+ long retVal;
+ long outputAddress;
+} tBsdGethostbynameParams;
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // __EVENT_HANDLER_H__
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CC3000HostDriver/hci.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,230 @@
+/*****************************************************************************
+*
+* 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
+//! @{
+//
+//*****************************************************************************
+
+#include "cc3000_common.h"
+#include "hci.h"
+#include "spi.h"
+#include "evnt_handler.h"
+#include "wlan.h"
+
+#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.
+//
+//*****************************************************************************
+unsigned short
+hci_command_send(unsigned short usOpcode, unsigned char *pucBuff,
+ unsigned char ucArgsLength)
+{
+ unsigned char *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(unsigned char ucOpcode,
+ unsigned char *ucArgs,
+ unsigned short usArgsLength,
+ unsigned short usDataLength,
+ const unsigned char *ucTail,
+ unsigned short usTailLength)
+{
+ unsigned char *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);
+}
+
+
+//*****************************************************************************
+//
+//! 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(unsigned short usOpcode, unsigned char *pucBuff,
+ unsigned char ucArgsLength,unsigned short ucDataLength)
+{
+ unsigned char *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;
+}
+
+//*****************************************************************************
+//
+//! 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(unsigned char ucOpcode, unsigned char *pucBuff, char *patch, unsigned short usDataLength)
+{
+ unsigned char *data_ptr = (pucBuff + SPI_HEADER_SIZE);
+ unsigned short usTransLength;
+ unsigned char *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;
+ }
+
+ *(unsigned short *)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((unsigned char *)data_ptr, usTransLength + sizeof(usTransLength));
+ }
+ }
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//
+//*****************************************************************************
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CC3000HostDriver/hci.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,329 @@
+/*****************************************************************************
+*
+* hci.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 __HCI_H__
+#define __HCI_H__
+
+#include "cc3000_common.h"
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define SPI_HEADER_SIZE (5)
+#define SIMPLE_LINK_HCI_CMND_HEADER_SIZE (4)
+#define HEADERS_SIZE_CMD (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE)
+#define SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE (5)
+#define SIMPLE_LINK_HCI_DATA_HEADER_SIZE (5)
+#define SIMPLE_LINK_HCI_PATCH_HEADER_SIZE (2)
+
+
+//*****************************************************************************
+//
+// Values that can be used as HCI Commands and HCI Packet header defines
+//
+//*****************************************************************************
+#define HCI_TYPE_CMND 0x1
+#define HCI_TYPE_DATA 0x2
+#define HCI_TYPE_PATCH 0x3
+#define HCI_TYPE_EVNT 0x4
+
+
+#define HCI_EVENT_PATCHES_DRV_REQ (1)
+#define HCI_EVENT_PATCHES_FW_REQ (2)
+#define HCI_EVENT_PATCHES_BOOTLOAD_REQ (3)
+
+
+#define HCI_CMND_WLAN_BASE (0x0000)
+#define HCI_CMND_WLAN_CONNECT 0x0001
+#define HCI_CMND_WLAN_DISCONNECT 0x0002
+#define HCI_CMND_WLAN_IOCTL_SET_SCANPARAM 0x0003
+#define HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY 0x0004
+#define HCI_CMND_WLAN_IOCTL_ADD_PROFILE 0x0005
+#define HCI_CMND_WLAN_IOCTL_DEL_PROFILE 0x0006
+#define HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS 0x0007
+#define HCI_CMND_EVENT_MASK 0x0008
+#define HCI_CMND_WLAN_IOCTL_STATUSGET 0x0009
+#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START 0x000A
+#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP 0x000B
+#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX 0x000C
+#define HCI_CMND_WLAN_CONFIGURE_PATCH 0x000D
+
+
+#define HCI_CMND_SOCKET_BASE 0x1000
+#define HCI_CMND_SOCKET 0x1001
+#define HCI_CMND_BIND 0x1002
+#define HCI_CMND_RECV 0x1004
+#define HCI_CMND_ACCEPT 0x1005
+#define HCI_CMND_LISTEN 0x1006
+#define HCI_CMND_CONNECT 0x1007
+#define HCI_CMND_BSD_SELECT 0x1008
+#define HCI_CMND_SETSOCKOPT 0x1009
+#define HCI_CMND_GETSOCKOPT 0x100A
+#define HCI_CMND_CLOSE_SOCKET 0x100B
+#define HCI_CMND_RECVFROM 0x100D
+#define HCI_CMND_GETHOSTNAME 0x1010
+#define HCI_CMND_MDNS_ADVERTISE 0x1011
+
+
+#define HCI_DATA_BASE 0x80
+
+#define HCI_CMND_SEND (0x01 + HCI_DATA_BASE)
+#define HCI_CMND_SENDTO (0x03 + HCI_DATA_BASE)
+#define HCI_DATA_BSD_RECVFROM (0x04 + HCI_DATA_BASE)
+#define HCI_DATA_BSD_RECV (0x05 + HCI_DATA_BASE)
+
+
+#define HCI_CMND_NVMEM_CBASE (0x0200)
+
+
+#define HCI_CMND_NVMEM_CREATE_ENTRY (0x0203)
+#define HCI_CMND_NVMEM_SWAP_ENTRY (0x0205)
+#define HCI_CMND_NVMEM_READ (0x0201)
+#define HCI_CMND_NVMEM_WRITE (0x0090)
+#define HCI_CMND_NVMEM_WRITE_PATCH (0x0204)
+#define HCI_CMND_READ_SP_VERSION (0x0207)
+
+#define HCI_CMND_READ_BUFFER_SIZE 0x400B
+#define HCI_CMND_SIMPLE_LINK_START 0x4000
+
+#define HCI_CMND_NETAPP_BASE 0x2000
+
+#define HCI_NETAPP_DHCP (0x0001 + HCI_CMND_NETAPP_BASE)
+#define HCI_NETAPP_PING_SEND (0x0002 + HCI_CMND_NETAPP_BASE)
+#define HCI_NETAPP_PING_REPORT (0x0003 + HCI_CMND_NETAPP_BASE)
+#define HCI_NETAPP_PING_STOP (0x0004 + HCI_CMND_NETAPP_BASE)
+#define HCI_NETAPP_IPCONFIG (0x0005 + HCI_CMND_NETAPP_BASE)
+#define HCI_NETAPP_ARP_FLUSH (0x0006 + HCI_CMND_NETAPP_BASE)
+#define HCI_NETAPP_SET_DEBUG_LEVEL (0x0008 + HCI_CMND_NETAPP_BASE)
+#define HCI_NETAPP_SET_TIMERS (0x0009 + HCI_CMND_NETAPP_BASE)
+
+
+
+
+
+
+//*****************************************************************************
+//
+// Values that can be used as HCI Events defines
+//
+//*****************************************************************************
+#define HCI_EVNT_WLAN_BASE 0x0000
+#define HCI_EVNT_WLAN_CONNECT 0x0001
+#define HCI_EVNT_WLAN_DISCONNECT \
+ 0x0002
+#define HCI_EVNT_WLAN_IOCTL_ADD_PROFILE \
+ 0x0005
+
+
+#define HCI_EVNT_SOCKET HCI_CMND_SOCKET
+#define HCI_EVNT_BIND HCI_CMND_BIND
+#define HCI_EVNT_RECV HCI_CMND_RECV
+#define HCI_EVNT_ACCEPT HCI_CMND_ACCEPT
+#define HCI_EVNT_LISTEN HCI_CMND_LISTEN
+#define HCI_EVNT_CONNECT HCI_CMND_CONNECT
+#define HCI_EVNT_SELECT HCI_CMND_BSD_SELECT
+#define HCI_EVNT_CLOSE_SOCKET HCI_CMND_CLOSE_SOCKET
+#define HCI_EVNT_RECVFROM HCI_CMND_RECVFROM
+#define HCI_EVNT_SETSOCKOPT HCI_CMND_SETSOCKOPT
+#define HCI_EVNT_GETSOCKOPT HCI_CMND_GETSOCKOPT
+#define HCI_EVNT_BSD_GETHOSTBYNAME HCI_CMND_GETHOSTNAME
+#define HCI_EVNT_MDNS_ADVERTISE HCI_CMND_MDNS_ADVERTISE
+
+#define HCI_EVNT_SEND 0x1003
+#define HCI_EVNT_WRITE 0x100E
+#define HCI_EVNT_SENDTO 0x100F
+
+#define HCI_EVNT_PATCHES_REQ 0x1000
+
+#define HCI_EVNT_UNSOL_BASE 0x4000
+
+#define HCI_EVNT_WLAN_UNSOL_BASE (0x8000)
+
+#define HCI_EVNT_WLAN_UNSOL_CONNECT (0x0001 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_WLAN_UNSOL_DISCONNECT (0x0002 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_WLAN_UNSOL_INIT (0x0004 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_WLAN_TX_COMPLETE (0x0008 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_WLAN_UNSOL_DHCP (0x0010 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_WLAN_ASYNC_PING_REPORT (0x0040 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE (0x0080 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_WLAN_KEEPALIVE (0x0200 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_BSD_TCP_CLOSE_WAIT (0x0800 + HCI_EVNT_WLAN_UNSOL_BASE)
+
+#define HCI_EVNT_DATA_UNSOL_FREE_BUFF \
+ 0x4100
+
+#define HCI_EVNT_NVMEM_CREATE_ENTRY \
+ HCI_CMND_NVMEM_CREATE_ENTRY
+#define HCI_EVNT_NVMEM_SWAP_ENTRY HCI_CMND_NVMEM_SWAP_ENTRY
+
+#define HCI_EVNT_NVMEM_READ HCI_CMND_NVMEM_READ
+#define HCI_EVNT_NVMEM_WRITE (0x0202)
+
+#define HCI_EVNT_READ_SP_VERSION \
+ HCI_CMND_READ_SP_VERSION
+
+#define HCI_EVNT_INPROGRESS 0xFFFF
+
+
+#define HCI_DATA_RECVFROM 0x84
+#define HCI_DATA_RECV 0x85
+#define HCI_DATA_NVMEM 0x91
+
+#define HCI_EVENT_CC3000_CAN_SHUT_DOWN 0x99
+
+//*****************************************************************************
+//
+// Prototypes for the structures for APIs.
+//
+//*****************************************************************************
+
+#define HCI_DATA_HEADER_SIZE (5)
+#define HCI_EVENT_HEADER_SIZE (5)
+#define HCI_DATA_CMD_HEADER_SIZE (5)
+#define HCI_PATCH_HEADER_SIZE (6)
+
+#define HCI_PACKET_TYPE_OFFSET (0)
+#define HCI_PACKET_ARGSIZE_OFFSET (2)
+#define HCI_PACKET_LENGTH_OFFSET (3)
+
+
+#define HCI_EVENT_OPCODE_OFFSET (1)
+#define HCI_EVENT_LENGTH_OFFSET (3)
+#define HCI_EVENT_STATUS_OFFSET (4)
+#define HCI_DATA_LENGTH_OFFSET (3)
+
+
+
+
+//*****************************************************************************
+//
+// Prototypes for the APIs.
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+//! 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.
+//
+//*****************************************************************************
+extern unsigned short hci_command_send(unsigned short usOpcode,
+ unsigned char *ucArgs,
+ unsigned char ucArgsLength);
+
+
+//*****************************************************************************
+//
+//! 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
+//
+//*****************************************************************************
+extern long hci_data_send(unsigned char ucOpcode,
+ unsigned char *ucArgs,
+ unsigned short usArgsLength,
+ unsigned short usDataLength,
+ const unsigned char *ucTail,
+ unsigned short usTailLength);
+
+
+//*****************************************************************************
+//
+//! 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 Prepare HCI header and initiate an HCI data write operation
+//
+//*****************************************************************************
+extern void hci_data_command_send(unsigned short usOpcode, unsigned char *pucBuff,
+ unsigned char ucArgsLength, unsigned short 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 Prepare HCI header and initiate an HCI patch write operation
+//
+//*****************************************************************************
+extern void hci_patch_send(unsigned char ucOpcode, unsigned char *pucBuff, char *patch, unsigned short usDataLength);
+
+
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // __HCI_H__
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CC3000HostDriver/host_driver_version.h Sat Sep 14 17:38:41 2013 +0000 @@ -0,0 +1,56 @@ +/***************************************************************************** +* +* host_driver_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 __HOST_DRIVER_VERSION_H__ +#define __HOST_DRIVER_VERSION_H__ + +#define DRIVER_VERSION_NUMBER 13 + + + +#endif // __VERSION_H__ + + + + + + + + + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CC3000HostDriver/netapp.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,460 @@
+/*****************************************************************************
+*
+* 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.
+*
+*****************************************************************************/
+#include <string.h>
+#include "netapp.h"
+#include "hci.h"
+#include "socket.h"
+#include "evnt_handler.h"
+#include "nvmem.h"
+
+#define MIN_TIMER_VAL_SECONDS 20
+#define MIN_TIMER_SET(t) if ((0 != t) && (t < MIN_TIMER_VAL_SECONDS)) \
+ { \
+ t = MIN_TIMER_VAL_SECONDS; \
+ }
+
+
+#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.
+//
+//*****************************************************************************
+long netapp_config_mac_adrress(unsigned char * 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)
+{
+ signed char scRet;
+ unsigned char *ptr;
+ unsigned char *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);
+}
+
+
+//*****************************************************************************
+//
+//! 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.
+//!
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+long
+netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP,unsigned long *aucKeepalive, unsigned long *aucInactivity)
+{
+ signed char scRet;
+ unsigned char *ptr;
+ unsigned char *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.
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+long
+netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts, unsigned long ulPingSize, unsigned long ulPingTimeout)
+{
+ signed char scRet;
+ unsigned char *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.
+//!
+//*****************************************************************************
+
+
+#ifndef CC3000_TINY_DRIVER
+void netapp_ping_report()
+{
+ unsigned char *ptr;
+ ptr = tSLInformation.pucTxCommandBuffer;
+ signed char 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.
+//!
+//!
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+long netapp_ping_stop()
+{
+ signed char scRet;
+ unsigned char *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.
+//!
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig )
+{
+ unsigned char *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 )
+{
+
+}
+#endif
+
+//*****************************************************************************
+//
+//! netapp_arp_flush
+//!
+//! @param none
+//!
+//! @return none
+//!
+//! @brief Flushes ARP table
+//!
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+long netapp_arp_flush(void)
+{
+ signed char scRet;
+ unsigned char *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
+//!
+//*****************************************************************************
+
+
+#ifndef CC3000_TINY_DRIVER
+long netapp_set_debug_level(unsigned long ulLevel)
+{
+ signed char scRet;
+ unsigned char *ptr, *args;
+
+ scRet = EFAIL;
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ //
+ // Fill in temporary command buffer
+ //
+ args = UINT32_TO_STREAM(args, ulLevel);
+
+
+ //
+ // Initiate a HCI command
+ //
+ 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);
+
+ return(scRet);
+
+}
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CC3000HostDriver/netapp.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,343 @@
+/*****************************************************************************
+*
+* netapp.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 __NETAPP_H__
+#define __NETAPP_H__
+
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//*****************************************************************************
+//
+//! \addtogroup netapp_api
+//! @{
+//
+//*****************************************************************************
+
+typedef struct _netapp_dhcp_ret_args_t
+{
+ unsigned char aucIP[4];
+ unsigned char aucSubnetMask[4];
+ unsigned char aucDefaultGateway[4];
+ unsigned char aucDHCPServer[4];
+ unsigned char aucDNSServer[4];
+}tNetappDhcpParams;
+
+typedef struct _netapp_ipconfig_ret_args_t
+{
+ unsigned char aucIP[4];
+ unsigned char aucSubnetMask[4];
+ unsigned char aucDefaultGateway[4];
+ unsigned char aucDHCPServer[4];
+ unsigned char aucDNSServer[4];
+ unsigned char uaMacAddr[6];
+ unsigned char uaSSID[32];
+}tNetappIpconfigRetArgs;
+
+
+/*Ping send report parameters*/
+typedef struct _netapp_pingreport_args
+{
+ unsigned long packets_sent;
+ unsigned long packets_received;
+ unsigned long min_round_time;
+ unsigned long max_round_time;
+ unsigned long avg_round_time;
+} netapp_pingreport_args_t;
+
+
+//*****************************************************************************
+//
+//! 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.
+//
+//*****************************************************************************
+extern long netapp_config_mac_adrress( unsigned char *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.
+//!
+//*****************************************************************************
+extern long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsigned long *aucDefaultGateway, unsigned long *aucDNSServer);
+
+
+
+//*****************************************************************************
+//
+//! 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.
+//!
+//*****************************************************************************
+ #ifndef CC3000_TINY_DRIVER
+extern long netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP,unsigned long *aucKeepalive, unsigned long *aucInactivity);
+#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.
+//*****************************************************************************
+
+ #ifndef CC3000_TINY_DRIVER
+extern long netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts, unsigned long ulPingSize, unsigned long ulPingTimeout);
+#endif
+
+//*****************************************************************************
+//
+//! netapp_ping_stop
+//!
+//! @param none
+//!
+//! @return On success, zero is returned. On error, -1 is returned.
+//!
+//! @brief Stop any ping request.
+//!
+//!
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+extern long netapp_ping_stop();
+#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.
+//!
+//*****************************************************************************
+#ifndef CC3000_TINY_DRIVER
+extern void netapp_ping_report();
+#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.
+//!
+//*****************************************************************************
+
+extern void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig );
+
+
+//*****************************************************************************
+//
+//! netapp_arp_flush
+//!
+//! @param none
+//!
+//! @return none
+//!
+//! @brief Flushes ARP table
+//!
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+extern long netapp_arp_flush();
+#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
+//!
+//*****************************************************************************
+
+
+#ifndef CC3000_TINY_DRIVER
+long netapp_set_debug_level(unsigned long ulLevel);
+#endif
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // __NETAPP_H__
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CC3000HostDriver/nvmem.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,341 @@
+/*****************************************************************************
+*
+* 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
+//! @{
+//
+//*****************************************************************************
+
+#include <stdio.h>
+#include <string.h>
+#include "nvmem.h"
+#include "hci.h"
+#include "socket.h"
+#include "evnt_handler.h"
+
+//*****************************************************************************
+//
+// Prototypes for the structures for APIs.
+//
+//*****************************************************************************
+
+#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, unsigned char *buff)
+{
+ unsigned char ucStatus = 0xFF;
+ unsigned char *ptr;
+ unsigned char *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, unsigned char *buff)
+{
+ long iRes;
+ unsigned char *ptr;
+ unsigned char *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)
+//!
+//*****************************************************************************
+
+unsigned char nvmem_set_mac_address(unsigned char *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)
+//!
+//*****************************************************************************
+
+unsigned char nvmem_get_mac_address(unsigned char *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.
+//!
+//*****************************************************************************
+
+unsigned char nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, const unsigned char *spData)
+{
+ unsigned char status = 0;
+ unsigned short offset = 0;
+ unsigned char* spDataPtr = (unsigned char*)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)
+//!
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+unsigned char nvmem_read_sp_version(unsigned char* patchVer)
+{
+ unsigned char *ptr;
+ // 1st byte is the status and the rest is the SP version
+ unsigned char 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)
+{
+ unsigned char *ptr;
+ unsigned char *args;
+ unsigned short 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);
+}
+
+
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CC3000HostDriver/nvmem.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,249 @@
+/*****************************************************************************
+*
+* nvmem.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 __NVRAM_H__
+#define __NVRAM_H__
+
+#include "cc3000_common.h"
+
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+//*****************************************************************************
+//
+//! \addtogroup nvmem_api
+//! @{
+//
+//*****************************************************************************
+
+/****************************************************************************
+**
+** Definitions for File IDs
+**
+****************************************************************************/
+/* NVMEM file ID - system files*/
+#define NVMEM_NVS_FILEID (0)
+#define NVMEM_NVS_SHADOW_FILEID (1)
+#define NVMEM_WLAN_CONFIG_FILEID (2)
+#define NVMEM_WLAN_CONFIG_SHADOW_FILEID (3)
+#define NVMEM_WLAN_DRIVER_SP_FILEID (4)
+#define NVMEM_WLAN_FW_SP_FILEID (5)
+#define NVMEM_MAC_FILEID (6)
+#define NVMEM_FRONTEND_VARS_FILEID (7)
+#define NVMEM_IP_CONFIG_FILEID (8)
+#define NVMEM_IP_CONFIG_SHADOW_FILEID (9)
+#define NVMEM_BOOTLOADER_SP_FILEID (10)
+#define NVMEM_RM_FILEID (11)
+
+/* NVMEM file ID - user files*/
+#define NVMEM_AES128_KEY_FILEID (12)
+#define NVMEM_SHARED_MEM_FILEID (13)
+
+/* max entry in order to invalid nvmem */
+#define NVMEM_MAX_ENTRY (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.
+//!
+//*****************************************************************************
+
+extern signed long nvmem_read(unsigned long file_id, unsigned long length, unsigned long offset, unsigned char *buff);
+
+//*****************************************************************************
+//
+//! 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.
+//!
+//*****************************************************************************
+
+extern signed long nvmem_write(unsigned long ulFileId, unsigned long ulLength, unsigned long ulEntryOffset, unsigned char *buff);
+
+
+//*****************************************************************************
+//
+//! 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)
+//!
+//*****************************************************************************
+extern unsigned char nvmem_set_mac_address(unsigned char *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)
+//!
+//*****************************************************************************
+extern unsigned char nvmem_get_mac_address(unsigned char *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.
+//!
+//*****************************************************************************
+extern unsigned char nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, const unsigned char *spData);
+
+
+//*****************************************************************************
+//
+//! 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)
+//!
+//*****************************************************************************
+#ifndef CC3000_TINY_DRIVER
+extern unsigned char nvmem_read_sp_version(unsigned char* patchVer);
+#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.
+//!
+//*****************************************************************************
+extern signed long nvmem_create_entry(unsigned long file_id, unsigned long newlen);
+
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
+
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // __NVRAM_H__
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CC3000HostDriver/security.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,534 @@
+/*****************************************************************************
+*
+* security.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 security_api
+//! @{
+//
+//*****************************************************************************
+
+#include "security.h"
+
+#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
+// foreward sbox
+const unsigned char sbox[256] = {
+//0 1 2 3 4 5 6 7 8 9 A B C D E F
+0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0
+0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1
+0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, //2
+0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, //3
+0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, //4
+0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, //5
+0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, //6
+0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, //7
+0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, //8
+0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, //9
+0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //A
+0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //B
+0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C
+0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D
+0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E
+0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; //F
+// inverse sbox
+const unsigned char rsbox[256] =
+{ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
+, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
+, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
+, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
+, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
+, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
+, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
+, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
+, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
+, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
+, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
+, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
+, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
+, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
+, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
+, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
+// round constant
+const unsigned char Rcon[11] = {
+ 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
+
+
+unsigned char expandedKey[176];
+
+//*****************************************************************************
+//
+//! expandKey
+//!
+//! @param key AES128 key - 16 bytes
+//! @param expandedKey expanded AES128 key
+//!
+//! @return none
+//!
+//! @brief expend a 16 bytes key for AES128 implementation
+//!
+//*****************************************************************************
+
+void expandKey(unsigned char *expandedKey,
+ unsigned char *key)
+{
+ unsigned short ii, buf1;
+ for (ii=0;ii<16;ii++)
+ expandedKey[ii] = key[ii];
+ for (ii=1;ii<11;ii++){
+ buf1 = expandedKey[ii*16 - 4];
+ expandedKey[ii*16 + 0] = sbox[expandedKey[ii*16 - 3]]^expandedKey[(ii-1)*16 + 0]^Rcon[ii];
+ expandedKey[ii*16 + 1] = sbox[expandedKey[ii*16 - 2]]^expandedKey[(ii-1)*16 + 1];
+ expandedKey[ii*16 + 2] = sbox[expandedKey[ii*16 - 1]]^expandedKey[(ii-1)*16 + 2];
+ expandedKey[ii*16 + 3] = sbox[buf1 ]^expandedKey[(ii-1)*16 + 3];
+ expandedKey[ii*16 + 4] = expandedKey[(ii-1)*16 + 4]^expandedKey[ii*16 + 0];
+ expandedKey[ii*16 + 5] = expandedKey[(ii-1)*16 + 5]^expandedKey[ii*16 + 1];
+ expandedKey[ii*16 + 6] = expandedKey[(ii-1)*16 + 6]^expandedKey[ii*16 + 2];
+ expandedKey[ii*16 + 7] = expandedKey[(ii-1)*16 + 7]^expandedKey[ii*16 + 3];
+ expandedKey[ii*16 + 8] = expandedKey[(ii-1)*16 + 8]^expandedKey[ii*16 + 4];
+ expandedKey[ii*16 + 9] = expandedKey[(ii-1)*16 + 9]^expandedKey[ii*16 + 5];
+ expandedKey[ii*16 +10] = expandedKey[(ii-1)*16 +10]^expandedKey[ii*16 + 6];
+ expandedKey[ii*16 +11] = expandedKey[(ii-1)*16 +11]^expandedKey[ii*16 + 7];
+ expandedKey[ii*16 +12] = expandedKey[(ii-1)*16 +12]^expandedKey[ii*16 + 8];
+ expandedKey[ii*16 +13] = expandedKey[(ii-1)*16 +13]^expandedKey[ii*16 + 9];
+ expandedKey[ii*16 +14] = expandedKey[(ii-1)*16 +14]^expandedKey[ii*16 +10];
+ expandedKey[ii*16 +15] = expandedKey[(ii-1)*16 +15]^expandedKey[ii*16 +11];
+ }
+
+}
+
+//*****************************************************************************
+//
+//! galois_mul2
+//!
+//! @param value argument to multiply
+//!
+//! @return multiplied argument
+//!
+//! @brief multiply by 2 in the galois field
+//!
+//*****************************************************************************
+
+unsigned char galois_mul2(unsigned char value)
+{
+ if (value>>7)
+ {
+ value = value << 1;
+ return (value^0x1b);
+ } else
+ return value<<1;
+}
+
+//*****************************************************************************
+//
+//! aes_encr
+//!
+//! @param[in] expandedKey expanded AES128 key
+//! @param[in/out] state 16 bytes of plain text and cipher text
+//!
+//! @return none
+//!
+//! @brief internal implementation of AES128 encryption.
+//! straight forward aes encryption implementation
+//! first the group of operations
+//! - addRoundKey
+//! - subbytes
+//! - shiftrows
+//! - mixcolums
+//! is executed 9 times, after this addroundkey to finish the 9th
+//! round, after that the 10th round without mixcolums
+//! no further subfunctions to save cycles for function calls
+//! no structuring with "for (....)" to save cycles.
+//!
+//!
+//*****************************************************************************
+
+void aes_encr(unsigned char *state, unsigned char *expandedKey)
+{
+ unsigned char buf1, buf2, buf3, round;
+
+ for (round = 0; round < 9; round ++){
+ // addroundkey, sbox and shiftrows
+ // row 0
+ state[ 0] = sbox[(state[ 0] ^ expandedKey[(round*16) ])];
+ state[ 4] = sbox[(state[ 4] ^ expandedKey[(round*16) + 4])];
+ state[ 8] = sbox[(state[ 8] ^ expandedKey[(round*16) + 8])];
+ state[12] = sbox[(state[12] ^ expandedKey[(round*16) + 12])];
+ // row 1
+ buf1 = state[1] ^ expandedKey[(round*16) + 1];
+ state[ 1] = sbox[(state[ 5] ^ expandedKey[(round*16) + 5])];
+ state[ 5] = sbox[(state[ 9] ^ expandedKey[(round*16) + 9])];
+ state[ 9] = sbox[(state[13] ^ expandedKey[(round*16) + 13])];
+ state[13] = sbox[buf1];
+ // row 2
+ buf1 = state[2] ^ expandedKey[(round*16) + 2];
+ buf2 = state[6] ^ expandedKey[(round*16) + 6];
+ state[ 2] = sbox[(state[10] ^ expandedKey[(round*16) + 10])];
+ state[ 6] = sbox[(state[14] ^ expandedKey[(round*16) + 14])];
+ state[10] = sbox[buf1];
+ state[14] = sbox[buf2];
+ // row 3
+ buf1 = state[15] ^ expandedKey[(round*16) + 15];
+ state[15] = sbox[(state[11] ^ expandedKey[(round*16) + 11])];
+ state[11] = sbox[(state[ 7] ^ expandedKey[(round*16) + 7])];
+ state[ 7] = sbox[(state[ 3] ^ expandedKey[(round*16) + 3])];
+ state[ 3] = sbox[buf1];
+
+ // mixcolums //////////
+ // col1
+ buf1 = state[0] ^ state[1] ^ state[2] ^ state[3];
+ buf2 = state[0];
+ buf3 = state[0]^state[1]; buf3=galois_mul2(buf3); state[0] = state[0] ^ buf3 ^ buf1;
+ buf3 = state[1]^state[2]; buf3=galois_mul2(buf3); state[1] = state[1] ^ buf3 ^ buf1;
+ buf3 = state[2]^state[3]; buf3=galois_mul2(buf3); state[2] = state[2] ^ buf3 ^ buf1;
+ buf3 = state[3]^buf2; buf3=galois_mul2(buf3); state[3] = state[3] ^ buf3 ^ buf1;
+ // col2
+ buf1 = state[4] ^ state[5] ^ state[6] ^ state[7];
+ buf2 = state[4];
+ buf3 = state[4]^state[5]; buf3=galois_mul2(buf3); state[4] = state[4] ^ buf3 ^ buf1;
+ buf3 = state[5]^state[6]; buf3=galois_mul2(buf3); state[5] = state[5] ^ buf3 ^ buf1;
+ buf3 = state[6]^state[7]; buf3=galois_mul2(buf3); state[6] = state[6] ^ buf3 ^ buf1;
+ buf3 = state[7]^buf2; buf3=galois_mul2(buf3); state[7] = state[7] ^ buf3 ^ buf1;
+ // col3
+ buf1 = state[8] ^ state[9] ^ state[10] ^ state[11];
+ buf2 = state[8];
+ buf3 = state[8]^state[9]; buf3=galois_mul2(buf3); state[8] = state[8] ^ buf3 ^ buf1;
+ buf3 = state[9]^state[10]; buf3=galois_mul2(buf3); state[9] = state[9] ^ buf3 ^ buf1;
+ buf3 = state[10]^state[11]; buf3=galois_mul2(buf3); state[10] = state[10] ^ buf3 ^ buf1;
+ buf3 = state[11]^buf2; buf3=galois_mul2(buf3); state[11] = state[11] ^ buf3 ^ buf1;
+ // col4
+ buf1 = state[12] ^ state[13] ^ state[14] ^ state[15];
+ buf2 = state[12];
+ buf3 = state[12]^state[13]; buf3=galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1;
+ buf3 = state[13]^state[14]; buf3=galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1;
+ buf3 = state[14]^state[15]; buf3=galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1;
+ buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1;
+
+ }
+ // 10th round without mixcols
+ state[ 0] = sbox[(state[ 0] ^ expandedKey[(round*16) ])];
+ state[ 4] = sbox[(state[ 4] ^ expandedKey[(round*16) + 4])];
+ state[ 8] = sbox[(state[ 8] ^ expandedKey[(round*16) + 8])];
+ state[12] = sbox[(state[12] ^ expandedKey[(round*16) + 12])];
+ // row 1
+ buf1 = state[1] ^ expandedKey[(round*16) + 1];
+ state[ 1] = sbox[(state[ 5] ^ expandedKey[(round*16) + 5])];
+ state[ 5] = sbox[(state[ 9] ^ expandedKey[(round*16) + 9])];
+ state[ 9] = sbox[(state[13] ^ expandedKey[(round*16) + 13])];
+ state[13] = sbox[buf1];
+ // row 2
+ buf1 = state[2] ^ expandedKey[(round*16) + 2];
+ buf2 = state[6] ^ expandedKey[(round*16) + 6];
+ state[ 2] = sbox[(state[10] ^ expandedKey[(round*16) + 10])];
+ state[ 6] = sbox[(state[14] ^ expandedKey[(round*16) + 14])];
+ state[10] = sbox[buf1];
+ state[14] = sbox[buf2];
+ // row 3
+ buf1 = state[15] ^ expandedKey[(round*16) + 15];
+ state[15] = sbox[(state[11] ^ expandedKey[(round*16) + 11])];
+ state[11] = sbox[(state[ 7] ^ expandedKey[(round*16) + 7])];
+ state[ 7] = sbox[(state[ 3] ^ expandedKey[(round*16) + 3])];
+ state[ 3] = sbox[buf1];
+ // last addroundkey
+ state[ 0]^=expandedKey[160];
+ state[ 1]^=expandedKey[161];
+ state[ 2]^=expandedKey[162];
+ state[ 3]^=expandedKey[163];
+ state[ 4]^=expandedKey[164];
+ state[ 5]^=expandedKey[165];
+ state[ 6]^=expandedKey[166];
+ state[ 7]^=expandedKey[167];
+ state[ 8]^=expandedKey[168];
+ state[ 9]^=expandedKey[169];
+ state[10]^=expandedKey[170];
+ state[11]^=expandedKey[171];
+ state[12]^=expandedKey[172];
+ state[13]^=expandedKey[173];
+ state[14]^=expandedKey[174];
+ state[15]^=expandedKey[175];
+}
+
+//*****************************************************************************
+//
+//! aes_decr
+//!
+//! @param[in] expandedKey expanded AES128 key
+//! @param[in\out] state 16 bytes of cipher text and plain text
+//!
+//! @return none
+//!
+//! @brief internal implementation of AES128 decryption.
+//! straight forward aes decryption implementation
+//! the order of substeps is the exact reverse of decryption
+//! inverse functions:
+//! - addRoundKey is its own inverse
+//! - rsbox is inverse of sbox
+//! - rightshift instead of leftshift
+//! - invMixColumns = barreto + mixColumns
+//! no further subfunctions to save cycles for function calls
+//! no structuring with "for (....)" to save cycles
+//!
+//*****************************************************************************
+
+void aes_decr(unsigned char *state, unsigned char *expandedKey)
+{
+ unsigned char buf1, buf2, buf3;
+ signed char round;
+ round = 9;
+
+ // initial addroundkey
+ state[ 0]^=expandedKey[160];
+ state[ 1]^=expandedKey[161];
+ state[ 2]^=expandedKey[162];
+ state[ 3]^=expandedKey[163];
+ state[ 4]^=expandedKey[164];
+ state[ 5]^=expandedKey[165];
+ state[ 6]^=expandedKey[166];
+ state[ 7]^=expandedKey[167];
+ state[ 8]^=expandedKey[168];
+ state[ 9]^=expandedKey[169];
+ state[10]^=expandedKey[170];
+ state[11]^=expandedKey[171];
+ state[12]^=expandedKey[172];
+ state[13]^=expandedKey[173];
+ state[14]^=expandedKey[174];
+ state[15]^=expandedKey[175];
+
+ // 10th round without mixcols
+ state[ 0] = rsbox[state[ 0]] ^ expandedKey[(round*16) ];
+ state[ 4] = rsbox[state[ 4]] ^ expandedKey[(round*16) + 4];
+ state[ 8] = rsbox[state[ 8]] ^ expandedKey[(round*16) + 8];
+ state[12] = rsbox[state[12]] ^ expandedKey[(round*16) + 12];
+ // row 1
+ buf1 = rsbox[state[13]] ^ expandedKey[(round*16) + 1];
+ state[13] = rsbox[state[ 9]] ^ expandedKey[(round*16) + 13];
+ state[ 9] = rsbox[state[ 5]] ^ expandedKey[(round*16) + 9];
+ state[ 5] = rsbox[state[ 1]] ^ expandedKey[(round*16) + 5];
+ state[ 1] = buf1;
+ // row 2
+ buf1 = rsbox[state[ 2]] ^ expandedKey[(round*16) + 10];
+ buf2 = rsbox[state[ 6]] ^ expandedKey[(round*16) + 14];
+ state[ 2] = rsbox[state[10]] ^ expandedKey[(round*16) + 2];
+ state[ 6] = rsbox[state[14]] ^ expandedKey[(round*16) + 6];
+ state[10] = buf1;
+ state[14] = buf2;
+ // row 3
+ buf1 = rsbox[state[ 3]] ^ expandedKey[(round*16) + 15];
+ state[ 3] = rsbox[state[ 7]] ^ expandedKey[(round*16) + 3];
+ state[ 7] = rsbox[state[11]] ^ expandedKey[(round*16) + 7];
+ state[11] = rsbox[state[15]] ^ expandedKey[(round*16) + 11];
+ state[15] = buf1;
+
+ for (round = 8; round >= 0; round--){
+ // barreto
+ //col1
+ buf1 = galois_mul2(galois_mul2(state[0]^state[2]));
+ buf2 = galois_mul2(galois_mul2(state[1]^state[3]));
+ state[0] ^= buf1; state[1] ^= buf2; state[2] ^= buf1; state[3] ^= buf2;
+ //col2
+ buf1 = galois_mul2(galois_mul2(state[4]^state[6]));
+ buf2 = galois_mul2(galois_mul2(state[5]^state[7]));
+ state[4] ^= buf1; state[5] ^= buf2; state[6] ^= buf1; state[7] ^= buf2;
+ //col3
+ buf1 = galois_mul2(galois_mul2(state[8]^state[10]));
+ buf2 = galois_mul2(galois_mul2(state[9]^state[11]));
+ state[8] ^= buf1; state[9] ^= buf2; state[10] ^= buf1; state[11] ^= buf2;
+ //col4
+ buf1 = galois_mul2(galois_mul2(state[12]^state[14]));
+ buf2 = galois_mul2(galois_mul2(state[13]^state[15]));
+ state[12] ^= buf1; state[13] ^= buf2; state[14] ^= buf1; state[15] ^= buf2;
+ // mixcolums //////////
+ // col1
+ buf1 = state[0] ^ state[1] ^ state[2] ^ state[3];
+ buf2 = state[0];
+ buf3 = state[0]^state[1]; buf3=galois_mul2(buf3); state[0] = state[0] ^ buf3 ^ buf1;
+ buf3 = state[1]^state[2]; buf3=galois_mul2(buf3); state[1] = state[1] ^ buf3 ^ buf1;
+ buf3 = state[2]^state[3]; buf3=galois_mul2(buf3); state[2] = state[2] ^ buf3 ^ buf1;
+ buf3 = state[3]^buf2; buf3=galois_mul2(buf3); state[3] = state[3] ^ buf3 ^ buf1;
+ // col2
+ buf1 = state[4] ^ state[5] ^ state[6] ^ state[7];
+ buf2 = state[4];
+ buf3 = state[4]^state[5]; buf3=galois_mul2(buf3); state[4] = state[4] ^ buf3 ^ buf1;
+ buf3 = state[5]^state[6]; buf3=galois_mul2(buf3); state[5] = state[5] ^ buf3 ^ buf1;
+ buf3 = state[6]^state[7]; buf3=galois_mul2(buf3); state[6] = state[6] ^ buf3 ^ buf1;
+ buf3 = state[7]^buf2; buf3=galois_mul2(buf3); state[7] = state[7] ^ buf3 ^ buf1;
+ // col3
+ buf1 = state[8] ^ state[9] ^ state[10] ^ state[11];
+ buf2 = state[8];
+ buf3 = state[8]^state[9]; buf3=galois_mul2(buf3); state[8] = state[8] ^ buf3 ^ buf1;
+ buf3 = state[9]^state[10]; buf3=galois_mul2(buf3); state[9] = state[9] ^ buf3 ^ buf1;
+ buf3 = state[10]^state[11]; buf3=galois_mul2(buf3); state[10] = state[10] ^ buf3 ^ buf1;
+ buf3 = state[11]^buf2; buf3=galois_mul2(buf3); state[11] = state[11] ^ buf3 ^ buf1;
+ // col4
+ buf1 = state[12] ^ state[13] ^ state[14] ^ state[15];
+ buf2 = state[12];
+ buf3 = state[12]^state[13]; buf3=galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1;
+ buf3 = state[13]^state[14]; buf3=galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1;
+ buf3 = state[14]^state[15]; buf3=galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1;
+ buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1;
+
+ // addroundkey, rsbox and shiftrows
+ // row 0
+ state[ 0] = rsbox[state[ 0]] ^ expandedKey[(round*16) ];
+ state[ 4] = rsbox[state[ 4]] ^ expandedKey[(round*16) + 4];
+ state[ 8] = rsbox[state[ 8]] ^ expandedKey[(round*16) + 8];
+ state[12] = rsbox[state[12]] ^ expandedKey[(round*16) + 12];
+ // row 1
+ buf1 = rsbox[state[13]] ^ expandedKey[(round*16) + 1];
+ state[13] = rsbox[state[ 9]] ^ expandedKey[(round*16) + 13];
+ state[ 9] = rsbox[state[ 5]] ^ expandedKey[(round*16) + 9];
+ state[ 5] = rsbox[state[ 1]] ^ expandedKey[(round*16) + 5];
+ state[ 1] = buf1;
+ // row 2
+ buf1 = rsbox[state[ 2]] ^ expandedKey[(round*16) + 10];
+ buf2 = rsbox[state[ 6]] ^ expandedKey[(round*16) + 14];
+ state[ 2] = rsbox[state[10]] ^ expandedKey[(round*16) + 2];
+ state[ 6] = rsbox[state[14]] ^ expandedKey[(round*16) + 6];
+ state[10] = buf1;
+ state[14] = buf2;
+ // row 3
+ buf1 = rsbox[state[ 3]] ^ expandedKey[(round*16) + 15];
+ state[ 3] = rsbox[state[ 7]] ^ expandedKey[(round*16) + 3];
+ state[ 7] = rsbox[state[11]] ^ expandedKey[(round*16) + 7];
+ state[11] = rsbox[state[15]] ^ expandedKey[(round*16) + 11];
+ state[15] = buf1;
+ }
+
+}
+
+//*****************************************************************************
+//
+//! aes_encrypt
+//!
+//! @param[in] key AES128 key of size 16 bytes
+//! @param[in\out] state 16 bytes of plain text and cipher text
+//!
+//! @return none
+//!
+//! @brief AES128 encryption:
+//! Given AES128 key and 16 bytes plain text, cipher text of 16 bytes
+//! is computed. The AES implementation is in mode ECB (Electronic
+//! Code Book).
+//!
+//!
+//*****************************************************************************
+
+void aes_encrypt(unsigned char *state,
+ unsigned char *key)
+{
+ // expand the key into 176 bytes
+ expandKey(expandedKey, key);
+ aes_encr(state, expandedKey);
+}
+
+//*****************************************************************************
+//
+//! aes_decrypt
+//!
+//! @param[in] key AES128 key of size 16 bytes
+//! @param[in\out] state 16 bytes of cipher text and plain text
+//!
+//! @return none
+//!
+//! @brief AES128 decryption:
+//! Given AES128 key and 16 bytes cipher text, plain text of 16 bytes
+//! is computed The AES implementation is in mode ECB
+//! (Electronic Code Book).
+//!
+//!
+//*****************************************************************************
+
+void aes_decrypt(unsigned char *state,
+ unsigned char *key)
+{
+ expandKey(expandedKey, key); // expand the key into 176 bytes
+ aes_decr(state, expandedKey);
+}
+
+//*****************************************************************************
+//
+//! aes_read_key
+//!
+//! @param[out] key AES128 key of size 16 bytes
+//!
+//! @return on success 0, error otherwise.
+//!
+//! @brief Reads AES128 key from EEPROM
+//! Reads the AES128 key from fileID #12 in EEPROM
+//! returns an error if the key does not exist.
+//!
+//!
+//*****************************************************************************
+
+signed long aes_read_key(unsigned char *key)
+{
+ signed long returnValue;
+
+ returnValue = nvmem_read(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key);
+
+ return returnValue;
+}
+
+//*****************************************************************************
+//
+//! aes_write_key
+//!
+//! @param[out] key AES128 key of size 16 bytes
+//!
+//! @return on success 0, error otherwise.
+//!
+//! @brief writes AES128 key from EEPROM
+//! Writes the AES128 key to fileID #12 in EEPROM
+//!
+//!
+//*****************************************************************************
+
+signed long aes_write_key(unsigned char *key)
+{
+ signed long returnValue;
+
+ returnValue = nvmem_write(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key);
+
+ return returnValue;
+}
+
+#endif //CC3000_UNENCRYPTED_SMART_CONFIG
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CC3000HostDriver/security.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,131 @@
+/*****************************************************************************
+*
+* security.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 __SECURITY__
+#define __SECURITY__
+
+#include "nvmem.h"
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define AES128_KEY_SIZE 16
+
+#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
+
+
+//*****************************************************************************
+//
+//! aes_encrypt
+//!
+//! @param[in] key AES128 key of size 16 bytes
+//! @param[in\out] state 16 bytes of plain text and cipher text
+//!
+//! @return none
+//!
+//! @brief AES128 encryption:
+//! Given AES128 key and 16 bytes plain text, cipher text of 16 bytes
+//! is computed. The AES implementation is in mode ECB (Electronic
+//! Code Book).
+//!
+//!
+//*****************************************************************************
+extern void aes_encrypt(unsigned char *state, unsigned char *key);
+
+//*****************************************************************************
+//
+//! aes_decrypt
+//!
+//! @param[in] key AES128 key of size 16 bytes
+//! @param[in\out] state 16 bytes of cipher text and plain text
+//!
+//! @return none
+//!
+//! @brief AES128 decryption:
+//! Given AES128 key and 16 bytes cipher text, plain text of 16 bytes
+//! is computed The AES implementation is in mode ECB
+//! (Electronic Code Book).
+//!
+//!
+//*****************************************************************************
+extern void aes_decrypt(unsigned char *state, unsigned char *key);
+
+
+//*****************************************************************************
+//
+//! aes_read_key
+//!
+//! @param[out] key AES128 key of size 16 bytes
+//!
+//! @return on success 0, error otherwise.
+//!
+//! @brief Reads AES128 key from EEPROM
+//! Reads the AES128 key from fileID #12 in EEPROM
+//! returns an error if the key does not exist.
+//!
+//!
+//*****************************************************************************
+extern signed long aes_read_key(unsigned char *key);
+
+//*****************************************************************************
+//
+//! aes_write_key
+//!
+//! @param[out] key AES128 key of size 16 bytes
+//!
+//! @return on success 0, error otherwise.
+//!
+//! @brief writes AES128 key from EEPROM
+//! Writes the AES128 key to fileID #12 in EEPROM
+//!
+//!
+//*****************************************************************************
+extern signed long aes_write_key(unsigned char *key);
+
+#endif //CC3000_UNENCRYPTED_SMART_CONFIG
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CC3000HostDriver/socket.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,1170 @@
+/*****************************************************************************
+*
+* socket.c - CC3000 Host Driver Implementation.
+* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+
+//*****************************************************************************
+//
+//! \addtogroup socket_api
+//! @{
+//
+//*****************************************************************************
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "hci.h"
+#include "socket.h"
+#include "evnt_handler.h"
+#include "netapp.h"
+
+
+
+//Enable this flag if and only if you must comply with BSD socket
+//close() function
+#ifdef _API_USE_BSD_CLOSE
+ #define close(sd) closesocket(sd)
+#endif
+
+//Enable this flag if and only if you must comply with BSD socket read() and
+//write() functions
+#ifdef _API_USE_BSD_READ_WRITE
+ #define read(sd, buf, len, flags) recv(sd, buf, len, flags)
+ #define write(sd, buf, len, flags) send(sd, buf, len, flags)
+#endif
+
+#define SOCKET_OPEN_PARAMS_LEN (12)
+#define SOCKET_CLOSE_PARAMS_LEN (4)
+#define SOCKET_ACCEPT_PARAMS_LEN (4)
+#define SOCKET_BIND_PARAMS_LEN (20)
+#define SOCKET_LISTEN_PARAMS_LEN (8)
+#define SOCKET_GET_HOST_BY_NAME_PARAMS_LEN (9)
+#define SOCKET_CONNECT_PARAMS_LEN (20)
+#define SOCKET_SELECT_PARAMS_LEN (44)
+#define SOCKET_SET_SOCK_OPT_PARAMS_LEN (20)
+#define SOCKET_GET_SOCK_OPT_PARAMS_LEN (12)
+#define SOCKET_RECV_FROM_PARAMS_LEN (12)
+#define SOCKET_SENDTO_PARAMS_LEN (24)
+#define SOCKET_MDNS_ADVERTISE_PARAMS_LEN (12)
+
+
+// The legnth of arguments for the SEND command: sd + buff_offset + len + flags,
+// while size of each parameter is 32 bit - so the total length is 16 bytes;
+
+#define HCI_CMND_SEND_ARG_LENGTH (16)
+
+
+#define SELECT_TIMEOUT_MIN_MICRO_SECONDS 5000
+
+#define HEADERS_SIZE_DATA (SPI_HEADER_SIZE + 5)
+
+#define SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE)
+
+#define MDNS_DEVICE_SERVICE_MAX_LENGTH (32)
+
+
+//*****************************************************************************
+//
+//! HostFlowControlConsumeBuff
+//!
+//! @param sd socket descriptor
+//!
+//! @return 0 in case there are buffers available,
+//! -1 in case of bad socket
+//! -2 if there are no free buffers present (only when
+//! SEND_NON_BLOCKING is enabled)
+//!
+//! @brief if SEND_NON_BLOCKING not define - block until have free buffer
+//! becomes available, else return immediately with correct status
+//! regarding the buffers available.
+//
+//*****************************************************************************
+int
+HostFlowControlConsumeBuff(int sd)
+{
+#ifndef SEND_NON_BLOCKING
+ /* wait in busy loop */
+ do
+ {
+ // In case last transmission failed then we will return the last failure
+ // reason here.
+ // Note that the buffer will not be allocated in this case
+ if (tSLInformation.slTransmitDataError != 0)
+ {
+ errno = tSLInformation.slTransmitDataError;
+ tSLInformation.slTransmitDataError = 0;
+ return errno;
+ }
+
+ if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd))
+ return -1;
+ } while(0 == tSLInformation.usNumberOfFreeBuffers);
+
+ tSLInformation.usNumberOfFreeBuffers--;
+
+ return 0;
+#else
+
+ // In case last transmission failed then we will return the last failure
+ // reason here.
+ // Note that the buffer will not be allocated in this case
+ if (tSLInformation.slTransmitDataError != 0)
+ {
+ errno = tSLInformation.slTransmitDataError;
+ tSLInformation.slTransmitDataError = 0;
+ return errno;
+ }
+ if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd))
+ return -1;
+
+ //If there are no available buffers, return -2. It is recommended to use
+ // select or receive to see if there is any buffer occupied with received data
+ // If so, call receive() to release the buffer.
+ if(0 == tSLInformation.usNumberOfFreeBuffers)
+ {
+ return -2;
+ }
+ else
+ {
+ tSLInformation.usNumberOfFreeBuffers--;
+ return 0;
+ }
+#endif
+}
+
+//*****************************************************************************
+//
+//! socket
+//!
+//! @param domain selects the protocol family which will be used for
+//! communication. On this version only AF_INET is supported
+//! @param type specifies the communication semantics. On this version
+//! only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW are supported
+//! @param protocol specifies a particular protocol to be used with the
+//! socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are
+//! supported.
+//!
+//! @return On success, socket handle that is used for consequent socket
+//! operations. On error, -1 is returned.
+//!
+//! @brief create an endpoint for communication
+//! The socket function creates a socket that is bound to a specific
+//! transport service provider. This function is called by the
+//! application layer to obtain a socket handle.
+//
+//*****************************************************************************
+
+int
+socket(long domain, long type, long protocol)
+{
+ long ret;
+ unsigned char *ptr, *args;
+
+ ret = EFAIL;
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in HCI packet structure
+ args = UINT32_TO_STREAM(args, domain);
+ args = UINT32_TO_STREAM(args, type);
+ args = UINT32_TO_STREAM(args, protocol);
+
+ // Initiate a HCI command
+ hci_command_send(HCI_CMND_SOCKET, ptr, SOCKET_OPEN_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(HCI_CMND_SOCKET, &ret);
+
+ // Process the event
+ errno = ret;
+
+ set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
+
+ return(ret);
+}
+
+//*****************************************************************************
+//
+//! closesocket
+//!
+//! @param sd socket handle.
+//!
+//! @return On success, zero is returned. On error, -1 is returned.
+//!
+//! @brief The socket function closes a created socket.
+//
+//*****************************************************************************
+
+long
+closesocket(long sd)
+{
+ long ret;
+ unsigned char *ptr, *args;
+
+ ret = EFAIL;
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in HCI packet structure
+ args = UINT32_TO_STREAM(args, sd);
+
+ // Initiate a HCI command
+ hci_command_send(HCI_CMND_CLOSE_SOCKET,
+ ptr, SOCKET_CLOSE_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(HCI_CMND_CLOSE_SOCKET, &ret);
+ errno = ret;
+
+ // since 'close' call may result in either OK (and then it closed) or error
+ // mark this socket as invalid
+ set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
+
+ return(ret);
+}
+
+//*****************************************************************************
+//
+//! accept
+//!
+//! @param[in] sd socket descriptor (handle)
+//! @param[out] addr the argument addr is a pointer to a sockaddr structure
+//! This structure is filled in with the address of the
+//! peer socket, as known to the communications layer.
+//! determined. The exact format of the address returned
+//! addr is by the socket's address sockaddr.
+//! On this version only AF_INET is supported.
+//! This argument returns in network order.
+//! @param[out] addrlen the addrlen argument is a value-result argument:
+//! it should initially contain the size of the structure
+//! pointed to by addr.
+//!
+//! @return For socket in blocking mode:
+//! On success, socket handle. on failure negative
+//! For socket in non-blocking mode:
+//! - On connection establishment, socket handle
+//! - On connection pending, SOC_IN_PROGRESS (-2)
+//! - On failure, SOC_ERROR (-1)
+//!
+//! @brief accept a connection on a socket:
+//! This function is used with connection-based socket types
+//! (SOCK_STREAM). It extracts the first connection request on the
+//! queue of pending connections, creates a new connected socket, and
+//! returns a new file descriptor referring to that socket.
+//! The newly created socket is not in the listening state.
+//! The original socket sd is unaffected by this call.
+//! The argument sd is a socket that has been created with socket(),
+//! bound to a local address with bind(), and is listening for
+//! connections after a listen(). The argument addr is a pointer
+//! to a sockaddr structure. This structure is filled in with the
+//! address of the peer socket, as known to the communications layer.
+//! The exact format of the address returned addr is determined by the
+//! socket's address family. The addrlen argument is a value-result
+//! argument: it should initially contain the size of the structure
+//! pointed to by addr, on return it will contain the actual
+//! length (in bytes) of the address returned.
+//!
+//! @sa socket ; bind ; listen
+//
+//*****************************************************************************
+
+long
+accept(long sd, sockaddr *addr, socklen_t *addrlen)
+{
+ long ret;
+ unsigned char *ptr, *args;
+ tBsdReturnParams tAcceptReturnArguments;
+
+ ret = EFAIL;
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, sd);
+
+ // Initiate a HCI command
+ hci_command_send(HCI_CMND_ACCEPT,
+ ptr, SOCKET_ACCEPT_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(HCI_CMND_ACCEPT, &tAcceptReturnArguments);
+
+
+ // need specify return parameters!!!
+ memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN);
+ *addrlen = ASIC_ADDR_LEN;
+ errno = tAcceptReturnArguments.iStatus;
+ ret = errno;
+
+ // if succeeded, iStatus = new socket descriptor. otherwise - error number
+ if(M_IS_VALID_SD(ret))
+ {
+ set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
+ }
+ else
+ {
+ set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
+ }
+
+ return(ret);
+}
+
+//*****************************************************************************
+//
+//! bind
+//!
+//! @param[in] sd socket descriptor (handle)
+//! @param[out] addr specifies the destination address. On this version
+//! only AF_INET is supported.
+//! @param[out] addrlen contains the size of the structure pointed to by addr.
+//!
+//! @return On success, zero is returned. On error, -1 is returned.
+//!
+//! @brief assign a name to a socket
+//! This function gives the socket the local address addr.
+//! addr is addrlen bytes long. Traditionally, this is called when a
+//! socket is created with socket, it exists in a name space (address
+//! family) but has no name assigned.
+//! It is necessary to assign a local address before a SOCK_STREAM
+//! socket may receive connections.
+//!
+//! @sa socket ; accept ; listen
+//
+//*****************************************************************************
+
+long
+bind(long sd, const sockaddr *addr, long addrlen)
+{
+ long ret;
+ unsigned char *ptr, *args;
+
+ ret = EFAIL;
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ addrlen = ASIC_ADDR_LEN;
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, sd);
+ args = UINT32_TO_STREAM(args, 0x00000008);
+ args = UINT32_TO_STREAM(args, addrlen);
+ ARRAY_TO_STREAM(args, ((unsigned char *)addr), addrlen);
+
+ // Initiate a HCI command
+ hci_command_send(HCI_CMND_BIND,
+ ptr, SOCKET_BIND_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(HCI_CMND_BIND, &ret);
+
+ errno = ret;
+
+ return(ret);
+}
+
+//*****************************************************************************
+//
+//! listen
+//!
+//! @param[in] sd socket descriptor (handle)
+//! @param[in] backlog specifies the listen queue depth. On this version
+//! backlog is not supported.
+//! @return On success, zero is returned. On error, -1 is returned.
+//!
+//! @brief listen for connections on a socket
+//! The willingness to accept incoming connections and a queue
+//! limit for incoming connections are specified with listen(),
+//! and then the connections are accepted with accept.
+//! The listen() call applies only to sockets of type SOCK_STREAM
+//! The backlog parameter defines the maximum length the queue of
+//! pending connections may grow to.
+//!
+//! @sa socket ; accept ; bind
+//!
+//! @note On this version, backlog is not supported
+//
+//*****************************************************************************
+
+long
+listen(long sd, long backlog)
+{
+ long ret;
+ unsigned char *ptr, *args;
+
+ ret = EFAIL;
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, sd);
+ args = UINT32_TO_STREAM(args, backlog);
+
+ // Initiate a HCI command
+ hci_command_send(HCI_CMND_LISTEN,
+ ptr, SOCKET_LISTEN_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(HCI_CMND_LISTEN, &ret);
+ errno = ret;
+
+ return(ret);
+}
+
+//*****************************************************************************
+//
+//! gethostbyname
+//!
+//! @param[in] hostname host name
+//! @param[in] usNameLen name length
+//! @param[out] out_ip_addr This parameter is filled in with host IP address.
+//! In case that host name is not resolved,
+//! out_ip_addr is zero.
+//! @return On success, positive is returned. On error, negative is returned
+//!
+//! @brief Get host IP by name. Obtain the IP Address of machine on network,
+//! by its name.
+//!
+//! @note On this version, only blocking mode is supported. Also note that
+//! the function requires DNS server to be configured prior to its usage.
+//
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+int
+gethostbyname(char * hostname, unsigned short usNameLen,
+ unsigned long* out_ip_addr)
+{
+ tBsdGethostbynameParams ret;
+ unsigned char *ptr, *args;
+
+ errno = EFAIL;
+
+ if (usNameLen > HOSTNAME_MAX_LENGTH)
+ {
+ return errno;
+ }
+
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
+
+ // Fill in HCI packet structure
+ args = UINT32_TO_STREAM(args, 8);
+ args = UINT32_TO_STREAM(args, usNameLen);
+ ARRAY_TO_STREAM(args, hostname, usNameLen);
+
+ // Initiate a HCI command
+ hci_command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN
+ + usNameLen - 1);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(HCI_EVNT_BSD_GETHOSTBYNAME, &ret);
+
+ errno = ret.retVal;
+
+ (*((long*)out_ip_addr)) = ret.outputAddress;
+
+ return (errno);
+
+}
+#endif
+
+//*****************************************************************************
+//
+//! connect
+//!
+//! @param[in] sd socket descriptor (handle)
+//! @param[in] addr specifies the destination addr. On this version
+//! only AF_INET is supported.
+//! @param[out] addrlen contains the size of the structure pointed to by addr
+//! @return On success, zero is returned. On error, -1 is returned
+//!
+//! @brief initiate a connection on a socket
+//! Function connects the socket referred to by the socket descriptor
+//! sd, to the address specified by addr. The addrlen argument
+//! specifies the size of addr. The format of the address in addr is
+//! determined by the address space of the socket. If it is of type
+//! SOCK_DGRAM, this call specifies the peer with which the socket is
+//! to be associated; this address is that to which datagrams are to be
+//! sent, and the only address from which datagrams are to be received.
+//! If the socket is of type SOCK_STREAM, this call attempts to make a
+//! connection to another socket. The other socket is specified by
+//! address, which is an address in the communications space of the
+//! socket. Note that the function implements only blocking behavior
+//! thus the caller will be waiting either for the connection
+//! establishment or for the connection establishment failure.
+//!
+//! @sa socket
+//
+//*****************************************************************************
+
+long
+connect(long sd, const sockaddr *addr, long addrlen)
+{
+ long int ret;
+ unsigned char *ptr, *args;
+
+ ret = EFAIL;
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
+ addrlen = 8;
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, sd);
+ args = UINT32_TO_STREAM(args, 0x00000008);
+ args = UINT32_TO_STREAM(args, addrlen);
+ ARRAY_TO_STREAM(args, ((unsigned char *)addr), addrlen);
+
+ // Initiate a HCI command
+ hci_command_send(HCI_CMND_CONNECT,
+ ptr, SOCKET_CONNECT_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(HCI_CMND_CONNECT, &ret);
+
+ errno = ret;
+
+ return((long)ret);
+}
+
+
+//*****************************************************************************
+//
+//! select
+//!
+//! @param[in] nfds the highest-numbered file descriptor in any of the
+//! three sets, plus 1.
+//! @param[out] writesds socket descriptors list for write monitoring
+//! @param[out] readsds socket descriptors list for read monitoring
+//! @param[out] exceptsds socket descriptors list for exception monitoring
+//! @param[in] timeout is an upper bound on the amount of time elapsed
+//! before select() returns. Null means infinity
+//! timeout. The minimum timeout is 5 milliseconds,
+//! less than 5 milliseconds will be set
+//! automatically to 5 milliseconds.
+//! @return On success, select() returns the number of file descriptors
+//! contained in the three returned descriptor sets (that is, the
+//! total number of bits that are set in readfds, writefds,
+//! exceptfds) which may be zero if the timeout expires before
+//! anything interesting happens.
+//! On error, -1 is returned.
+//! *readsds - return the sockets on which Read request will
+//! return without delay with valid data.
+//! *writesds - return the sockets on which Write request
+//! will return without delay.
+//! *exceptsds - return the sockets which closed recently.
+//!
+//! @brief Monitor socket activity
+//! Select allow a program to monitor multiple file descriptors,
+//! waiting until one or more of the file descriptors become
+//! "ready" for some class of I/O operation
+//!
+//! @Note If the timeout value set to less than 5ms it will automatically set
+//! to 5ms to prevent overload of the system
+//!
+//! @sa socket
+//
+//*****************************************************************************
+
+int
+select(long nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds,
+ struct timeval *timeout)
+{
+ unsigned char *ptr, *args;
+ tBsdSelectRecvParams tParams;
+ unsigned long is_blocking;
+
+ if( timeout == NULL)
+ {
+ is_blocking = 1; /* blocking , infinity timeout */
+ }
+ else
+ {
+ is_blocking = 0; /* no blocking, timeout */
+ }
+
+ // Fill in HCI packet structure
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, nfds);
+ args = UINT32_TO_STREAM(args, 0x00000014);
+ args = UINT32_TO_STREAM(args, 0x00000014);
+ args = UINT32_TO_STREAM(args, 0x00000014);
+ args = UINT32_TO_STREAM(args, 0x00000014);
+ args = UINT32_TO_STREAM(args, is_blocking);
+ args = UINT32_TO_STREAM(args, ((readsds) ? *(unsigned long*)readsds : 0));
+ args = UINT32_TO_STREAM(args, ((writesds) ? *(unsigned long*)writesds : 0));
+ args = UINT32_TO_STREAM(args, ((exceptsds) ? *(unsigned long*)exceptsds : 0));
+
+ if (timeout)
+ {
+ if ( 0 == timeout->tv_sec && timeout->tv_usec <
+ SELECT_TIMEOUT_MIN_MICRO_SECONDS)
+ {
+ timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS;
+ }
+ args = UINT32_TO_STREAM(args, timeout->tv_sec);
+ args = UINT32_TO_STREAM(args, timeout->tv_usec);
+ }
+
+ // Initiate a HCI command
+ hci_command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(HCI_EVNT_SELECT, &tParams);
+
+ // Update actually read FD
+ if (tParams.iStatus >= 0)
+ {
+ if (readsds)
+ {
+ memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd));
+ }
+
+ if (writesds)
+ {
+ memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd));
+ }
+
+ if (exceptsds)
+ {
+ memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd));
+ }
+
+ return(tParams.iStatus);
+
+ }
+ else
+ {
+ errno = tParams.iStatus;
+ return(-1);
+ }
+}
+
+//*****************************************************************************
+//
+//! setsockopt
+//!
+//! @param[in] sd socket handle
+//! @param[in] level defines the protocol level for this option
+//! @param[in] optname defines the option name to Interrogate
+//! @param[in] optval specifies a value for the option
+//! @param[in] optlen specifies the length of the option value
+//! @return On success, zero is returned. On error, -1 is returned
+//!
+//! @brief set socket options
+//! This function manipulate the options associated with a socket.
+//! Options may exist at multiple protocol levels; they are always
+//! present at the uppermost socket level.
+//! When manipulating socket options the level at which the option
+//! resides and the name of the option must be specified.
+//! To manipulate options at the socket level, level is specified as
+//! SOL_SOCKET. To manipulate options at any other level the protocol
+//! number of the appropriate protocol controlling the option is
+//! supplied. For example, to indicate that an option is to be
+//! interpreted by the TCP protocol, level should be set to the
+//! protocol number of TCP;
+//! The parameters optval and optlen are used to access optval -
+//! use for setsockopt(). For getsockopt() they identify a buffer
+//! in which the value for the requested option(s) are to
+//! be returned. For getsockopt(), optlen is a value-result
+//! parameter, initially containing the size of the buffer
+//! pointed to by option_value, and modified on return to
+//! indicate the actual size of the value returned. If no option
+//! value is to be supplied or returned, option_value may be NULL.
+//!
+//! @Note On this version the following two socket options are enabled:
+//! The only protocol level supported in this version
+//! is SOL_SOCKET (level).
+//! 1. SOCKOPT_RECV_TIMEOUT (optname)
+//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout
+//! in milliseconds.
+//! In that case optval should be pointer to unsigned long.
+//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on
+//! or off.
+//! In that case optval should be SOCK_ON or SOCK_OFF (optval).
+//!
+//! @sa getsockopt
+//
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+int
+setsockopt(long sd, long level, long optname, const void *optval,
+ socklen_t optlen)
+{
+ int ret;
+ unsigned char *ptr, *args;
+
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, sd);
+ args = UINT32_TO_STREAM(args, level);
+ args = UINT32_TO_STREAM(args, optname);
+ args = UINT32_TO_STREAM(args, 0x00000008);
+ args = UINT32_TO_STREAM(args, optlen);
+ ARRAY_TO_STREAM(args, ((unsigned char *)optval), optlen);
+
+ // Initiate a HCI command
+ hci_command_send(HCI_CMND_SETSOCKOPT,
+ ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN + optlen);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(HCI_CMND_SETSOCKOPT, &ret);
+
+ if (ret >= 0)
+ {
+ return (0);
+ }
+ else
+ {
+ errno = ret;
+ return (errno);
+ }
+}
+#endif
+
+//*****************************************************************************
+//
+//! getsockopt
+//!
+//! @param[in] sd socket handle
+//! @param[in] level defines the protocol level for this option
+//! @param[in] optname defines the option name to Interrogate
+//! @param[out] optval specifies a value for the option
+//! @param[out] optlen specifies the length of the option value
+//! @return On success, zero is returned. On error, -1 is returned
+//!
+//! @brief set socket options
+//! This function manipulate the options associated with a socket.
+//! Options may exist at multiple protocol levels; they are always
+//! present at the uppermost socket level.
+//! When manipulating socket options the level at which the option
+//! resides and the name of the option must be specified.
+//! To manipulate options at the socket level, level is specified as
+//! SOL_SOCKET. To manipulate options at any other level the protocol
+//! number of the appropriate protocol controlling the option is
+//! supplied. For example, to indicate that an option is to be
+//! interpreted by the TCP protocol, level should be set to the
+//! protocol number of TCP;
+//! The parameters optval and optlen are used to access optval -
+//! use for setsockopt(). For getsockopt() they identify a buffer
+//! in which the value for the requested option(s) are to
+//! be returned. For getsockopt(), optlen is a value-result
+//! parameter, initially containing the size of the buffer
+//! pointed to by option_value, and modified on return to
+//! indicate the actual size of the value returned. If no option
+//! value is to be supplied or returned, option_value may be NULL.
+//!
+//! @Note On this version the following two socket options are enabled:
+//! The only protocol level supported in this version
+//! is SOL_SOCKET (level).
+//! 1. SOCKOPT_RECV_TIMEOUT (optname)
+//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout
+//! in milliseconds.
+//! In that case optval should be pointer to unsigned long.
+//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on
+//! or off.
+//! In that case optval should be SOCK_ON or SOCK_OFF (optval).
+//!
+//! @sa setsockopt
+//
+//*****************************************************************************
+
+int
+getsockopt (long sd, long level, long optname, void *optval, socklen_t *optlen)
+{
+ unsigned char *ptr, *args;
+ tBsdGetSockOptReturnParams tRetParams;
+
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, sd);
+ args = UINT32_TO_STREAM(args, level);
+ args = UINT32_TO_STREAM(args, optname);
+
+ // Initiate a HCI command
+ hci_command_send(HCI_CMND_GETSOCKOPT,
+ ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(HCI_CMND_GETSOCKOPT, &tRetParams);
+
+ if (((signed char)tRetParams.iStatus) >= 0)
+ {
+ *optlen = 4;
+ memcpy(optval, tRetParams.ucOptValue, 4);
+ return (0);
+ }
+ else
+ {
+ errno = tRetParams.iStatus;
+ return (errno);
+ }
+}
+
+//*****************************************************************************
+//
+//! simple_link_recv
+//!
+//! @param sd socket handle
+//! @param buf read buffer
+//! @param len buffer length
+//! @param flags indicates blocking or non-blocking operation
+//! @param from pointer to an address structure indicating source address
+//! @param fromlen source address structure size
+//!
+//! @return Return the number of bytes received, or -1 if an error
+//! occurred
+//!
+//! @brief Read data from socket
+//! Return the length of the message on successful completion.
+//! If a message is too long to fit in the supplied buffer,
+//! excess bytes may be discarded depending on the type of
+//! socket the message is received from
+//
+//*****************************************************************************
+int
+simple_link_recv(long sd, void *buf, long len, long flags, sockaddr *from,
+ socklen_t *fromlen, long opcode)
+{
+ unsigned char *ptr, *args;
+ tBsdReadReturnParams tSocketReadEvent;
+
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in HCI packet structure
+ args = UINT32_TO_STREAM(args, sd);
+ args = UINT32_TO_STREAM(args, len);
+ args = UINT32_TO_STREAM(args, flags);
+
+ // Generate the read command, and wait for the
+ hci_command_send(opcode, ptr, SOCKET_RECV_FROM_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(opcode, &tSocketReadEvent);
+
+ // In case the number of bytes is more then zero - read data
+ if (tSocketReadEvent.iNumberOfBytes > 0)
+ {
+ // Wait for the data in a synchronous way. Here we assume that the bug is
+ // big enough to store also parameters of receive from too....
+ SimpleLinkWaitData((unsigned char *)buf, (unsigned char *)from, (unsigned char *)fromlen);
+ }
+
+ errno = tSocketReadEvent.iNumberOfBytes;
+
+ return(tSocketReadEvent.iNumberOfBytes);
+}
+
+//*****************************************************************************
+//
+//! recv
+//!
+//! @param[in] sd socket handle
+//! @param[out] buf Points to the buffer where the message should be stored
+//! @param[in] len Specifies the length in bytes of the buffer pointed to
+//! by the buffer argument.
+//! @param[in] flags Specifies the type of message reception.
+//! On this version, this parameter is not supported.
+//!
+//! @return Return the number of bytes received, or -1 if an error
+//! occurred
+//!
+//! @brief function receives a message from a connection-mode socket
+//!
+//! @sa recvfrom
+//!
+//! @Note On this version, only blocking mode is supported.
+//
+//*****************************************************************************
+
+int
+recv(long sd, void *buf, long len, long flags)
+{
+ return(simple_link_recv(sd, buf, len, flags, NULL, NULL, HCI_CMND_RECV));
+}
+
+//*****************************************************************************
+//
+//! recvfrom
+//!
+//! @param[in] sd socket handle
+//! @param[out] buf Points to the buffer where the message should be stored
+//! @param[in] len Specifies the length in bytes of the buffer pointed to
+//! by the buffer argument.
+//! @param[in] flags Specifies the type of message reception.
+//! On this version, this parameter is not supported.
+//! @param[in] from pointer to an address structure indicating the source
+//! address: sockaddr. On this version only AF_INET is
+//! supported.
+//! @param[in] fromlen source address tructure size
+//!
+//! @return Return the number of bytes received, or -1 if an error
+//! occurred
+//!
+//! @brief read data from socket
+//! function receives a message from a connection-mode or
+//! connectionless-mode socket. Note that raw sockets are not
+//! supported.
+//!
+//! @sa recv
+//!
+//! @Note On this version, only blocking mode is supported.
+//
+//*****************************************************************************
+int
+recvfrom(long sd, void *buf, long len, long flags, sockaddr *from,
+ socklen_t *fromlen)
+{
+ return(simple_link_recv(sd, buf, len, flags, from, fromlen,
+ HCI_CMND_RECVFROM));
+}
+
+//*****************************************************************************
+//
+//! simple_link_send
+//!
+//! @param sd socket handle
+//! @param buf write buffer
+//! @param len buffer length
+//! @param flags On this version, this parameter is not supported
+//! @param to pointer to an address structure indicating destination
+//! address
+//! @param tolen destination address structure size
+//!
+//! @return Return the number of bytes transmitted, or -1 if an error
+//! occurred, or -2 in case there are no free buffers available
+//! (only when SEND_NON_BLOCKING is enabled)
+//!
+//! @brief This function is used to transmit a message to another
+//! socket
+//
+//*****************************************************************************
+int
+simple_link_send(long sd, const void *buf, long len, long flags,
+ const sockaddr *to, long tolen, long opcode)
+{
+ unsigned char uArgSize, addrlen;
+ unsigned char *ptr, *pDataPtr, *args;
+ unsigned long addr_offset;
+ int res;
+ tBsdReadReturnParams tSocketSendEvent;
+
+ // Check the bsd_arguments
+ if (0 != (res = HostFlowControlConsumeBuff(sd)))
+ {
+ return res;
+ }
+
+ //Update the number of sent packets
+ tSLInformation.NumberOfSentPackets++;
+
+ // Allocate a buffer and construct a packet and send it over spi
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (ptr + HEADERS_SIZE_DATA);
+
+ // Update the offset of data and parameters according to the command
+ switch(opcode)
+ {
+ case HCI_CMND_SENDTO:
+ {
+ addr_offset = len + sizeof(len) + sizeof(len);
+ addrlen = 8;
+ uArgSize = SOCKET_SENDTO_PARAMS_LEN;
+ pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN;
+ break;
+ }
+
+ case HCI_CMND_SEND:
+ {
+ tolen = 0;
+ to = NULL;
+ uArgSize = HCI_CMND_SEND_ARG_LENGTH;
+ pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH;
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, sd);
+ args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd));
+ args = UINT32_TO_STREAM(args, len);
+ args = UINT32_TO_STREAM(args, flags);
+
+ if (opcode == HCI_CMND_SENDTO)
+ {
+ args = UINT32_TO_STREAM(args, addr_offset);
+ args = UINT32_TO_STREAM(args, addrlen);
+ }
+
+ // Copy the data received from user into the TX Buffer
+ ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)buf), len);
+
+ // In case we are using SendTo, copy the to parameters
+ if (opcode == HCI_CMND_SENDTO)
+ {
+ ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)to), tolen);
+ }
+
+ // Initiate a HCI command
+ hci_data_send(opcode, ptr, uArgSize, len,(unsigned char*)to, tolen);
+
+ if (opcode == HCI_CMND_SENDTO)
+ SimpleLinkWaitEvent(HCI_EVNT_SENDTO, &tSocketSendEvent);
+ else
+ SimpleLinkWaitEvent(HCI_EVNT_SEND, &tSocketSendEvent);
+
+ return (len);
+}
+
+
+//*****************************************************************************
+//
+//! send
+//!
+//! @param sd socket handle
+//! @param buf Points to a buffer containing the message to be sent
+//! @param len message size in bytes
+//! @param flags On this version, this parameter is not supported
+//!
+//! @return Return the number of bytes transmitted, or -1 if an
+//! error occurred
+//!
+//! @brief Write data to TCP socket
+//! This function is used to transmit a message to another
+//! socket.
+//!
+//! @Note On this version, only blocking mode is supported.
+//!
+//! @sa sendto
+//
+//*****************************************************************************
+
+int
+send(long sd, const void *buf, long len, long flags)
+{
+ return(simple_link_send(sd, buf, len, flags, NULL, 0, HCI_CMND_SEND));
+}
+
+//*****************************************************************************
+//
+//! sendto
+//!
+//! @param sd socket handle
+//! @param buf Points to a buffer containing the message to be sent
+//! @param len message size in bytes
+//! @param flags On this version, this parameter is not supported
+//! @param to pointer to an address structure indicating the destination
+//! address: sockaddr. On this version only AF_INET is
+//! supported.
+//! @param tolen destination address structure size
+//!
+//! @return Return the number of bytes transmitted, or -1 if an
+//! error occurred
+//!
+//! @brief Write data to TCP socket
+//! This function is used to transmit a message to another
+//! socket.
+//!
+//! @Note On this version, only blocking mode is supported.
+//!
+//! @sa send
+//
+//*****************************************************************************
+
+int
+sendto(long sd, const void *buf, long len, long flags, const sockaddr *to,
+ socklen_t tolen)
+{
+ return(simple_link_send(sd, buf, len, flags, to, tolen, HCI_CMND_SENDTO));
+}
+
+//*****************************************************************************
+//
+//! mdnsAdvertiser
+//!
+//! @param[in] mdnsEnabled flag to enable/disable the mDNS feature
+//! @param[in] deviceServiceName Service name as part of the published
+//! canonical domain name
+//! @param[in] deviceServiceNameLength Length of the service name
+//!
+//!
+//! @return On success, zero is returned, return SOC_ERROR if socket was not
+//! opened successfully, or if an error occurred.
+//!
+//! @brief Set CC3000 in mDNS advertiser mode in order to advertise itself.
+//
+//*****************************************************************************
+
+int
+mdnsAdvertiser(unsigned short mdnsEnabled, char * deviceServiceName, unsigned short deviceServiceNameLength)
+{
+ int ret;
+ unsigned char *pTxBuffer, *pArgs;
+
+ if (deviceServiceNameLength > MDNS_DEVICE_SERVICE_MAX_LENGTH)
+ {
+ return EFAIL;
+ }
+
+ pTxBuffer = tSLInformation.pucTxCommandBuffer;
+ pArgs = (pTxBuffer + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
+
+ // Fill in HCI packet structure
+ pArgs = UINT32_TO_STREAM(pArgs, mdnsEnabled);
+ pArgs = UINT32_TO_STREAM(pArgs, 8);
+ pArgs = UINT32_TO_STREAM(pArgs, deviceServiceNameLength);
+ ARRAY_TO_STREAM(pArgs, deviceServiceName, deviceServiceNameLength);
+
+ // Initiate a HCI command
+ hci_command_send(HCI_CMND_MDNS_ADVERTISE, pTxBuffer, SOCKET_MDNS_ADVERTISE_PARAMS_LEN + deviceServiceNameLength);
+
+ // Since we are in blocking state - wait for event complete
+ SimpleLinkWaitEvent(HCI_EVNT_MDNS_ADVERTISE, &ret);
+
+ return ret;
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CC3000HostDriver/socket.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,665 @@
+/*****************************************************************************
+*
+* socket.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 __SOCKET_H__
+#define __SOCKET_H__
+
+
+//*****************************************************************************
+//
+//! \addtogroup socket_api
+//! @{
+//
+//*****************************************************************************
+
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define HOSTNAME_MAX_LENGTH (230) // 230 bytes + header shouldn't exceed 8 bit value
+
+//--------- Address Families --------
+
+#define AF_INET 2
+#define AF_INET6 23
+
+//------------ Socket Types ------------
+
+#define SOCK_STREAM 1
+#define SOCK_DGRAM 2
+#define SOCK_RAW 3 // Raw sockets allow new IPv4 protocols to be implemented in user space. A raw socket receives or sends the raw datagram not including link level headers
+#define SOCK_RDM 4
+#define SOCK_SEQPACKET 5
+
+//----------- Socket Protocol ----------
+
+#define IPPROTO_IP 0 // dummy for IP
+#define IPPROTO_ICMP 1 // control message protocol
+#define IPPROTO_IPV4 IPPROTO_IP // IP inside IP
+#define IPPROTO_TCP 6 // tcp
+#define IPPROTO_UDP 17 // user datagram protocol
+#define IPPROTO_IPV6 41 // IPv6 in IPv6
+#define IPPROTO_NONE 59 // No next header
+#define IPPROTO_RAW 255 // raw IP packet
+#define IPPROTO_MAX 256
+
+//----------- Socket retunr codes -----------
+
+#define SOC_ERROR (-1) // error
+#define SOC_IN_PROGRESS (-2) // socket in progress
+
+//----------- Socket Options -----------
+#define SOL_SOCKET 0xffff // socket level
+#define SOCKOPT_RECV_NONBLOCK 0 // recv non block mode, set SOCK_ON or SOCK_OFF (default block mode)
+#define SOCKOPT_RECV_TIMEOUT 1 // optname to configure recv and recvfromtimeout
+#define SOCKOPT_ACCEPT_NONBLOCK 2 // accept non block mode, set SOCK_ON or SOCK_OFF (default block mode)
+#define SOCK_ON 0 // socket non-blocking mode is enabled
+#define SOCK_OFF 1 // socket blocking mode is enabled
+
+#define TCP_NODELAY 0x0001
+#define TCP_BSDURGENT 0x7000
+
+#define MAX_PACKET_SIZE 1500
+#define MAX_LISTEN_QUEUE 4
+
+#define IOCTL_SOCKET_EVENTMASK
+
+#define ENOBUFS 55 // No buffer space available
+
+#define __FD_SETSIZE 32
+
+#define ASIC_ADDR_LEN 8
+
+#define NO_QUERY_RECIVED -3
+
+
+typedef struct _in_addr_t
+{
+ unsigned long s_addr; // load with inet_aton()
+} in_addr;
+
+typedef struct _sockaddr_t
+{
+ unsigned short int sa_family;
+ unsigned char sa_data[14];
+} sockaddr;
+
+typedef struct _sockaddr_in_t
+{
+ short sin_family; // e.g. AF_INET
+ unsigned short sin_port; // e.g. htons(3490)
+ in_addr sin_addr; // see struct in_addr, below
+ char sin_zero[8]; // zero this if you want to
+} sockaddr_in;
+
+typedef unsigned long socklen_t;
+
+// The fd_set member is required to be an array of longs.
+typedef long int __fd_mask;
+
+// It's easier to assume 8-bit bytes than to get CHAR_BIT.
+#define __NFDBITS (8 * sizeof (__fd_mask))
+#define __FDELT(d) ((d) / __NFDBITS)
+#define __FDMASK(d) ((__fd_mask) 1 << ((d) % __NFDBITS))
+
+// fd_set for select and pselect.
+typedef struct
+{
+ __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];
+#define __FDS_BITS(set) ((set)->fds_bits)
+} fd_set;
+
+// We don't use `memset' because this would require a prototype and
+// the array isn't too big.
+#define __FD_ZERO(set) \
+ do { \
+ unsigned int __i; \
+ fd_set *__arr = (set); \
+ for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i) \
+ __FDS_BITS (__arr)[__i] = 0; \
+ } while (0)
+#define __FD_SET(d, set) (__FDS_BITS (set)[__FDELT (d)] |= __FDMASK (d))
+#define __FD_CLR(d, set) (__FDS_BITS (set)[__FDELT (d)] &= ~__FDMASK (d))
+#define __FD_ISSET(d, set) (__FDS_BITS (set)[__FDELT (d)] & __FDMASK (d))
+
+// Access macros for 'fd_set'.
+#define FD_SET(fd, fdsetp) __FD_SET (fd, fdsetp)
+#define FD_CLR(fd, fdsetp) __FD_CLR (fd, fdsetp)
+#define FD_ISSET(fd, fdsetp) __FD_ISSET (fd, fdsetp)
+#define FD_ZERO(fdsetp) __FD_ZERO (fdsetp)
+
+//Use in case of Big Endian only
+
+#define htonl(A) ((((unsigned long)(A) & 0xff000000) >> 24) | \
+ (((unsigned long)(A) & 0x00ff0000) >> 8) | \
+ (((unsigned long)(A) & 0x0000ff00) << 8) | \
+ (((unsigned long)(A) & 0x000000ff) << 24))
+
+#define ntohl htonl
+
+//Use in case of Big Endian only
+#define htons(A) ((((unsigned long)(A) & 0xff00) >> 8) | \
+ (((unsigned long)(A) & 0x00ff) << 8))
+
+
+#define ntohs htons
+
+// mDNS port - 5353 mDNS multicast address - 224.0.0.251
+#define SET_mDNS_ADD(sockaddr) sockaddr.sa_data[0] = 0x14; \
+ sockaddr.sa_data[1] = 0xe9; \
+ sockaddr.sa_data[2] = 0xe0; \
+ sockaddr.sa_data[3] = 0x0; \
+ sockaddr.sa_data[4] = 0x0; \
+ sockaddr.sa_data[5] = 0xfb;
+
+
+//*****************************************************************************
+//
+// Prototypes for the APIs.
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+//! 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.
+//
+//*****************************************************************************
+extern int socket(long domain, long type, long protocol);
+
+//*****************************************************************************
+//
+//! closesocket
+//!
+//! @param sd socket handle.
+//!
+//! @return On success, zero is returned. On error, -1 is returned.
+//!
+//! @brief The socket function closes a created socket.
+//
+//*****************************************************************************
+extern long closesocket(long sd);
+
+//*****************************************************************************
+//
+//! 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
+//
+//*****************************************************************************
+extern long accept(long sd, sockaddr *addr, socklen_t *addrlen);
+
+//*****************************************************************************
+//
+//! 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
+//
+//*****************************************************************************
+extern long bind(long sd, const sockaddr *addr, long addrlen);
+
+//*****************************************************************************
+//
+//! 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
+//
+//*****************************************************************************
+extern long listen(long sd, long backlog);
+
+//*****************************************************************************
+//
+//! gethostbyname
+//!
+//! @param[in] hostname host name
+//! @param[in] usNameLen name length
+//! @param[out] out_ip_addr This parameter is filled in with host IP address.
+//! In case that host name is not resolved,
+//! out_ip_addr is zero.
+//! @return On success, positive is returned. On error, negative is returned
+//!
+//! @brief Get host IP by name. Obtain the IP Address of machine on network,
+//! by its name.
+//!
+//! @note On this version, only blocking mode is supported. Also note that
+//! the function requires DNS server to be configured prior to its usage.
+//
+//*****************************************************************************
+#ifndef CC3000_TINY_DRIVER
+extern int gethostbyname(char * hostname, unsigned short usNameLen, unsigned long* out_ip_addr);
+#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
+//
+//*****************************************************************************
+extern long connect(long sd, const sockaddr *addr, long addrlen);
+
+//*****************************************************************************
+//
+//! 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
+//
+//*****************************************************************************
+extern int select(long nfds, fd_set *readsds, fd_set *writesds,
+ fd_set *exceptsds, struct timeval *timeout);
+
+//*****************************************************************************
+//
+//! setsockopt
+//!
+//! @param[in] sd socket handle
+//! @param[in] level defines the protocol level for this option
+//! @param[in] optname defines the option name to Interrogate
+//! @param[in] optval specifies a value for the option
+//! @param[in] optlen specifies the length of the option value
+//! @return On success, zero is returned. On error, -1 is returned
+//!
+//! @brief set socket options
+//! This function manipulate the options associated with a socket.
+//! Options may exist at multiple protocol levels; they are always
+//! present at the uppermost socket level.
+//! When manipulating socket options the level at which the option
+//! resides and the name of the option must be specified.
+//! To manipulate options at the socket level, level is specified as
+//! SOL_SOCKET. To manipulate options at any other level the protocol
+//! number of the appropriate protocol controlling the option is
+//! supplied. For example, to indicate that an option is to be
+//! interpreted by the TCP protocol, level should be set to the
+//! protocol number of TCP;
+//! The parameters optval and optlen are used to access optval -
+//! use for setsockopt(). For getsockopt() they identify a buffer
+//! in which the value for the requested option(s) are to
+//! be returned. For getsockopt(), optlen is a value-result
+//! parameter, initially containing the size of the buffer
+//! pointed to by option_value, and modified on return to
+//! indicate the actual size of the value returned. If no option
+//! value is to be supplied or returned, option_value may be NULL.
+//!
+//! @Note On this version the following two socket options are enabled:
+//! The only protocol level supported in this version
+//! is SOL_SOCKET (level).
+//! 1. SOCKOPT_RECV_TIMEOUT (optname)
+//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout
+//! in milliseconds.
+//! In that case optval should be pointer to unsigned long.
+//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on
+//! or off.
+//! In that case optval should be SOCK_ON or SOCK_OFF (optval).
+//!
+//! @sa getsockopt
+//
+//*****************************************************************************
+#ifndef CC3000_TINY_DRIVER
+extern int setsockopt(long sd, long level, long optname, const void *optval,
+ socklen_t optlen);
+#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
+//
+//*****************************************************************************
+extern int getsockopt(long sd, long level, long optname, void *optval,
+ socklen_t *optlen);
+
+//*****************************************************************************
+//
+//! 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.
+//
+//*****************************************************************************
+extern int recv(long sd, void *buf, long len, long flags);
+
+//*****************************************************************************
+//
+//! 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 structure 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.
+//
+//*****************************************************************************
+extern int recvfrom(long sd, void *buf, long len, long flags, sockaddr *from,
+ socklen_t *fromlen);
+
+//*****************************************************************************
+//
+//! 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
+//
+//*****************************************************************************
+
+extern int send(long sd, const void *buf, long len, long flags);
+
+//*****************************************************************************
+//
+//! 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
+//
+//*****************************************************************************
+
+extern int sendto(long sd, const void *buf, long len, long flags,
+ const sockaddr *to, socklen_t tolen);
+
+//*****************************************************************************
+//
+//! 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.
+//
+//*****************************************************************************
+extern int mdnsAdvertiser(unsigned short mdnsEnabled, char * deviceServiceName, unsigned short deviceServiceNameLength);
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
+
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // __SOCKET_H__
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CC3000HostDriver/wlan.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,1252 @@
+/*****************************************************************************
+*
+* 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
+//! @{
+//
+//*****************************************************************************
+#include <string.h>
+#include "wlan.h"
+#include "hci.h"
+#include "spi.h"
+#include "socket.h"
+#include "nvmem.h"
+#include "security.h"
+#include "evnt_handler.h"
+
+
+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)
+
+#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
+unsigned char key[AES128_KEY_SIZE];
+unsigned char 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
+//
+//*****************************************************************************
+static void SimpleLink_Init_Start(unsigned short usPatchesAvailableAtHost)
+{
+ unsigned char *ptr;
+ unsigned char *args;
+
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (unsigned char *)(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);
+}
+
+
+
+//*****************************************************************************
+//
+//! 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)
+{
+
+ 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;
+}
+
+//*****************************************************************************
+//
+//! 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
+//
+//*****************************************************************************
+void SpiReceiveHandler(void *pvBuffer)
+{
+ tSLInformation.usEventOrDataReceived = 1;
+ tSLInformation.pucReceivedData = (unsigned char *)pvBuffer;
+
+ hci_unsolicited_event_handler();
+}
+
+
+//*****************************************************************************
+//
+//! 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(unsigned short 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 = (unsigned char *)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);
+}
+
+
+//*****************************************************************************
+//
+//! wlan_stop
+//!
+//! @param none
+//!
+//! @return none
+//!
+//! @brief Stop WLAN device by putting it into reset state.
+//!
+//! @sa wlan_start
+//
+//*****************************************************************************
+
+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();
+}
+
+
+//*****************************************************************************
+//
+//! 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,
+ unsigned char *bssid, unsigned char *key, long key_len)
+{
+ long ret;
+ unsigned char *ptr;
+ unsigned char *args;
+ unsigned char 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 ret;
+ unsigned char *ptr;
+ unsigned char *args;
+ unsigned char 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()
+{
+ long ret;
+ unsigned char *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)
+{
+ long ret;
+ unsigned char *ptr;
+ unsigned char *args;
+
+ ret = EFAIL;
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (unsigned char *)(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
+//
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+long
+wlan_add_profile(unsigned long ulSecType,
+ unsigned char* ucSsid,
+ unsigned long ulSsidLen,
+ unsigned char *ucBssid,
+ unsigned long ulPriority,
+ unsigned long ulPairwiseCipher_Or_TxKeyLen,
+ unsigned long ulGroupCipher_TxKeyIndex,
+ unsigned long ulKeyMgmt,
+ unsigned char* ucPf_OrKey,
+ unsigned long ulPassPhraseLen)
+{
+ unsigned short arg_len;
+ long ret;
+ unsigned char *ptr;
+ long i = 0;
+ unsigned char *args;
+ unsigned char 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++)
+ {
+ unsigned char *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,
+ unsigned char* ucSsid,
+ unsigned long ulSsidLen,
+ unsigned char *ucBssid,
+ unsigned long ulPriority,
+ unsigned long ulPairwiseCipher_Or_TxKeyLen,
+ unsigned long ulGroupCipher_TxKeyIndex,
+ unsigned long ulKeyMgmt,
+ unsigned char* ucPf_OrKey,
+ unsigned long ulPassPhraseLen)
+{
+ 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)
+{
+ long ret;
+ unsigned char *ptr;
+ unsigned char *args;
+
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (unsigned char *)(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
+//
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+long
+wlan_ioctl_get_scan_results(unsigned long ulScanTimeout,
+ unsigned char *ucResults)
+{
+ unsigned char *ptr;
+ unsigned char *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
+//
+//*****************************************************************************
+
+#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)
+{
+ unsigned long uiRes;
+ unsigned char *ptr;
+ unsigned char *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)
+{
+ long ret;
+ unsigned char *ptr;
+ unsigned char *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 = (unsigned char *)(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
+//
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+long
+wlan_ioctl_statusget(void)
+{
+ long ret;
+ unsigned char *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)
+{
+ long ret;
+ unsigned char *ptr;
+ unsigned char *args;
+
+ ret = EFAIL;
+ ptr = tSLInformation.pucTxCommandBuffer;
+ args = (unsigned char *)(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)
+{
+ long ret;
+ unsigned char *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)
+{
+ long ret;
+ unsigned char *ptr;
+ unsigned char *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);
+}
+
+//*****************************************************************************
+//
+//! 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.
+//
+//*****************************************************************************
+
+
+#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
+long
+wlan_smart_config_process()
+{
+ signed long returnValue;
+ unsigned long ssidLen, keyLen;
+ unsigned char *decKeyPtr;
+ unsigned char *ssidPtr;
+
+ // read the key from EEPROM - fileID 12
+ returnValue = aes_read_key(key);
+
+ 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, key);
+ if (profileArray[profileArray[0] + 1] > 16)
+ aes_decrypt((unsigned char *)(decKeyPtr + 16), key);
+
+ if (*(unsigned char *)(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.
+//! @}
+//
+//*****************************************************************************
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CC3000HostDriver/wlan.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,518 @@
+/*****************************************************************************
+*
+* wlan.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 __WLAN_H__
+#define __WLAN_H__
+
+#include "cc3000_common.h"
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WLAN_SEC_UNSEC (0)
+#define WLAN_SEC_WEP (1)
+#define WLAN_SEC_WPA (2)
+#define WLAN_SEC_WPA2 (3)
+//*****************************************************************************
+//
+//! \addtogroup wlan_api
+//! @{
+//
+//*****************************************************************************
+
+
+//*****************************************************************************
+//
+//! 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
+//
+//*****************************************************************************
+extern void wlan_init( tWlanCB sWlanCB,
+ tFWPatches sFWPatches,
+ tDriverPatches sDriverPatches,
+ tBootLoaderPatches sBootLoaderPatches,
+ tWlanReadInteruptPin sReadWlanInterruptPin,
+ tWlanInterruptEnable sWlanInterruptEnable,
+ tWlanInterruptDisable sWlanInterruptDisable,
+ tWriteWlanPin sWriteWlanPin);
+
+
+
+//*****************************************************************************
+//
+//! 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
+//!
+//
+//*****************************************************************************
+extern void wlan_start(unsigned short usPatchesAvailableAtHost);
+
+//*****************************************************************************
+//
+//! wlan_stop
+//!
+//! @param none
+//!
+//! @return none
+//!
+//! @brief Stop WLAN device by putting it into reset state.
+//!
+//! @sa wlan_start
+//
+//*****************************************************************************
+extern void wlan_stop(void);
+
+//*****************************************************************************
+//
+//! 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
+extern long wlan_connect(unsigned long ulSecType, char *ssid, long ssid_len,
+ unsigned char *bssid, unsigned char *key, long key_len);
+#else
+extern long wlan_connect(char *ssid, long ssid_len);
+
+#endif
+
+//*****************************************************************************
+//
+//! wlan_disconnect
+//!
+//! @return 0 disconnected done, other CC3000 already disconnected
+//!
+//! @brief Disconnect connection from AP.
+//!
+//! @sa wlan_connect
+//
+//*****************************************************************************
+
+extern long wlan_disconnect(void);
+
+//*****************************************************************************
+//
+//! 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
+//
+//*****************************************************************************
+
+extern long wlan_add_profile(unsigned long ulSecType, unsigned char* ucSsid,
+ unsigned long ulSsidLen,
+ unsigned char *ucBssid,
+ unsigned long ulPriority,
+ unsigned long ulPairwiseCipher_Or_Key,
+ unsigned long ulGroupCipher_TxKeyLen,
+ unsigned long ulKeyMgmt,
+ unsigned char* ucPf_OrKey,
+ unsigned long ulPassPhraseLen);
+
+
+
+//*****************************************************************************
+//
+//! 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
+//
+//*****************************************************************************
+extern long wlan_ioctl_del_profile(unsigned long ulIndex);
+
+//*****************************************************************************
+//
+//! 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.
+//
+//*****************************************************************************
+extern long wlan_set_event_mask(unsigned long ulMask);
+
+//*****************************************************************************
+//
+//! 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
+//
+//*****************************************************************************
+extern long wlan_ioctl_statusget(void);
+
+
+//*****************************************************************************
+//
+//! 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
+//
+//*****************************************************************************
+extern long wlan_ioctl_set_connection_policy(
+ unsigned long should_connect_to_open_ap,
+ unsigned long should_use_fast_connect,
+ unsigned long ulUseProfiles);
+
+//*****************************************************************************
+//
+//! wlan_ioctl_get_scan_results
+//!
+//! @param[in] scan_timeout parameter not supported
+//! @param[out] ucResults scan result (_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
+//
+//*****************************************************************************
+
+
+extern long wlan_ioctl_get_scan_results(unsigned long ulScanTimeout,
+ unsigned char *ucResults);
+
+//*****************************************************************************
+//
+//! 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 milliseconds. 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
+//
+//*****************************************************************************
+extern 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);
+
+
+//*****************************************************************************
+//
+//! 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
+//
+//*****************************************************************************
+extern long wlan_smart_config_start(unsigned long algoEncryptedFlag);
+
+
+//*****************************************************************************
+//
+//! 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
+//
+//*****************************************************************************
+extern long wlan_smart_config_stop(void);
+
+//*****************************************************************************
+//
+//! 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
+//
+//*****************************************************************************
+extern long wlan_smart_config_set_prefix(char* cNewPrefix);
+
+//*****************************************************************************
+//
+//! 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.
+//
+//*****************************************************************************
+extern long wlan_smart_config_process(void);
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // __WLAN_H__
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CC3000Spi/DigitalClass.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,19 @@
+
+#include "mbed.h"
+#include "DigitalClass.h"
+
+
+DigitalClass::DigitalClass(PinName Pin_IRQ, PinName Pin_EN) : WLAN_IRQ(Pin_IRQ), WLAN_EN(Pin_EN)
+{
+WLAN_EN = 0;
+
+// This delay is needed. I guess the CC3000 needs time to do some house keeping
+// as the pin is at ~+2 volts before going low then high.
+
+wait_ms(10);
+
+
+//WLAN_IRQ(p9) p0.0 interrupt pin CC3000 j5 pin 8
+//WLAN_EN(p10) power enable CC3000 j4 pin 8
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CC3000Spi/DigitalClass.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,27 @@
+
+#ifndef DigitalClass_H
+#define DigitalClass_H
+
+
+class DigitalClass
+{
+
+public:
+
+/**
+ * Constructor.
+ *
+ * @param pin_IRQ CC3000 irq pin.
+ * @param pin pin_EN power enable for CC3000.
+ */
+
+DigitalClass(PinName Pin_IRQ, PinName Pin_EN);
+
+
+DigitalOut WLAN_EN;
+DigitalIn WLAN_IRQ;
+
+
+};
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CC3000Spi/spi.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,845 @@
+
+/*****************************************************************************
+*
+* spi.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 link_buff_api
+//! @{
+//
+//*****************************************************************************
+#include "mbed.h"
+#include "hci.h"
+#include "spi.h"
+#include "evnt_handler.h"
+#include "Board.h"
+//#include <msp430.h>
+#include "DigitalClass.h"
+
+SPI spi(p5, p6, p7); // mosi, miso, sclk
+DigitalOut cs(p8); // chip select
+
+DigitalClass Dio(p9, p10);
+
+InterruptIn irq(p9);
+
+
+#define READ 3
+#define WRITE 1
+
+#define HI(value) (((value) & 0xFF00) >> 8)
+#define LO(value) ((value) & 0x00FF)
+
+#define ASSERT_CS() (cs = 0)//(RF_CS_OUT &= ~RF_CS)
+
+#define DEASSERT_CS() (cs = 1)//(RF_CS_OUT |= RF_CS)
+
+#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)
+
+int a = 0;
+
+typedef struct
+{
+ gcSpiHandleRx SPIRxHandler;
+ unsigned short usTxPacketLength;
+ unsigned short usRxPacketLength;
+ unsigned long ulSpiState;
+ unsigned char *pTxPacket;
+ unsigned char *pRxPacket;
+
+}tSpiInformation;
+
+
+tSpiInformation sSpiInformation;
+
+
+// buffer for 5 bytes of SPI HEADER
+unsigned char tSpiReadHeader[] = {READ, 0, 0, 0, 0};
+
+
+void SpiWriteDataSynchronous(unsigned char *data, unsigned short size);
+void SpiWriteAsync(const unsigned char *data, unsigned short size);
+void SpiPauseSpi(void);
+void SpiResumeSpi(void);
+void SSIContReadOperation(void);
+
+// 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 occurred and either receive function or send
+// function will stuck forever.
+#define CC3000_BUFFER_MAGIC_NUMBER (0xDE)
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////
+//__no_init is used to prevent the buffer initialization in order to prevent hardware WDT expiration ///
+// before entering to 'main()'. ///
+//for every IDE, different syntax exists : 1. __CCS__ for CCS v5 ///
+// 2. __IAR_SYSTEMS_ICC__ for IAR Embedded Workbench ///
+// *CCS does not initialize variables - therefore, __no_init is not needed. ///
+///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//#ifdef __CCS__
+char spi_buffer[CC3000_RX_BUFFER_SIZE];
+
+//#elif __IAR_SYSTEMS_ICC__
+//__no_init char spi_buffer[CC3000_RX_BUFFER_SIZE];
+//#endif
+
+//#ifdef __CCS__
+unsigned char wlan_tx_buffer[CC3000_TX_BUFFER_SIZE];
+
+//#elif __IAR_SYSTEMS_ICC__
+//__no_init unsigned char wlan_tx_buffer[CC3000_TX_BUFFER_SIZE];
+//#endif
+
+//*****************************************************************************
+//
+//! SpiCleanGPIOISR
+//!
+//! \param none
+//!
+//! \return none
+//!
+//! \brief This function get the reason for the GPIO interrupt and clear
+//! corresponding interrupt flag
+//
+//*****************************************************************************
+void
+SpiCleanGPIOISR(void)
+{
+ WlanInterruptDisable();
+ //SPI_IFG_PORT &= ~SPI_IRQ_PIN;
+}
+
+//*****************************************************************************
+//
+//! SpiClose
+//!
+//! @param none
+//!
+//! @return none
+//!
+//! @brief Close Spi interface
+//
+//*****************************************************************************
+void
+SpiClose(void)
+{
+ if (sSpiInformation.pRxPacket)
+ {
+ sSpiInformation.pRxPacket = 0;
+ }
+
+ // Disable Interrupt
+ tSLInformation.WlanInterruptDisable();
+}
+
+
+//*****************************************************************************
+//
+//! SpiOpen
+//!
+//! @param none
+//!
+//! @return none
+//!
+//! @brief Open Spi interface
+//
+//*****************************************************************************
+void
+SpiOpen(gcSpiHandleRx pfRxHandler)
+{
+ sSpiInformation.ulSpiState = eSPI_STATE_POWERUP;
+ sSpiInformation.SPIRxHandler = pfRxHandler;
+ sSpiInformation.usTxPacketLength = 0;
+ sSpiInformation.pTxPacket = NULL;
+ sSpiInformation.pRxPacket = (unsigned char *)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;
+
+ // Enable interrupt on WLAN IRQ pin
+ tSLInformation.WlanInterruptEnable();
+}
+
+//*****************************************************************************
+//
+//! init_spi
+//!
+//! @param none
+//!
+//! @return none
+//!
+//! @brief initializes an SPI interface
+//
+//*****************************************************************************
+
+int init_spi(void)
+{
+ spi.frequency(12000000);
+ spi.format(8, 1);
+ cs = 1;
+
+ //UCB0CTL1 |= UCSWRST; // Put state machine in reset
+ //UCB0CTL0 = UCMSB + UCMST + UCMODE_0 + UCSYNC; // 3-pin, 8-bit SPI master
+
+ //UCB0CTL1 = UCSWRST + UCSSEL_2; // Use SMCLK, keep RESET
+
+ // Set SPI clock
+ //UCB0CTL1 |= UCSWRST; // Put state machine in reset
+ //UCB0BR0 = 2; // f_UCxCLK = 25MHz/2 = 12.5MHz
+ //UCB0BR1 = 0;
+ //UCB0CTL1 &= ~UCSWRST;
+
+ return(ESUCCESS);
+}
+
+//*****************************************************************************
+//
+//! SpiFirstWrite
+//!
+//! @param ucBuf buffer to write
+//! @param usLength buffer's length
+//!
+//! @return none
+//!
+//! @brief enter point for first write flow
+//
+//*****************************************************************************
+long
+SpiFirstWrite(unsigned char *ucBuf, unsigned short usLength)
+{
+ // workaround for first transaction
+ ASSERT_CS();
+
+ // Assuming we are running on 24 MHz ~50 micro delay is 1200 cycles;
+ //__delay_cycles(1200);
+ wait_us(50);
+ // SPI writes first 4 bytes of data
+ SpiWriteDataSynchronous(ucBuf, 4);
+ wait_us(50);
+ //__delay_cycles(1200);
+
+ SpiWriteDataSynchronous(ucBuf + 4, usLength - 4);
+
+ // From this point on - operate in a regular way
+ sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
+
+ DEASSERT_CS();
+
+ return(0);
+}
+
+
+//*****************************************************************************
+//
+//! SpiWrite
+//!
+//! @param pUserBuffer buffer to write
+//! @param usLength buffer's length
+//!
+//! @return none
+//!
+//! @brief Spi write operation
+//
+//*****************************************************************************
+long
+SpiWrite(unsigned char *pUserBuffer, unsigned short usLength)
+{
+ unsigned char ucPad = 0;
+
+ // Figure out the total length of the packet in order to figure out if there
+ // is padding or not
+ if(!(usLength & 0x0001))
+ {
+ 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 detection of the overrun. If the
+ // magic number is overwritten - buffer overrun occurred - and we will 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)
+ ;
+ }
+
+ 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);
+ //printf("first TX/RX transaction....\r\n");
+ }
+ else
+ {
+ // We need to prevent here race that can occur in case 2 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
+ ASSERT_CS();
+
+ // Re-enable IRQ - if it was not disabled - this is not a problem...
+ tSLInformation.WlanInterruptEnable();
+ //DEASSERT_CS();
+
+
+ // check for a missing interrupt between the CS assertion and enabling back the interrupts
+ if (tSLInformation.ReadWlanInterruptPin() == 0)
+ {
+ //printf("Deal with missing interrupt....\r\n");
+ SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength);
+
+ sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
+
+ DEASSERT_CS();
+ }
+
+ }
+
+ // 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);
+}
+
+
+//*****************************************************************************
+//
+//! SpiWriteDataSynchronous
+//!
+//! @param data buffer to write
+//! @param size buffer's size
+//!
+//! @return none
+//!
+//! @brief Spi write operation
+//
+//*****************************************************************************
+void
+SpiWriteDataSynchronous(unsigned char *data, unsigned short size)
+{
+ //printf("SPI Write\r\n");
+ while (size)
+ {
+ spi.write(*data);
+
+ size --;
+ //if(*data > 31 && *data < 127){
+ //printf(" %c",*data);
+ //}else{
+ //printf(" %x",*data);
+ //}
+
+ data++;
+ }
+ //printf("\r\n");
+}
+
+//*****************************************************************************
+//
+//! SpiReadDataSynchronous
+//!
+//! @param data buffer to read
+//! @param size buffer's size
+//!
+//! @return none
+//!
+//! @brief Spi read operation
+//
+//*****************************************************************************
+void
+SpiReadDataSynchronous(unsigned char *data, unsigned short size)
+{
+ unsigned char *data_to_send = tSpiReadHeader;
+ //printf("SPI Read\r\n");
+ for (int i = 0; i < size; i ++)
+ {
+ data[i] = spi.write(data_to_send[0]);
+
+ //if(data[i] > 31 && data[i] < 127){
+ //printf(" %c",data[i]);
+ //}else{
+ //printf(" %x",data[i]);
+ //}
+
+ }
+ //printf("\r\n");
+}
+
+
+//*****************************************************************************
+//
+//! SpiReadHeader
+//!
+//! \param buffer
+//!
+//! \return none
+//!
+//! \brief This function enter point for read flow: first we read minimal 5
+//! SPI header bytes and 5 Event Data bytes
+//
+//*****************************************************************************
+void
+SpiReadHeader(void)
+{
+ SpiReadDataSynchronous(sSpiInformation.pRxPacket, 10);
+}
+
+
+//*****************************************************************************
+//
+//! SpiReadDataCont
+//!
+//! @param None
+//!
+//! @return None
+//!
+//! @brief This function processes received SPI Header and in accordance with
+//! it - continues reading the packet
+//
+//*****************************************************************************
+long
+SpiReadDataCont(void)
+{
+ long data_to_recv;
+ unsigned char *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);
+}
+
+
+//*****************************************************************************
+//
+//! SpiPauseSpi
+//!
+//! @param none
+//!
+//! @return none
+//!
+//! @brief Spi pause operation
+//
+//*****************************************************************************
+
+void
+SpiPauseSpi(void)
+{
+ WlanInterruptDisable();
+ //SPI_IRQ_IE &= ~SPI_IRQ_PIN;
+}
+
+
+//*****************************************************************************
+//
+//! SpiResumeSpi
+//!
+//! @param none
+//!
+//! @return none
+//!
+//! @brief Spi resume operation
+//
+//*****************************************************************************
+
+void
+SpiResumeSpi(void)
+{
+ WlanInterruptEnable();
+ //SPI_IRQ_IE |= SPI_IRQ_PIN;
+}
+
+
+//*****************************************************************************
+//
+//! SpiTriggerRxProcessing
+//!
+//! @param none
+//!
+//! @return none
+//!
+//! @brief Spi RX processing
+//
+//*****************************************************************************
+void
+SpiTriggerRxProcessing(void)
+{
+
+ // Trigger Rx processing
+ SpiPauseSpi();
+ DEASSERT_CS();
+
+ // 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 overwritten - buffer overrun occurred - and we will stuck
+ // here forever!
+ if (sSpiInformation.pRxPacket[CC3000_RX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER)
+ {
+ while (1)
+ ;
+ }
+
+ sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
+ sSpiInformation.SPIRxHandler(sSpiInformation.pRxPacket + SPI_HEADER_SIZE);
+}
+
+//*****************************************************************************
+//
+//! IntSpiGPIOHandler
+//!
+//! @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 registered this interrupt request
+//! it set the corresponding /CS in active state.
+//
+//*****************************************************************************
+//#pragma vector=PORT2_VECTOR
+//__interrupt
+void IntSpiGPIOHandler(void)
+{
+ //switch(__even_in_range(P2IV, P2IV_P2IFG7))
+ //{
+ //case P2IV_P2IFG4:
+ 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 - we are start reception */
+ ASSERT_CS();
+
+ // Wait for TX/RX Compete 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;
+
+ DEASSERT_CS();
+ }
+ // break;
+ //default:
+ // break;
+ //}
+
+}
+
+//*****************************************************************************
+//
+//! SSIContReadOperation
+//!
+//! @param none
+//!
+//! @return none
+//!
+//! @brief SPI read operation
+//
+//*****************************************************************************
+
+void
+SSIContReadOperation(void)
+{
+ // The header was read - continue with the payload read
+ if (!SpiReadDataCont())
+ {
+ // All the data was read - finalize handling by switching to the task
+ // and calling from task Event Handler
+ SpiTriggerRxProcessing();
+ }
+}
+
+
+//*****************************************************************************
+//
+//! TXBufferIsEmpty
+//!
+//! @param
+//!
+//! @return returns 1 if buffer is empty, 0 otherwise
+//!
+//! @brief Indication if TX SPI buffer is empty
+//
+//*****************************************************************************
+
+long TXBufferIsEmpty(void)
+{
+ return 1;//(UCB0IFG&UCTXIFG);
+}
+
+//*****************************************************************************
+//
+//! RXBufferIsEmpty
+//!
+//! @param none
+//!
+//! @return returns 1 if buffer is empty, 0 otherwise
+//!
+//! @brief Indication if RX SPI buffer is empty
+//
+//*****************************************************************************
+
+long RXBufferIsEmpty(void)
+{
+ return 1;//(UCB0IFG&UCRXIFG);
+}
+
+//*****************************************************************************
+//
+//! ReadWlanInterruptPin
+//!
+//! @param none
+//!
+//! @return none
+//!
+//! @brief return wlan interrup pin
+//
+//*****************************************************************************
+
+int ReadWlanInterruptPin(void)
+{
+
+ int8_t val;
+ //printf("WLAN_IRQ %i \r\n",Dio.WLAN_IRQ.read());
+ val = Dio.WLAN_IRQ.read();
+ return (int)val;
+
+}
+
+//*****************************************************************************
+//
+//! WlanInterruptEnable
+//!
+//! @param none
+//!
+//! @return none
+//!
+//! @brief Enable wlan IRQ pin
+//
+//*****************************************************************************
+
+void WlanInterruptEnable()
+{
+ //int8_t val;
+ //int a;
+ //printf("IRQ Enabled....\r\n");
+ //irq.fall(&IntSpiGPIOHandler);
+ //wait_ms(1);
+ //val = ReadWlanInterruptPin();
+
+ // Taken from SpiWrite above, it appears to work better here????
+ // First deal with missing interrupt if any. Bypass first run,
+ // refer to Wlan_start() (wlan.cpp) toggling IRQ.
+/*
+ if (a < 1){
+ a++;
+ }
+ else
+ {
+
+ if (tSLInformation.ReadWlanInterruptPin() == 0)
+ {
+
+ ASSERT_CS();
+ //printf("Deal with missing interrupt....\r\n");
+
+ SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength);
+
+ sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
+
+ DEASSERT_CS();
+ }
+ a=1;
+ }
+*/
+ irq.fall(&IntSpiGPIOHandler);
+ //SPI_IRQ_IES |= SPI_IRQ_PIN;
+ //SPI_IRQ_IE |= SPI_IRQ_PIN;
+}
+
+//*****************************************************************************
+//
+//! WlanInterruptDisable
+//!
+//! @param none
+//!
+//! @return none
+//!
+//! @brief Disable waln IrQ pin
+//
+//*****************************************************************************
+
+void WlanInterruptDisable()
+{
+
+ irq.fall(NULL);
+
+}
+
+//*****************************************************************************
+//
+//! WriteWlanPin
+//!
+//! @param val value to write to wlan pin
+//!
+//! @return none
+//!
+//! @brief write value to wlan pin
+//
+//*****************************************************************************
+
+void WriteWlanPin(unsigned char val)
+{
+
+ if (val) {
+ Dio.WLAN_EN = 1;
+ //printf("WLAN_EN %i \r\n",val);
+ }
+ else {
+ Dio.WLAN_EN = 0;
+ //printf("WLAN_EN %i \r\n",val);
+ }
+
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CC3000Spi/spi.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,101 @@
+/*****************************************************************************
+*
+* spi.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_H__
+#define __SPI_H__
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*gcSpiHandleRx)(void *p);
+typedef void (*gcSpiHandleTx)(void);
+
+extern unsigned char wlan_tx_buffer[];
+
+//*****************************************************************************
+//
+// Prototypes for the APIs.
+//
+//*****************************************************************************
+extern void SpiOpen(gcSpiHandleRx pfRxHandler);
+extern void SpiClose(void);
+extern long SpiWrite(unsigned char *pUserBuffer, unsigned short usLength);
+extern void SpiResumeSpi(void);
+//extern void SpiConfigureHwMapping( unsigned long ulPioPortAddress,
+// unsigned long ulPort,
+// unsigned long ulSpiCs,
+// unsigned long ulPortInt,
+// unsigned long uluDmaPort,
+// unsigned long ulSsiPortAddress,
+// unsigned long ulSsiTx,
+// unsigned long ulSsiRx,
+// unsigned long ulSsiClck);
+extern void SpiCleanGPIOISR(void);
+extern int init_spi(void);
+extern void ReadWriteFrame(unsigned char *pTxBuffer, unsigned char *pRxBuffer, unsigned short size);
+extern long TXBufferIsEmpty(void);
+extern long RXBufferIsEmpty(void);
+
+extern void WlanInterruptDisable(void);
+extern void WlanInterruptEnable(void);
+extern int ReadWlanInterruptPin(void);
+extern void WriteWlanPin( unsigned char val );
+extern void IntSpiGPIOHandler(void);
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CC3000Spi/spi_version.h Sat Sep 14 17:38:41 2013 +0000 @@ -0,0 +1,54 @@ +/***************************************************************************** +* +* 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__ + + + + + + + + + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/HyperTerminal/dispatcher.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,173 @@
+/*****************************************************************************
+*
+* dispatcher.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 dispatcher_api
+//! @{
+//
+//*****************************************************************************
+
+#include "dispatcher.h"
+
+#include "mbed.h"
+//#include <msp430.h>
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////
+//__no_init is used to prevent varible's initialize. ///
+//for every IDE, exist different syntax: 1. __CCS__ for CCS v5 ///
+// 2. __IAR_SYSTEMS_ICC__ for IAR Embedded Workbench ///
+// *CCS does not initialize variables - therefore, __no_init is not needed. ///
+///////////////////////////////////////////////////////////////////////////////////////////////////////////
+//#ifdef __CCS__
+
+Serial usb(USBTX, USBRX);
+//com.baud(115200);
+unsigned char g_ucUARTBuffer[UART_IF_BUFFER];
+unsigned char g_ucLength;
+
+//#elif __IAR_SYSTEMS_ICC__
+
+//__no_init unsigned char g_ucUARTBuffer[UART_IF_BUFFER];
+//__no_init unsigned char g_ucLength;
+
+//#endif
+
+int uart_have_cmd = 0;
+
+//*****************************************************************************
+//
+//! UARTIntHandler
+//!
+//! \param buffer
+//!
+//! \return none
+//!
+//! \brief Handles RX and TX interrupts
+//
+//*****************************************************************************
+//#pragma vector=USCI_A1_VECTOR
+//__interrupt void UART_ISR(void)
+/*
+void UART_ISR(void)
+{
+
+ if(UCA1IFG & UCRXIFG)
+ {
+ g_ucUARTBuffer[g_ucLength] = UCA1RXBUF;
+ if( g_ucUARTBuffer[g_ucLength] == 0x0D )
+ {
+ g_ucLength = 0;
+ uart_have_cmd = 1;
+ }
+ else
+ {
+ g_ucLength++;
+ }
+ }
+}
+*/
+
+//*****************************************************************************
+//
+//! DispatcherUartSendPacket
+//!
+//! \param inBuff pointer to the UART input buffer
+//! \param usLength buffer length
+//!
+//! \return none
+//!
+//! \brief The function sends to UART a buffer of given length
+//
+//*****************************************************************************
+void DispatcherUartSendPacket(const char *inBuff, unsigned short usLength)
+{
+ //com.baud(115200);
+ //usb.printf("Sending packets.....");
+ while (usLength)
+ {
+ //while (usLength)) ;
+ usb.putc(*inBuff);
+ //UCA1TXBUF = *inBuff;
+ usLength--;
+ inBuff++;
+
+ }
+}
+
+
+//*****************************************************************************
+//
+//! Cofigure the UART
+//!
+//! @param none
+//!
+//! @return none
+//!
+//! @brief Cofigure the UART
+//
+//*****************************************************************************
+
+void
+DispatcherUARTConfigure(void)
+{
+
+ usb.baud(460800);
+
+ //P4SEL = BIT5 + BIT4; // P4.4,5 = USCI_A1 TXD/RXD
+
+ //UCA1CTL1 |= UCSWRST; // **Put state machine in reset**
+ //UCA1CTL0 = 0x00;
+ //UCA1CTL1 = UCSSEL__SMCLK + UCSWRST; // Use SMCLK, keep RESET
+ //UCA1BR0 = 0x2C; // 25MHz/115200= 217.01 =0xD9 (see User's Guide)
+ //UCA1BR1 = 0x0A; // 25MHz/9600= 2604 =0xA2C (see User's Guide)
+
+ //UCA1MCTL = UCBRS_3 + UCBRF_0; // Modulation UCBRSx=3, UCBRFx=0
+ //UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
+
+ /* Enable RX Interrupt on UART */
+ //UCA1IFG &= ~ (UCRXIFG | UCRXIFG);
+ //UCA1IE |= UCRXIE;
+ g_ucLength = 0;
+}
+
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/HyperTerminal/dispatcher.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,67 @@
+/*****************************************************************************
+*
+* dispatcher.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 __DISPATCHER_H__
+#define __DISPATCHER_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C" {
+#endif
+// Define the size of UART IF buffer for RX
+
+#define UART_IF_BUFFER 64
+// Define the UART IF buffer
+extern unsigned char g_ucUARTBuffer[];
+
+extern void DispatcherUARTConfigure(void);
+extern void DispatcherUartSendPacket(const char *inBuff, unsigned short usLength);
+
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // __DISPATCHER_H__
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MD5/md5.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,297 @@
+/*
+ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
+ * MD5 Message-Digest Algorithm (RFC 1321).
+ *
+ * Homepage:
+ * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
+ *
+ * Author:
+ * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
+ *
+ * This software was written by Alexander Peslyak in 2001. No copyright is
+ * claimed, and the software is hereby placed in the public domain.
+ * In case this attempt to disclaim copyright and place the software in the
+ * public domain is deemed null and void, then the software is
+ * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
+ * general public under the following terms:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
+ *
+ * (This is a heavily cut-down "BSD license".)
+ *
+ * This differs from Colin Plumb's older public domain implementation in that
+ * no exactly 32-bit integer data type is required (any 32-bit or wider
+ * unsigned integer data type will do), there's no compile-time endianness
+ * configuration, and the function prototypes match OpenSSL's. No code from
+ * Colin Plumb's implementation has been reused; this comment merely compares
+ * the properties of the two independent implementations.
+ *
+ * The primary goals of this implementation are portability and ease of use.
+ * It is meant to be fast, but not as fast as possible. Some known
+ * optimizations are not included to reduce source code size and avoid
+ * compile-time configuration.
+ */
+
+#ifndef HAVE_OPENSSL
+
+#include "mbed.h"
+#include <string.h>
+
+#include "md5.h"
+
+/*
+ * The basic MD5 functions.
+ *
+ * F and G are optimized compared to their RFC 1321 definitions for
+ * architectures that lack an AND-NOT instruction, just like in Colin Plumb's
+ * implementation.
+ */
+#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
+#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+
+/*
+ * The MD5 transformation for all four rounds.
+ */
+#define STEP(f, a, b, c, d, x, t, s) \
+ (a) += f((b), (c), (d)) + (x) + (t); \
+ (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
+ (a) += (b);
+
+/*
+ * SET reads 4 input bytes in little-endian byte order and stores them
+ * in a properly aligned word in host byte order.
+ *
+ * The check for little-endian architectures that tolerate unaligned
+ * memory accesses is just an optimization. Nothing will break if it
+ * doesn't work.
+ */
+#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
+#define SET(n) \
+ (*(MD5_u32plus *)&ptr[(n) * 4])
+#define GET(n) \
+ SET(n)
+#else
+#define SET(n) \
+ (ctx->block[(n)] = \
+ (MD5_u32plus)ptr[(n) * 4] | \
+ ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
+ ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
+ ((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
+#define GET(n) \
+ (ctx->block[(n)])
+#endif
+
+/*
+ * This processes one or more 64-byte data blocks, but does NOT update
+ * the bit counters. There are no alignment requirements.
+ */
+static void *body(MD5_CTX *ctx, void *data, unsigned long size)
+{
+ unsigned char *ptr;
+ MD5_u32plus a, b, c, d;
+ MD5_u32plus saved_a, saved_b, saved_c, saved_d;
+
+ ptr = (unsigned char*)data;
+
+ a = ctx->a;
+ b = ctx->b;
+ c = ctx->c;
+ d = ctx->d;
+
+ do {
+ saved_a = a;
+ saved_b = b;
+ saved_c = c;
+ saved_d = d;
+
+/* Round 1 */
+ STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
+ STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
+ STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
+ STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
+ STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
+ STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
+ STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
+ STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
+ STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
+ STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
+ STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
+ STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
+ STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
+ STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
+ STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
+ STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
+
+/* Round 2 */
+ STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
+ STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
+ STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
+ STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
+ STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
+ STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
+ STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
+ STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
+ STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
+ STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
+ STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
+ STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
+ STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
+ STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
+ STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
+ STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
+
+/* Round 3 */
+ STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
+ STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)
+ STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
+ STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)
+ STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
+ STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)
+ STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
+ STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)
+ STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
+ STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)
+ STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
+ STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)
+ STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
+ STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)
+ STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
+ STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)
+
+/* Round 4 */
+ STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
+ STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
+ STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
+ STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
+ STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
+ STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
+ STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
+ STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
+ STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
+ STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
+ STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
+ STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
+ STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
+ STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
+ STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
+ STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
+
+ a += saved_a;
+ b += saved_b;
+ c += saved_c;
+ d += saved_d;
+
+ ptr += 64;
+ } while (size -= 64);
+
+ ctx->a = a;
+ ctx->b = b;
+ ctx->c = c;
+ ctx->d = d;
+
+ return ptr;
+}
+
+void MD5_Init(MD5_CTX *ctx)
+{
+ ctx->a = 0x67452301;
+ ctx->b = 0xefcdab89;
+ ctx->c = 0x98badcfe;
+ ctx->d = 0x10325476;
+
+ ctx->lo = 0;
+ ctx->hi = 0;
+}
+
+void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size)
+{
+ MD5_u32plus saved_lo;
+ unsigned long used, free;
+
+ saved_lo = ctx->lo;
+ if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
+ ctx->hi++;
+ ctx->hi += size >> 29;
+
+ used = saved_lo & 0x3f;
+
+ if (used) {
+ free = 64 - used;
+
+ if (size < free) {
+ memcpy(&ctx->buffer[used], data, size);
+ return;
+ }
+
+ memcpy(&ctx->buffer[used], data, free);
+ data = (unsigned char *)data + free;
+ size -= free;
+ body(ctx, ctx->buffer, 64);
+ }
+
+ if (size >= 64) {
+ data = body(ctx, data, size & ~(unsigned long)0x3f);
+ size &= 0x3f;
+ }
+
+ memcpy(ctx->buffer, data, size);
+}
+
+void MD5_Final(unsigned char *result, MD5_CTX *ctx)
+{
+ unsigned long used, free;
+
+ used = ctx->lo & 0x3f;
+
+ ctx->buffer[used++] = 0x80;
+
+ free = 64 - used;
+
+ if (free < 8) {
+ memset(&ctx->buffer[used], 0, free);
+ body(ctx, ctx->buffer, 64);
+ used = 0;
+ free = 64;
+ }
+
+ memset(&ctx->buffer[used], 0, free - 8);
+
+ ctx->lo <<= 3;
+ ctx->buffer[56] = ctx->lo;
+ ctx->buffer[57] = ctx->lo >> 8;
+ ctx->buffer[58] = ctx->lo >> 16;
+ ctx->buffer[59] = ctx->lo >> 24;
+ ctx->buffer[60] = ctx->hi;
+ ctx->buffer[61] = ctx->hi >> 8;
+ ctx->buffer[62] = ctx->hi >> 16;
+ ctx->buffer[63] = ctx->hi >> 24;
+
+ body(ctx, ctx->buffer, 64);
+
+ result[0] = ctx->a;
+ result[1] = ctx->a >> 8;
+ result[2] = ctx->a >> 16;
+ result[3] = ctx->a >> 24;
+ result[4] = ctx->b;
+ result[5] = ctx->b >> 8;
+ result[6] = ctx->b >> 16;
+ result[7] = ctx->b >> 24;
+ result[8] = ctx->c;
+ result[9] = ctx->c >> 8;
+ result[10] = ctx->c >> 16;
+ result[11] = ctx->c >> 24;
+ result[12] = ctx->d;
+ result[13] = ctx->d >> 8;
+ result[14] = ctx->d >> 16;
+ result[15] = ctx->d >> 24;
+
+ memset(ctx, 0, sizeof(*ctx));
+}
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MD5/md5.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,71 @@
+/*
+ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
+ * MD5 Message-Digest Algorithm (RFC 1321).
+ *
+ * Homepage:
+ * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
+ *
+ * Author:
+ * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
+ *
+ * This software was written by Alexander Peslyak in 2001. No copyright is
+ * claimed, and the software is hereby placed in the public domain.
+ * In case this attempt to disclaim copyright and place the software in the
+ * public domain is deemed null and void, then the software is
+ * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
+ * general public under the following terms:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
+ *
+ * See md5.c for more information.
+ */
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_OPENSSL
+#include <openssl/md5.h>
+#elif !defined(_MD5_H)
+#define _MD5_H
+
+/* Any 32-bit or wider unsigned integer data type will do */
+typedef unsigned long MD5_u32plus;
+
+//#ifdef __CCS__
+//typedef struct __attribute__ ((__packed__))
+//#elif __IAR_SYSTEMS_ICC__
+//#pragma pack(1)
+typedef struct
+//#endif
+{
+ MD5_u32plus lo, hi;
+ MD5_u32plus a, b, c, d;
+ unsigned char buffer[64];
+ MD5_u32plus block[16];
+} MD5_CTX;
+
+extern void MD5_Init(MD5_CTX *ctx);
+extern void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size);
+extern void MD5_Final(unsigned char *result, MD5_CTX *ctx);
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebServer/Common.h Sat Sep 14 17:38:41 2013 +0000 @@ -0,0 +1,74 @@ +/***************************************************************************** +* +* Common.h +* 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 _TINY_WEB_SERVER_COMMON_H_ +#define _TINY_WEB_SERVER_COMMON_H_ + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef short int16; +typedef unsigned long uint32; + +//#define HTTP_WEB_SERVER_ON_BRIDGE + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef __IAR_SYSTEMS_ICC__ +#define __no_init +#endif + +#ifdef WIN32 +typedef int socklen_t; +#endif //WIN32 + +#if !defined(WIN32) || defined(HTTP_WEB_SERVER_ON_BRIDGE) +#define _TIME_T_DEFINED +#define SOCKET long +#define INVALID_SOCKET (-1) +#endif //WIN32 + +#define CC3000_INVALID_SOCKET ((SOCKET)-2) + +#define FALSE 0 +#define TRUE 1 + + +#define ESUCCESS 0 +#define SMART_CONFIG_SET 0xAA + + +#endif //_TINY_WEB_SERVER_COMMON_H_ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/FlashDB.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,251 @@
+/*****************************************************************************
+*
+* FlashDB.c
+* 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.
+*
+*****************************************************************************/
+#include "mbed.h"
+#include "Common.h"
+#include "FlashDB.h"
+#include "HttpString.h"
+#include "string.h"
+
+
+/// This database flag indicates that all resource strings are to be matched with a case-sensitive string comparison function
+#define FLASH_DB_FLAG_CASE_SENSITIVE (1 << 0)
+
+/**
+ * The header structure of the flash database
+ */
+//#ifdef __CCS__
+struct __attribute__ ((__packed__)) FlashDBHeader
+//#elif __IAR_SYSTEMS_ICC__
+//#pragma pack(1)
+//struct FlashDBHeader
+//#endif
+{
+ /// Amount of content type entries
+ uint16 uContentTypeAmount;
+ /// Offset of content-type entry list
+ uint16 uContentTypeOffset;
+ /// Amount of content entries
+ uint16 uContentAmount;
+ /// Offset of content entry list
+ uint16 uContentOffset;
+ /// Database flags. See FLASH_DB_FLAG_*
+ uint16 uFlags;
+};
+
+/**
+ * The header structure for a content entity in the database
+ */
+//#ifdef __CCS__
+struct __attribute__ ((__packed__)) FlashDBContentTypeEntry
+//#elif __IAR_SYSTEMS_ICC__
+//#pragma pack(1)
+//struct FlashDBContentTypeEntry
+//#endif
+{
+ /// Length of the value string. Should be 255 characters at most.
+ uint16 uValueLength;
+ /// Offset of the value string
+ uint16 uValueOffset;
+};
+
+extern const char FlashDBContentData[];
+
+/**
+ * The header structure for a content entity in the database
+ */
+//#ifdef __CCS__
+struct __attribute__ ((__packed__)) FlashDBContentEntry
+//#elif __IAR_SYSTEMS_ICC__
+//#pragma pack(1)
+//struct FlashDBContentEntry
+//#endif
+{
+ /// Length of the resource string. Should be 255 characters at most.
+ uint16 uResourceLength;
+ /// Offset of the resource string
+ //uint32 uResourceOffset;
+ unsigned long uResourceOffset;
+ /// Flags. See FLASHDB_FLAG_*
+ uint16 uFlags;
+ /// Index of content type entry for this resource, in the content type list
+ uint16 uContentType;
+ /// Length (in bytes) of the content blob
+ uint16 uContentLength;
+ /// Offset of the content blob in the database
+ //uint32 uContentOffset;
+ unsigned long uContentOffset;
+};
+
+extern const char FlashDBContentData[];
+
+/**
+ * The layout of the database file is as follows:
+ * Database Header
+ * Content type entry 1
+ * Content type entry 2
+ * and so on...
+ * Content entry 1
+ * Content entry 2
+ * and so on...
+ * Content type string 1
+ * Content type string 2
+ * and so on...
+ * Content blob 1
+ * Content blob 2
+ * and so on...
+ *
+ * Note: All offsets in the structures are absolute offsets, meaning they are relative to the database base pointer, as passed to FlashDB_Init()
+ */
+
+/* this global shows a sample how static pages/files are stored in the memory */
+
+#if 0
+struct StaticExamplePages
+{
+ struct FlashDBHeader header;
+ struct FlashDBContentTypeEntry contentTypeList[];
+ struct FlashDBContentEntry ContentList[];
+ char contentType[][];
+ char resource[][];
+ char content[][];
+};
+#endif
+
+struct FlashDBHeader *gFlashDB;
+
+/**
+ * Initialize the flash database module
+ * @param pDatabase Pointer to the beginning of the database in flash memory
+ */
+void FlashDB_Init()
+{
+ gFlashDB = (struct FlashDBHeader *)FlashDBContentData;
+}
+
+/**
+ * Find a content-type in the database
+ * @param index The index of the content type in the database
+ * @param[out] pResult Returns the string and its length
+ * @return nonzero if successful. zero if index out of range.
+ */
+int FlashDB_FindContentType(uint16 index, struct HttpBlob* pResult)
+{
+ struct FlashDBContentTypeEntry *pContentTypeEntryList;
+
+ if (index > gFlashDB->uContentTypeAmount)
+ return 0;
+
+ pContentTypeEntryList = (struct FlashDBContentTypeEntry *)((unsigned char*)gFlashDB + gFlashDB->uContentTypeOffset);
+ pContentTypeEntryList = (struct FlashDBContentTypeEntry *)(pContentTypeEntryList + index);
+ pResult->uLength = pContentTypeEntryList->uValueLength;
+ pResult->pData = (unsigned char*)((unsigned char*)gFlashDB + pContentTypeEntryList->uValueOffset);
+
+ return 1;
+}
+
+/**
+ * Lookup content in the database, given a resource identifier
+ * @param pResource The resource as given in the HTTP request
+ * @param[out] pResult Returns the content and its metadata
+ * @return nonzero if successful. zero if such a resource was not found.
+ */
+int FlashDB_FindContent(struct HttpBlob pResource, struct FlashDBContent* pResult)
+{
+ /* it is assumed that the resource list is sorted */
+ struct FlashDBContentEntry *pContentFieldStart;
+ struct FlashDBContentEntry *pContentFieldMoving;
+ struct HttpBlob MainPage;
+ uint16 uLowSearchIndex = 0;
+ uint16 uMidSearchIndex;
+ uint16 uHighSearchIndex;
+ int uComparison;
+ int16 found = -1; /* not found */
+ struct HttpBlob ResourceBlob;
+
+ uHighSearchIndex = gFlashDB->uContentAmount - 1;
+ pContentFieldStart = (struct FlashDBContentEntry *)((unsigned char*)gFlashDB + gFlashDB->uContentOffset);
+
+ while (uLowSearchIndex <= uHighSearchIndex)
+ {
+ uMidSearchIndex = (uLowSearchIndex + uHighSearchIndex)/2;
+ pContentFieldMoving = pContentFieldStart + uMidSearchIndex;
+ ResourceBlob.pData = (unsigned char*)((unsigned char*)gFlashDB + pContentFieldMoving->uResourceOffset);
+ ResourceBlob.uLength = pContentFieldMoving->uResourceLength;
+
+ if(pResource.uLength ==1 && *(pResource.pData)=='/')
+ {
+ MainPage.uLength = 11;
+ MainPage.pData = (unsigned char*)"/index.html";
+ uComparison = HttpString_strcmp(MainPage, ResourceBlob);
+ }
+ else
+ uComparison = HttpString_strcmp(pResource, ResourceBlob);
+ // found the exact blob
+ if (uComparison == 0)
+ {
+ found = 1;
+ printf("Content found \r\n");
+ break;
+ }
+
+ // the requested blob is "larger" than the current blob
+ else if (uComparison > 0)
+ {
+ uLowSearchIndex = uMidSearchIndex + 1;
+
+ }
+ // the requested blob is "smaller" than the current blob
+ else
+ {
+ uHighSearchIndex = uMidSearchIndex - 1;
+
+ }
+ }
+
+ if (found == -1)
+ {
+ printf("Content not found \r\n");
+ return 0;
+ }
+ else
+ {
+ pResult->uContentType = pContentFieldMoving->uContentType;
+ pResult->uFlags = pContentFieldMoving->uFlags;
+ pResult->contentBlob.uLength = pContentFieldMoving->uContentLength;
+ pResult->contentBlob.pData = (unsigned char*)((unsigned char*)gFlashDB + pContentFieldMoving->uContentOffset);
+ return 1;
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/FlashDB.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,105 @@
+/*****************************************************************************
+*
+* FlashDB.h
+* 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 _FLASH_DB_H_
+#define _FLASH_DB_H_
+
+#include "HttpString.h"
+
+
+
+/**
+ * @defgroup FlashDB Flash-storage database management
+ * This module implements a database for static content, which is either stored on Flash or read-only memory of some kind.
+ * The database is pre-compiled using external tools and is stored as a "flat file" in memory.
+ * The contents of the database are:
+ * - A list of content-type strings
+ * - A sorted-list of static content entities. Each entity has:
+ * - URL Resource of the content (sort and lookup key)
+ * - Content type number (index into the list of content-types)
+ * - Content binary data
+ * - Additional metadata flags (Compressed, Requires-authentication)
+ *
+ * @{
+ */
+
+/// Denotes gzip-compressed content
+#define FLASHDB_FLAG_COMPRESSED (1 << 0)
+/// Denotes authentication required
+#define FLASHDB_FLAG_REQUIRE_AUTH (1 << 1)
+
+/**
+ * A structure to hold all data about content which was found in a database lookup
+ */
+//#ifdef __CCS__
+//struct __attribute__ ((__packed__)) FlashDBContent
+//#elif __IAR_SYSTEMS_ICC__
+//#pragma pack(1)
+struct FlashDBContent
+//#endif
+{
+ /// Flags. See FLASHDB_FLAG_*
+ uint16 uFlags;
+ /// Index of content type entry for this resource, in the content type list
+ uint16 uContentType;
+ /// The content blob's pointer and length
+ struct HttpBlob contentBlob;
+};
+
+/**
+ * Initialize the flash database module
+ * @param pDatabase Pointer to the beginning of the database in flash memory
+ */
+void FlashDB_Init();
+
+/**
+ * Find a content-type in the database
+ * @param index The index of the content type in the database
+ * @param[out] pResult Returns the string and its length
+ * @return nonzero if successful. zero if index out of range.
+ */
+int FlashDB_FindContentType(uint16 index, struct HttpBlob* pResult);
+
+/**
+ * Lookup content in the database, given a resource identifier
+ * @param pResource The resource as given in the HTTP request
+ * @param[out] pResult Returns the content and its metadata
+ * @return nonzero if successful. zero if such a resource was not found.
+ */
+int FlashDB_FindContent(struct HttpBlob pResource, struct FlashDBContent* pResult);
+
+/// @}
+
+#endif // _FLASH_DB_H_
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/FlashDBContentData.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,164 @@
+#include "mbed.h"
+
+extern const char FlashDBContentData[] = {
+ 0x01, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x09, 0x00, 0x2e, 0x00, 0x0c, 0x00,
+ 0x37, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x9d, 0x06, 0x43, 0x00, 0x00, 0x00, 0x0b, 0x00,
+ 0xe0, 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xee, 0x02, 0xeb, 0x06, 0x00, 0x00, 0x74, 0x65,
+ 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x68,
+ 0x74, 0x6d, 0x6c, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0b, 0xad, 0x58, 0x7b,
+ 0x73, 0xda, 0x46, 0x10, 0xff, 0x1b, 0xcf, 0xe4, 0x3b, 0x5c, 0xae, 0x53, 0x07, 0x4a, 0x40, 0x12,
+ 0x4f, 0xc7, 0x48, 0x74, 0x84, 0x24, 0x1b, 0x26, 0x18, 0x28, 0xc8, 0x76, 0xdc, 0x4e, 0xa6, 0x23,
+ 0x4b, 0x07, 0xa8, 0x01, 0x89, 0x4a, 0xc2, 0x8e, 0x27, 0xf1, 0x77, 0xef, 0xde, 0xe9, 0x81, 0xc4,
+ 0xc3, 0x25, 0xe3, 0x78, 0xc6, 0x48, 0xb7, 0xb7, 0xbb, 0xbf, 0x7d, 0xdc, 0xed, 0x2e, 0x88, 0x6f,
+ 0xd5, 0xa1, 0xa2, 0xdf, 0x8d, 0x34, 0xd4, 0xd5, 0xaf, 0xfa, 0x68, 0x74, 0xdd, 0xe9, 0xf7, 0x14,
+ 0x84, 0x4b, 0x1c, 0x77, 0x5b, 0x55, 0x38, 0x4e, 0xd5, 0xd5, 0x70, 0xa3, 0x56, 0xe6, 0x91, 0xee,
+ 0x19, 0x8e, 0x6f, 0x07, 0xb6, 0xeb, 0x18, 0x0b, 0x8e, 0xd3, 0x06, 0xb8, 0xfd, 0xe6, 0x44, 0xa4,
+ 0xbb, 0xec, 0xa9, 0xc9, 0x2a, 0x3c, 0x73, 0xe2, 0x95, 0xa6, 0xcb, 0x20, 0xa3, 0x8f, 0x4a, 0xda,
+ 0x1f, 0xd7, 0xbd, 0x1b, 0x09, 0x2b, 0xc3, 0x81, 0xae, 0x0d, 0xf4, 0x12, 0x45, 0xc1, 0x28, 0x5a,
+ 0x49, 0x38, 0x20, 0x5f, 0x03, 0x6e, 0x1e, 0x2c, 0x17, 0x2d, 0x64, 0xce, 0x0d, 0xcf, 0x27, 0x81,
+ 0xf4, 0x68, 0x3b, 0x96, 0xfb, 0xe8, 0x97, 0x84, 0x4a, 0xbd, 0x82, 0x99, 0x32, 0xbd, 0xa7, 0xf7,
+ 0xb5, 0xb6, 0x4e, 0xbe, 0x1a, 0x3e, 0xea, 0x39, 0x7e, 0xb0, 0x5e, 0x12, 0x27, 0x10, 0xb9, 0x90,
+ 0x9c, 0xa0, 0x0d, 0xe4, 0x2b, 0x4d, 0xc2, 0x97, 0xda, 0x40, 0x1b, 0xcb, 0xfa, 0x70, 0x9c, 0x02,
+ 0x19, 0xae, 0x88, 0x33, 0x9c, 0x4e, 0x6d, 0x93, 0x94, 0x5d, 0x6f, 0x86, 0xaa, 0xe5, 0x0a, 0x42,
+ 0xf9, 0x5b, 0xdb, 0xa9, 0x56, 0x0a, 0x78, 0x5b, 0x5e, 0x19, 0x6b, 0xb2, 0xae, 0xa9, 0x29, 0x69,
+ 0xbe, 0xc5, 0xef, 0x72, 0x75, 0xe5, 0xc1, 0xa5, 0xa6, 0x76, 0xee, 0x52, 0x7c, 0xaa, 0xf1, 0x40,
+ 0xd0, 0xc5, 0x82, 0x04, 0xe6, 0x9c, 0x78, 0x87, 0x24, 0x52, 0xfc, 0x15, 0x5e, 0xa8, 0xf2, 0x1f,
+ 0x84, 0x5a, 0x4b, 0x68, 0x0a, 0xcd, 0x5a, 0x85, 0x8f, 0x50, 0x26, 0xca, 0xb8, 0x37, 0xd2, 0xe1,
+ 0xf5, 0xc1, 0xf0, 0x58, 0x04, 0x3d, 0xf2, 0xef, 0x9a, 0xf8, 0x01, 0x92, 0x90, 0x43, 0x1e, 0xd1,
+ 0xa7, 0xab, 0x7e, 0x37, 0x08, 0x56, 0xe3, 0x90, 0x98, 0x2f, 0xb4, 0x42, 0x46, 0xd3, 0x5d, 0x3b,
+ 0x94, 0x85, 0x8f, 0xd6, 0x1e, 0x31, 0x89, 0xfd, 0x40, 0xac, 0x31, 0xf1, 0x57, 0xae, 0xe3, 0x13,
+ 0xd8, 0x12, 0xa2, 0x2d, 0x9f, 0x38, 0xd6, 0xc0, 0x95, 0x28, 0xe7, 0x74, 0xed, 0x98, 0x34, 0x93,
+ 0x48, 0x77, 0x67, 0xb3, 0x05, 0xe9, 0x6b, 0x6a, 0x1e, 0xfe, 0x9d, 0xf5, 0xb2, 0xf0, 0xe6, 0xe4,
+ 0x1b, 0x18, 0x93, 0x82, 0x2f, 0xbb, 0x10, 0xc4, 0x3c, 0x1e, 0x0d, 0x27, 0x3a, 0x7e, 0x8f, 0xb9,
+ 0x05, 0xb1, 0x4a, 0x7e, 0x60, 0x04, 0x6b, 0xff, 0x77, 0x60, 0x97, 0x70, 0x31, 0x94, 0x2b, 0xe2,
+ 0x53, 0x83, 0x69, 0x94, 0x02, 0xa6, 0x11, 0xbf, 0x47, 0x81, 0xb7, 0x26, 0xd4, 0xca, 0x8c, 0x32,
+ 0x6a, 0x03, 0xb3, 0xfd, 0xf9, 0xcd, 0x49, 0xca, 0x8c, 0x15, 0xf1, 0x6c, 0xd7, 0xb2, 0xcd, 0xeb,
+ 0x95, 0x65, 0x04, 0x24, 0x5f, 0xa0, 0x36, 0xd8, 0xd3, 0xfc, 0xae, 0x33, 0xe0, 0x0d, 0xfa, 0xfe,
+ 0x3d, 0xf2, 0xba, 0x2d, 0xa1, 0x1a, 0x18, 0x9c, 0xa3, 0xdc, 0x94, 0x3d, 0x74, 0x50, 0xac, 0x52,
+ 0x5a, 0x48, 0x7c, 0xc1, 0x91, 0xc7, 0x39, 0x21, 0x8b, 0xd8, 0x95, 0xd8, 0xf8, 0x19, 0x09, 0x42,
+ 0x4a, 0x29, 0xed, 0x40, 0x6e, 0xbf, 0x0b, 0x40, 0xdf, 0x13, 0x6d, 0x3e, 0xdc, 0x49, 0xe7, 0x05,
+ 0x96, 0xa1, 0x69, 0xc5, 0xe2, 0xae, 0x3a, 0xd7, 0xf1, 0x88, 0x61, 0x3d, 0x51, 0x58, 0x02, 0x37,
+ 0xc1, 0x99, 0x51, 0x25, 0x71, 0x60, 0xf2, 0xcc, 0x95, 0xc8, 0x17, 0x70, 0x11, 0xe5, 0xd3, 0xa2,
+ 0x4c, 0x70, 0x42, 0x05, 0x25, 0xa9, 0x86, 0x4e, 0x4f, 0x51, 0xc6, 0x4c, 0xe6, 0x87, 0x24, 0xc1,
+ 0xf9, 0x0a, 0x95, 0xc4, 0x5a, 0x72, 0x07, 0x8e, 0x08, 0xdb, 0x4b, 0x9d, 0x11, 0xb6, 0xa6, 0xe7,
+ 0x86, 0x45, 0x0a, 0x98, 0xb2, 0xd0, 0xa1, 0x2c, 0xdc, 0x4d, 0x80, 0x5a, 0x2d, 0xec, 0x20, 0x8f,
+ 0xcf, 0x71, 0x21, 0x2d, 0x66, 0xce, 0x41, 0x86, 0xc9, 0xfe, 0x55, 0xf9, 0x5c, 0xa6, 0x97, 0x5c,
+ 0x71, 0x2d, 0x22, 0x07, 0x79, 0x3e, 0x61, 0x9b, 0xba, 0x5e, 0x9e, 0xb2, 0xda, 0x52, 0xb5, 0x85,
+ 0x6c, 0xf1, 0x0c, 0x3e, 0x8a, 0xc5, 0xc8, 0xda, 0xc4, 0x5c, 0x9a, 0x59, 0xd0, 0x75, 0x8a, 0x84,
+ 0x78, 0x67, 0xb3, 0x95, 0xb3, 0x5c, 0x93, 0x15, 0x85, 0x32, 0x64, 0x4e, 0x5b, 0x10, 0xfa, 0xda,
+ 0x79, 0xea, 0x59, 0x79, 0x4c, 0x8f, 0xa5, 0x8b, 0x8b, 0x79, 0xbb, 0x28, 0x14, 0x0a, 0x80, 0x4e,
+ 0xcc, 0x2f, 0xc4, 0x92, 0x68, 0x4a, 0x5b, 0x47, 0x09, 0x27, 0xa2, 0x7e, 0xf0, 0xb4, 0x20, 0x65,
+ 0xd3, 0x5d, 0xb8, 0x9e, 0x84, 0x67, 0x1e, 0x21, 0x0e, 0x4e, 0x34, 0x3c, 0xc7, 0x2f, 0x64, 0xe1,
+ 0x93, 0x57, 0x1b, 0x37, 0x35, 0x40, 0xcb, 0x6b, 0xac, 0xf3, 0x88, 0xb5, 0xc7, 0x36, 0x96, 0x07,
+ 0x73, 0xde, 0x6e, 0x27, 0x49, 0x7e, 0x4e, 0x65, 0xe9, 0xc1, 0x5d, 0x04, 0x06, 0x3b, 0x73, 0x2b,
+ 0x5a, 0x85, 0x7b, 0x4e, 0x90, 0x0f, 0x73, 0x26, 0x7c, 0x4e, 0xd2, 0x74, 0xd0, 0x92, 0xdb, 0x95,
+ 0x1b, 0x76, 0x04, 0x5c, 0x28, 0xdb, 0x8e, 0x43, 0x3c, 0xd6, 0x2c, 0xe2, 0xac, 0xf3, 0x9f, 0xff,
+ 0x5f, 0x41, 0x04, 0xbf, 0x57, 0x5e, 0x48, 0xe4, 0x37, 0x46, 0x46, 0x6f, 0xbf, 0x09, 0x3c, 0xbf,
+ 0xbb, 0x99, 0x78, 0x10, 0x91, 0xb8, 0x1a, 0x7f, 0xf6, 0x21, 0xf1, 0x02, 0x8e, 0xd1, 0x36, 0x43,
+ 0x81, 0x16, 0x14, 0x7e, 0xe7, 0xc0, 0x1d, 0x34, 0xd7, 0x5f, 0xd8, 0x16, 0xf1, 0x04, 0x1c, 0xc7,
+ 0xfd, 0xde, 0x30, 0xbf, 0xcc, 0x3c, 0xb8, 0xe9, 0x96, 0x42, 0x33, 0x00, 0x26, 0xe0, 0x5f, 0x2e,
+ 0xd8, 0x1f, 0xde, 0x8e, 0x75, 0xea, 0x84, 0xfc, 0x1c, 0x1c, 0x9e, 0x3f, 0xe3, 0xa1, 0x75, 0xb4,
+ 0x7e, 0x40, 0xd9, 0xa3, 0x6d, 0x05, 0x73, 0x29, 0x8e, 0x57, 0x11, 0xe1, 0x5f, 0x71, 0x2b, 0x87,
+ 0xb2, 0x86, 0x86, 0x0f, 0xf6, 0x49, 0x3f, 0xe8, 0x7f, 0x5c, 0xca, 0xc2, 0x67, 0x31, 0x2c, 0x16,
+ 0xd0, 0xb0, 0x75, 0x7b, 0x49, 0xdc, 0x75, 0x90, 0x4f, 0xaa, 0x78, 0xbe, 0x80, 0xbe, 0x6d, 0x57,
+ 0xf2, 0x16, 0x7a, 0x7e, 0x8f, 0x20, 0x5b, 0x7c, 0x54, 0xf4, 0x45, 0x2e, 0xe9, 0x73, 0xd0, 0xf2,
+ 0xf4, 0xbb, 0xbe, 0x86, 0xe8, 0x64, 0x10, 0x0d, 0x04, 0xa6, 0xef, 0x87, 0xcd, 0xf0, 0x6d, 0xa9,
+ 0x44, 0x4d, 0xe8, 0x56, 0xca, 0xe6, 0x3f, 0x5f, 0xd0, 0x37, 0x34, 0x75, 0x9d, 0xa0, 0x34, 0x35,
+ 0x96, 0xf6, 0xe2, 0xe9, 0x1c, 0xe1, 0x89, 0xbd, 0x9c, 0xac, 0x1d, 0x8c, 0xa8, 0x75, 0xa5, 0x12,
+ 0x13, 0xe0, 0x98, 0x2e, 0x3a, 0x8a, 0x70, 0xd1, 0x2c, 0x22, 0x76, 0x86, 0xea, 0x1d, 0xea, 0x43,
+ 0xf7, 0x95, 0x30, 0x71, 0x4a, 0x97, 0x1d, 0x8c, 0xd4, 0xde, 0x58, 0xc2, 0x7d, 0x1d, 0x46, 0x84,
+ 0xe1, 0xa0, 0x3f, 0x94, 0x55, 0x09, 0x6f, 0x9b, 0x1b, 0x0e, 0x35, 0x02, 0x92, 0xfb, 0xbd, 0xcb,
+ 0x81, 0xa4, 0x40, 0xbf, 0xd6, 0xc6, 0x6d, 0xf1, 0x02, 0x5a, 0x37, 0xf4, 0xef, 0xfe, 0x10, 0xc4,
+ 0x7f, 0x99, 0x4e, 0x79, 0x1a, 0xf8, 0xb6, 0xa2, 0x54, 0xe1, 0x89, 0x6e, 0xc9, 0x3d, 0x9a, 0x10,
+ 0xef, 0x81, 0x78, 0x22, 0x47, 0xf9, 0xda, 0x60, 0x80, 0xc0, 0xb4, 0x54, 0x90, 0xd2, 0x97, 0x27,
+ 0x13, 0x09, 0x3f, 0x42, 0xc5, 0x24, 0x1e, 0xd8, 0x7b, 0x84, 0xd6, 0x5b, 0xb2, 0x30, 0xdd, 0x25,
+ 0x81, 0xc6, 0xfc, 0xe6, 0xe4, 0xea, 0x9e, 0x58, 0xa8, 0xe3, 0x1a, 0x9e, 0x85, 0x14, 0xd7, 0x99,
+ 0xda, 0xb3, 0xb5, 0x67, 0xd0, 0x40, 0x97, 0x37, 0x48, 0x15, 0x8a, 0x14, 0x29, 0x64, 0x13, 0x93,
+ 0xdc, 0x81, 0x88, 0xde, 0xf6, 0x54, 0xbd, 0x2b, 0x09, 0x50, 0xfa, 0x51, 0x67, 0x38, 0x56, 0xb5,
+ 0xb1, 0xc4, 0x23, 0x45, 0xeb, 0xf7, 0x47, 0xb2, 0xaa, 0xf6, 0x20, 0x1e, 0x15, 0xb6, 0x9a, 0x8c,
+ 0x64, 0x85, 0xad, 0xa8, 0x24, 0x88, 0x8e, 0xd1, 0x4d, 0x68, 0xa0, 0x3e, 0x1c, 0x31, 0x12, 0xd0,
+ 0xd4, 0x48, 0x57, 0x83, 0xe7, 0x43, 0x52, 0x4e, 0x1c, 0x65, 0xdd, 0x60, 0x46, 0xde, 0x53, 0x23,
+ 0xdf, 0xf9, 0x08, 0x4a, 0x13, 0x1c, 0x93, 0x94, 0xa9, 0x68, 0xed, 0xdb, 0xce, 0x0c, 0x45, 0xb1,
+ 0x82, 0x31, 0xce, 0x08, 0xb5, 0xc4, 0x11, 0x1b, 0x1d, 0xd0, 0x5a, 0x47, 0x7d, 0x42, 0x15, 0x06,
+ 0x2e, 0xd5, 0x17, 0x78, 0xee, 0xa2, 0x9c, 0x62, 0xbe, 0x18, 0x8e, 0xaf, 0x90, 0xac, 0xe8, 0xbd,
+ 0xe1, 0x40, 0xc2, 0x38, 0xa2, 0xe6, 0x44, 0xb5, 0x77, 0x93, 0xd5, 0x12, 0xdf, 0x0d, 0xd0, 0xce,
+ 0x8e, 0x87, 0x84, 0x97, 0x86, 0x37, 0xb3, 0x9d, 0xd2, 0xbd, 0x1b, 0x04, 0xee, 0xf2, 0x1c, 0xf1,
+ 0xe6, 0x12, 0xb7, 0xc5, 0x78, 0x54, 0x63, 0x65, 0xb9, 0x06, 0x04, 0x4e, 0xce, 0x10, 0xf7, 0x90,
+ 0x1c, 0xb7, 0xbe, 0x4b, 0xac, 0xef, 0xe3, 0x6b, 0xec, 0x12, 0x1b, 0xfb, 0xf8, 0x9a, 0xbb, 0xc4,
+ 0xe6, 0x3e, 0xbe, 0xb3, 0x5d, 0x62, 0x44, 0x4a, 0xbc, 0xed, 0x0d, 0x46, 0xd7, 0x7a, 0x78, 0xad,
+ 0x94, 0xae, 0xa6, 0x7c, 0xec, 0x0c, 0x3f, 0x6d, 0x98, 0xff, 0xae, 0x61, 0x9a, 0xe7, 0xeb, 0xcd,
+ 0x2a, 0x0a, 0x0d, 0xab, 0x0e, 0x10, 0x92, 0x72, 0xb5, 0x6e, 0x2e, 0x5b, 0x68, 0x4e, 0xec, 0xd9,
+ 0x3c, 0x88, 0xd7, 0xf4, 0xc6, 0x28, 0xf0, 0xdd, 0xe0, 0xa3, 0x84, 0x37, 0x23, 0xe3, 0xbb, 0xda,
+ 0x3b, 0xb8, 0x30, 0xf0, 0x16, 0x23, 0x0b, 0x62, 0x07, 0xce, 0xf5, 0xcb, 0xf0, 0xf5, 0x0c, 0x7c,
+ 0xfd, 0x35, 0xf0, 0xf5, 0x2d, 0xf8, 0xca, 0x11, 0xf0, 0x8d, 0x0c, 0x7c, 0xe3, 0x35, 0xf0, 0x8d,
+ 0x2d, 0xf8, 0xea, 0x11, 0xf0, 0xcd, 0x0c, 0x7c, 0xf3, 0x35, 0xf0, 0xcd, 0x2d, 0xf8, 0xda, 0x11,
+ 0xf0, 0x67, 0x19, 0xf8, 0xb3, 0xd7, 0xc0, 0x9f, 0x6d, 0xc1, 0xd7, 0x37, 0xf7, 0x13, 0xaa, 0x31,
+ 0x5c, 0xc5, 0xf8, 0xb2, 0x72, 0xf4, 0xb6, 0xc6, 0x8b, 0x74, 0x7d, 0x6a, 0xfc, 0x48, 0x79, 0x62,
+ 0xc2, 0xa9, 0x1b, 0xad, 0xab, 0xc9, 0xfb, 0xfe, 0x92, 0x74, 0xcb, 0xa6, 0xd6, 0x09, 0x9b, 0x82,
+ 0x53, 0xa6, 0xed, 0x72, 0x27, 0x37, 0x69, 0x33, 0xcd, 0xb0, 0xeb, 0xc4, 0x14, 0x40, 0x09, 0x1a,
+ 0x45, 0x54, 0xe8, 0x80, 0x62, 0xa7, 0xcd, 0x8b, 0x5c, 0xa7, 0x7d, 0xa4, 0xbe, 0x78, 0xb8, 0x61,
+ 0xea, 0x6e, 0xa2, 0xb6, 0x2b, 0x9b, 0x9e, 0xeb, 0xfb, 0x89, 0xf4, 0xca, 0x0d, 0xa0, 0x53, 0xdb,
+ 0x50, 0xf2, 0xa1, 0x45, 0x1c, 0x80, 0x80, 0x6f, 0xbc, 0xea, 0x26, 0xb4, 0x9b, 0x28, 0xbc, 0x14,
+ 0x90, 0x97, 0xea, 0x5d, 0x67, 0x9c, 0x62, 0xcd, 0xb8, 0x92, 0x4e, 0x4f, 0x55, 0x68, 0xc4, 0xe9,
+ 0x11, 0x8e, 0x49, 0xcf, 0x96, 0x41, 0x51, 0xfb, 0xe8, 0x6a, 0xbd, 0xcb, 0xae, 0x2e, 0x55, 0xea,
+ 0xe9, 0x8d, 0x83, 0x40, 0xfc, 0x91, 0x40, 0xbb, 0x58, 0x5b, 0x70, 0xcd, 0x4d, 0x1a, 0xe2, 0xf9,
+ 0x27, 0x2c, 0x9b, 0x5c, 0x3a, 0x4e, 0x49, 0xe4, 0x76, 0xc9, 0xe9, 0x38, 0xc7, 0x04, 0x6a, 0x73,
+ 0x96, 0x16, 0xa7, 0xbe, 0xaf, 0x5d, 0xe8, 0x71, 0xc8, 0xef, 0x5d, 0x0f, 0xf0, 0xce, 0x91, 0xe3,
+ 0x3a, 0xa4, 0x05, 0x33, 0xa9, 0x65, 0x41, 0x07, 0x4c, 0x85, 0x3e, 0x13, 0xfe, 0xed, 0x0c, 0x64,
+ 0x93, 0xbd, 0x63, 0xc7, 0xb6, 0x11, 0x07, 0x4e, 0x46, 0x96, 0x4d, 0x1c, 0x6d, 0xe1, 0x26, 0x88,
+ 0x1b, 0xf1, 0x4c, 0x10, 0x62, 0x4d, 0x1b, 0x35, 0x22, 0x97, 0x74, 0xd4, 0x9f, 0x36, 0x6d, 0x6c,
+ 0x80, 0xf7, 0x8f, 0x00, 0x90, 0xc0, 0xee, 0x58, 0xbb, 0x90, 0x30, 0x67, 0x3b, 0x16, 0xf9, 0x5a,
+ 0xa6, 0x3f, 0x16, 0xe1, 0x68, 0x6a, 0x9a, 0xf4, 0xfe, 0xd4, 0xa4, 0x7a, 0xbb, 0x0b, 0xd7, 0x26,
+ 0x99, 0x85, 0xe4, 0xf6, 0xae, 0x5f, 0x2f, 0x7b, 0x92, 0x8e, 0x4b, 0x28, 0x0b, 0x37, 0x0f, 0x86,
+ 0xc6, 0x70, 0x8a, 0xa4, 0xbf, 0x6c, 0xfd, 0x07, 0x4b, 0x9e, 0x32, 0xf6, 0x20, 0x13, 0x00, 0x00,
+ 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x1f, 0x8b, 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x0b, 0x75, 0x54, 0x5b, 0x6f, 0x9b, 0x30, 0x14, 0x7e, 0xde, 0xa4, 0xfd,
+ 0x87, 0x33, 0x26, 0x4d, 0x9b, 0xb4, 0x04, 0x92, 0xb4, 0xda, 0xa5, 0x10, 0x89, 0x80, 0x9b, 0x20,
+ 0xd1, 0x90, 0x51, 0x77, 0x51, 0x1f, 0x1d, 0x62, 0x12, 0x6b, 0x60, 0x33, 0x70, 0x9a, 0xe6, 0xdf,
+ 0xef, 0x18, 0x58, 0x97, 0x75, 0xdb, 0x0b, 0xbe, 0x7e, 0x97, 0x73, 0x7c, 0x0e, 0xee, 0xeb, 0x30,
+ 0x09, 0xe8, 0xfd, 0x8a, 0xc0, 0x82, 0xde, 0xc4, 0xb0, 0xba, 0x9b, 0xc5, 0x51, 0x00, 0xd6, 0xc0,
+ 0xb6, 0xd7, 0x93, 0xc0, 0xb6, 0x43, 0x1a, 0x76, 0x07, 0x17, 0x43, 0x07, 0x68, 0xcd, 0x64, 0x23,
+ 0xb4, 0x50, 0x92, 0x15, 0xb6, 0x4d, 0x96, 0xd6, 0xf4, 0xd5, 0x4b, 0xd7, 0x9c, 0xb6, 0x23, 0xf1,
+ 0x43, 0x1c, 0x5f, 0xb8, 0x37, 0x84, 0xfa, 0x88, 0xa1, 0xab, 0x01, 0xf9, 0x7a, 0x17, 0x7d, 0xf3,
+ 0xac, 0x20, 0x59, 0x52, 0xb2, 0xa4, 0x03, 0xa3, 0x62, 0x41, 0xbf, 0xf2, 0x2c, 0xcd, 0x1f, 0xb5,
+ 0xbd, 0xd7, 0x65, 0x71, 0x05, 0xd9, 0x9e, 0xd5, 0x0d, 0xd7, 0xde, 0x51, 0xc8, 0xad, 0x3a, 0x36,
+ 0x83, 0xd1, 0xf8, 0x72, 0x6c, 0xb5, 0x64, 0x34, 0xa2, 0x31, 0x99, 0x52, 0xfe, 0xc8, 0x1a, 0x88,
+ 0x64, 0xa3, 0x0f, 0x25, 0x97, 0xda, 0xb5, 0xbb, 0xed, 0x27, 0xb5, 0xa5, 0x7f, 0x43, 0x3c, 0x6b,
+ 0x4e, 0x96, 0x24, 0xf5, 0x69, 0x92, 0x9e, 0x89, 0x24, 0x15, 0x97, 0x49, 0x9e, 0x8b, 0x8c, 0x0f,
+ 0x55, 0xbd, 0x83, 0xc9, 0x70, 0x0c, 0xf0, 0x6e, 0x2d, 0xe4, 0x64, 0xfc, 0xde, 0x7a, 0x8e, 0x0f,
+ 0x52, 0xe2, 0x53, 0x12, 0x9e, 0xa1, 0x9d, 0x2b, 0xe7, 0xef, 0x5b, 0x0b, 0x7f, 0x39, 0x27, 0xe1,
+ 0xec, 0xfe, 0xec, 0x5e, 0xc8, 0x1e, 0x38, 0x5c, 0x17, 0x5c, 0x67, 0x7b, 0x5e, 0xff, 0x0f, 0x71,
+ 0x76, 0x7f, 0xec, 0x8c, 0x26, 0xce, 0xe7, 0xd1, 0xc5, 0xd5, 0xe8, 0xe3, 0xe8, 0x33, 0x4e, 0x5b,
+ 0x15, 0xd7, 0xee, 0x53, 0xe8, 0xce, 0x92, 0xf0, 0x1e, 0x62, 0x04, 0x79, 0x16, 0x97, 0x83, 0xf9,
+ 0xcc, 0x82, 0x30, 0x4a, 0x3d, 0x2b, 0xa6, 0x69, 0x97, 0xf1, 0x11, 0xf8, 0x71, 0x34, 0x5f, 0x7a,
+ 0x01, 0x92, 0x91, 0x74, 0xea, 0x5e, 0x23, 0x2f, 0x92, 0xc7, 0x09, 0x5e, 0x7a, 0x93, 0xe7, 0x8e,
+ 0x63, 0x08, 0xd7, 0xbc, 0xc8, 0x54, 0xc9, 0x81, 0x2a, 0x08, 0x02, 0x94, 0x70, 0x60, 0xcd, 0x37,
+ 0x70, 0xcb, 0xeb, 0x07, 0x5e, 0xbb, 0xb6, 0x81, 0x4c, 0x51, 0x71, 0x64, 0x08, 0x57, 0x70, 0x4b,
+ 0xef, 0x63, 0x74, 0x5a, 0xb2, 0x7a, 0x27, 0xe4, 0x60, 0xa3, 0xb4, 0x56, 0xe5, 0x17, 0x70, 0xb2,
+ 0xd2, 0x9a, 0xba, 0xb3, 0xb4, 0x35, 0xb7, 0x32, 0xdf, 0x5e, 0xb1, 0x7d, 0x19, 0x7f, 0x16, 0x13,
+ 0x58, 0x47, 0x21, 0x5d, 0x78, 0xa3, 0x31, 0xd2, 0xcf, 0x92, 0x34, 0x24, 0xa9, 0xe7, 0x40, 0x40,
+ 0xe2, 0x78, 0xe5, 0x87, 0x61, 0x84, 0x01, 0x8c, 0xdb, 0xd5, 0xed, 0xca, 0x0f, 0xda, 0x95, 0x41,
+ 0x22, 0xb4, 0x65, 0x30, 0x93, 0xb0, 0x27, 0x98, 0x7c, 0xbc, 0x84, 0x05, 0x89, 0xe6, 0x0b, 0xea,
+ 0x5d, 0x7e, 0x1a, 0xa3, 0x31, 0x1a, 0x3e, 0xbf, 0x72, 0x71, 0xe9, 0xc0, 0xb7, 0x2e, 0x6e, 0x9a,
+ 0xac, 0xba, 0xd3, 0x17, 0x68, 0xbd, 0xdb, 0x8a, 0xc9, 0x35, 0x9d, 0xde, 0x6c, 0xf8, 0x16, 0xea,
+ 0x83, 0x6c, 0x80, 0x41, 0x53, 0xb2, 0xa2, 0x80, 0x92, 0x97, 0xaa, 0x3e, 0x41, 0xae, 0x94, 0xae,
+ 0x6a, 0x21, 0xf5, 0x59, 0x0e, 0x86, 0x10, 0xe9, 0x8e, 0x64, 0x8f, 0xb5, 0x95, 0xb1, 0x8a, 0x6d,
+ 0x44, 0x21, 0xf4, 0x09, 0xb4, 0x82, 0xbd, 0x6a, 0x34, 0x34, 0x9a, 0x69, 0x91, 0x01, 0x93, 0x5b,
+ 0xd8, 0x9e, 0x24, 0x2b, 0x71, 0x7e, 0x44, 0x74, 0xc5, 0x76, 0xbc, 0x19, 0x76, 0xf9, 0xf8, 0xdb,
+ 0x42, 0x24, 0xe1, 0x96, 0x95, 0x55, 0xc1, 0x81, 0x55, 0x55, 0x21, 0x32, 0x66, 0xba, 0xe5, 0x03,
+ 0xdc, 0x35, 0x42, 0xee, 0x9e, 0xde, 0x01, 0x9f, 0xb6, 0xc3, 0x66, 0x4a, 0x4a, 0x9e, 0x69, 0xf1,
+ 0x80, 0xba, 0x1f, 0xce, 0xbc, 0x41, 0x55, 0xab, 0x07, 0xb1, 0xe5, 0xcf, 0x7d, 0xd5, 0x18, 0x8e,
+ 0xe6, 0xc5, 0x09, 0x10, 0xa8, 0x6b, 0x55, 0x74, 0x2c, 0xcd, 0x51, 0x60, 0xe1, 0x19, 0x81, 0x98,
+ 0x84, 0x6f, 0xeb, 0xe6, 0xc7, 0x41, 0x5d, 0x35, 0xa0, 0xa4, 0xad, 0xf2, 0xbc, 0xb3, 0x2f, 0x9a,
+ 0xaa, 0x60, 0xa7, 0x06, 0xf4, 0x9e, 0xb7, 0x61, 0x1d, 0xf0, 0x38, 0x87, 0xe3, 0x9e, 0xf3, 0x9e,
+ 0x02, 0x03, 0xfd, 0x0e, 0x15, 0x72, 0x4b, 0xf4, 0x5b, 0x72, 0x8d, 0x16, 0x7a, 0x6f, 0x98, 0x51,
+ 0x14, 0x36, 0x40, 0x93, 0xdd, 0x8d, 0x62, 0xf5, 0x16, 0xda, 0xef, 0x7f, 0x53, 0xe0, 0x62, 0xf7,
+ 0xa7, 0xe4, 0xda, 0xb3, 0x6c, 0xa4, 0xc8, 0xc5, 0x6e, 0x68, 0x7a, 0xdc, 0x9a, 0x06, 0x85, 0xd1,
+ 0xc0, 0xfe, 0xe0, 0xae, 0xed, 0x4f, 0x0d, 0x29, 0x36, 0x4b, 0xf6, 0xbd, 0x0f, 0xa1, 0x33, 0x65,
+ 0xcc, 0x76, 0xa0, 0x43, 0xcd, 0x9f, 0x44, 0x3b, 0xbd, 0x73, 0xb9, 0xbe, 0x28, 0xdb, 0xc5, 0xaf,
+ 0xed, 0x7f, 0xd5, 0x0c, 0x96, 0xd5, 0xef, 0x5a, 0xc2, 0x49, 0x57, 0xb9, 0x76, 0x5b, 0xba, 0x6d,
+ 0x51, 0x3f, 0xd5, 0x73, 0xcf, 0xf9, 0x47, 0xb1, 0xdb, 0xa6, 0x0f, 0xbb, 0xc6, 0x34, 0xff, 0xb8,
+ 0x9f, 0xbe, 0x91, 0xbb, 0xd0, 0x2a, 0x05, 0x00, 0x00
+};
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/HttpAuth.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,349 @@
+/*****************************************************************************
+*
+* HttpAuth.c
+* 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.
+*
+*****************************************************************************/
+#include "HttpAuth.h"
+
+#ifdef HTTP_CORE_ENABLE_AUTH
+
+#include "md5.h"
+#include <string.h>
+#include "HttpString.h"
+/**
+ * @addtogroup HttpAuth
+ * @{
+ */
+
+#define DIGEST_AUTHENTICATION_BUFFER_SIZE (32)
+
+/**
+ * This structure holds the HTTP digest-access authentication state
+ */
+struct HttpAuthState
+{
+ /// Last-generated nonce
+ uint8 nonce[DIGEST_AUTHENTICATION_BUFFER_SIZE];
+ /// Last-generated opaque
+ uint8 opaque[DIGEST_AUTHENTICATION_BUFFER_SIZE];
+ /// The hash of the username, realm, and password
+ uint8 ha1[DIGEST_AUTHENTICATION_BUFFER_SIZE];
+};
+
+
+
+/// The global state for digest-access authentication
+
+static struct HttpAuthState g_authState; // = { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+// {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+// {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
+///
+MD5_CTX MD5state;
+
+char HTTP_AUTH_REALM[] = "mbed web server";
+
+/// Header strings to be used for response headers
+char HTTP_AUTHENTICATE_RESPONSE_REALM[] = "WWW-Authenticate: Digest realm=\"";
+char HTTP_AUTHENTICATE_RESPONSE_NONCE[] = "\",qop=\"auth\",nonce=\"";
+char HTTP_AUTHENTICATE_RESPONSE_OPAQUE[] = "\",opaque=\"";
+char HTTP_AUTHENTICATE_RESPONSE_EOH[] = "\"\r\n";
+
+/// Authenticate header tokens
+char HTTP_AUTHENTICATE_REALM[] = "realm";
+char HTTP_AUTHENTICATE_QOP[] = "qop";
+char HTTP_AUTHENTICATE_AUTH[] = "auth";
+char HTTP_AUTHENTICATE_NONCE[] = "nonce";
+char HTTP_AUTHENTICATE_OPAQUE[] = "opaque";
+char HTTP_AUTHENTICATE_DIGEST[] = "digest";
+char HTTP_AUTHENTICATE_URI[] = "uri";
+char HTTP_AUTHENTICATE_NC[] = "nc=";
+char HTTP_AUTHENTICATE_CNONCE[] = "cnonce";
+char HTTP_AUTHENTICATE_RESPONSE[] = "response";
+char HTTP_AUTHENTICATE_USERNAME[] = "username";
+char HTTP_DELIMITER_QUOTE[] = "\"";
+char HTTP_DELIMITER_COMMA[] = ",";
+
+
+/// The length of the response authentication header
+/// The two 32 numbers represent nonce and opaque strings and the -5 is to compensate for the sizeof() calls
+uint16 HTTP_AUTHENTICATE_RESPONSE_HEADER_LENGTH =
+ sizeof(HTTP_AUTHENTICATE_RESPONSE_REALM) +
+ sizeof(HTTP_AUTHENTICATE_RESPONSE_NONCE) +
+ sizeof(HTTP_AUTHENTICATE_RESPONSE_OPAQUE) +
+ sizeof(HTTP_AUTHENTICATE_RESPONSE_EOH) +
+ sizeof(HTTP_AUTH_REALM) +
+ DIGEST_AUTHENTICATION_BUFFER_SIZE + DIGEST_AUTHENTICATION_BUFFER_SIZE - 5;
+
+
+/**
+ * Simple random generator
+ * To improve randomness the initial seed has to be dynamic
+ */
+static uint32 GetRandomUint()
+{
+ // set static seed
+ static uint32 m_z = 1234;
+ static uint32 m_w = 98877;
+
+ m_z = 36969 * (m_z & 65535) + (m_z >> 16);
+ m_w = 18000 * (m_w & 65535) + (m_w >> 16);
+ return (m_z << 16) + m_w;
+}
+
+static void MD5_FinalToString(uint8* str, MD5_CTX *md5stat)
+{
+ uint8 tmp[16];
+ uint8 i;
+ struct HttpBlob location;
+ location.uLength = 2;
+ location.pData = str;
+ MD5_Final(tmp, md5stat);
+ for (i=0; i<16; i++, location.pData += 2)
+ HttpString_htoa(tmp[i], &location, 1);
+}
+
+
+/**
+ * This function will generate random 16 bytes to be used for Nonce and opaque strings
+ */
+static void Generate32BytesRandomString(uint8 *str)
+{
+ struct HttpBlob str1;
+ str1.uLength = 8;
+ str1.pData = str;
+ HttpString_htoa(GetRandomUint(), &str1, 1);
+ str1.pData = str + 8;
+ HttpString_htoa(GetRandomUint(), &str1, 1);
+ str1.pData = str + 16;
+ HttpString_htoa(GetRandomUint(), &str1, 1);
+ str1.pData = str + 24;
+ HttpString_htoa(GetRandomUint(), &str1, 1);
+}
+
+void HttpAuth_Init(struct HttpBlob username, struct HttpBlob password)
+{
+ MD5_Init(&MD5state);
+ MD5_Update(&MD5state, username.pData, username.uLength);
+ MD5_Update(&MD5state, (unsigned char*)":", 1);
+ MD5_Update(&MD5state, HTTP_AUTH_REALM, sizeof(HTTP_AUTH_REALM)-1);
+ MD5_Update(&MD5state, (unsigned char*)":", 1);
+ MD5_Update(&MD5state, password.pData, password.uLength);
+ MD5_FinalToString(g_authState.ha1, &MD5state);
+}
+
+static void AddStringToBlob(struct HttpBlob * trgt, char *str, uint16 length)
+{
+ memcpy(trgt->pData + trgt->uLength, str, length);
+ trgt->uLength += length;
+}
+
+void HttpAuth_ResponseAuthenticate(struct HttpRequest* pRequest, struct HttpBlob* pWWWAuthenticate)
+{
+ struct HttpBlob headerBlob;
+
+ if (pWWWAuthenticate->uLength < HTTP_AUTHENTICATE_RESPONSE_HEADER_LENGTH)
+ {
+ pWWWAuthenticate->uLength = 0;
+ return;
+ }
+ // There is enough space to add the authenticate header
+
+ headerBlob.pData = pWWWAuthenticate->pData;
+ headerBlob.uLength = 0;
+
+ // Generate new Nonce and opaque
+ Generate32BytesRandomString(g_authState.nonce);
+ Generate32BytesRandomString(g_authState.opaque);
+
+ // Build response header
+ AddStringToBlob(&headerBlob, HTTP_AUTHENTICATE_RESPONSE_REALM, sizeof(HTTP_AUTHENTICATE_RESPONSE_REALM)-1);
+ AddStringToBlob(&headerBlob, HTTP_AUTH_REALM, sizeof(HTTP_AUTH_REALM) -1);
+ AddStringToBlob(&headerBlob, HTTP_AUTHENTICATE_RESPONSE_NONCE, sizeof(HTTP_AUTHENTICATE_RESPONSE_NONCE) -1);
+ AddStringToBlob(&headerBlob, (char*)g_authState.nonce, sizeof(g_authState.nonce));
+ AddStringToBlob(&headerBlob, HTTP_AUTHENTICATE_RESPONSE_OPAQUE, sizeof(HTTP_AUTHENTICATE_RESPONSE_OPAQUE) -1);
+ AddStringToBlob(&headerBlob, (char*)g_authState.opaque, sizeof(g_authState.opaque));
+ AddStringToBlob(&headerBlob, HTTP_AUTHENTICATE_RESPONSE_EOH, sizeof(HTTP_AUTHENTICATE_RESPONSE_EOH) - 1);
+
+ pWWWAuthenticate->uLength = headerBlob.uLength;
+}
+
+/**
+ * Find/verify name value pair in the input blob
+ *
+ * After return the location is stays in the same place since the order of the name value pairs in not constant
+ * Returns: if header not found return 0
+ * if value token is NULL - return pointer to start of value length of value till the \" delimiter
+ * if value token is not NULL - return 1 if values match
+ */
+static uint16 HttpAuth_VerifyHeaderNameValue(struct HttpBlob *location, char* nameToken, uint8 tokenlenLen, char *value, uint8 valuelen, char** outValue)
+{
+ uint8 * found;
+ struct HttpBlob originalLocation;
+ originalLocation.uLength = location->uLength;
+ originalLocation.pData = location->pData;
+
+ found = HttpString_nextToken(nameToken, tokenlenLen, *location);
+
+ // Missing header name
+ if (found == 0)
+ return 0;
+ else
+ {
+ location->uLength = originalLocation.uLength - (uint16)(found - originalLocation.pData) - (tokenlenLen + 2);
+ location->pData = found + tokenlenLen + 2;
+ // Return the value pointer and size
+ if (value == NULL)
+ {
+ *outValue= (char*)location->pData;
+ nameToken = (char *)location->pData;
+ found = HttpString_nextToken(HTTP_DELIMITER_QUOTE, sizeof(HTTP_DELIMITER_QUOTE) - 1, *location);
+ if (found==0)
+ found = HttpString_nextToken(HTTP_DELIMITER_COMMA, sizeof(HTTP_DELIMITER_COMMA) - 1, *location);
+
+ // Restore current location
+ location->uLength = originalLocation.uLength;
+ location->pData = originalLocation.pData;
+ return (uint16)((char *)found - nameToken);
+ }
+
+ found = HttpString_nextToken(value, valuelen, *location);
+ // Value does not match - restore location
+ if (found == 0)
+ {
+ location->uLength = originalLocation.uLength;
+ location->pData = originalLocation.pData;
+ return 0;
+ }
+
+ // Restore location
+ location->uLength = originalLocation.uLength;
+ location->pData = originalLocation.pData;
+ return 1;
+ }
+}
+
+
+void HttpAuth_RequestAuthenticate(struct HttpRequest* pRequest, struct HttpBlob authorization)
+{
+ uint8 ha2[DIGEST_AUTHENTICATION_BUFFER_SIZE], correctResponse[DIGEST_AUTHENTICATION_BUFFER_SIZE];
+ struct HttpBlob currentLocation, blob;
+ // HA1 was not copmuted
+ if ((uint32)*g_authState.ha1 == 0)
+ {
+ return;
+ }
+
+ // Parse the header - find relevant tokens and handle
+ currentLocation.pData = authorization.pData;
+ currentLocation.uLength = authorization.uLength;
+
+ // Verify the mandatory tokens, whose content we ignore are present
+
+ // verify we are in degest authentication method, any other is not supported
+ if (HttpString_nextToken(HTTP_AUTHENTICATE_DIGEST, sizeof(HTTP_AUTHENTICATE_DIGEST)-1, currentLocation) == 0)
+ return;
+
+ // verify username exists
+ if (HttpString_nextToken(HTTP_AUTHENTICATE_USERNAME, sizeof(HTTP_AUTHENTICATE_USERNAME)-1, currentLocation) == 0)
+ return;
+
+ // Verify realm
+ if (HttpAuth_VerifyHeaderNameValue(¤tLocation, HTTP_AUTHENTICATE_REALM, sizeof(HTTP_AUTHENTICATE_REALM)-1, HTTP_AUTH_REALM, sizeof(HTTP_AUTH_REALM)-1, 0) != 1)
+ return;
+
+ // Verify correct nonce
+ if (HttpAuth_VerifyHeaderNameValue(¤tLocation, HTTP_AUTHENTICATE_NONCE, sizeof(HTTP_AUTHENTICATE_NONCE)-1, (char *)g_authState.nonce, DIGEST_AUTHENTICATION_BUFFER_SIZE, 0) != 1)
+ return;
+
+ // Verify correct opaque
+ if (HttpAuth_VerifyHeaderNameValue(¤tLocation, HTTP_AUTHENTICATE_OPAQUE, sizeof(HTTP_AUTHENTICATE_OPAQUE)-1, (char *)g_authState.opaque, DIGEST_AUTHENTICATION_BUFFER_SIZE, 0) != 1)
+ return;
+
+ // Find neccessary tokents and compute HA2 if some tokens are not found - return
+ blob.pData = NULL;
+ blob.uLength = HttpAuth_VerifyHeaderNameValue(¤tLocation, HTTP_AUTHENTICATE_URI, sizeof(HTTP_AUTHENTICATE_URI)-1, 0, 0, (char**)&blob.pData);
+ // Uri is missing
+ if (blob.uLength == 0)
+ return;
+
+ MD5_Init(&MD5state);
+ if ((pRequest->uFlags & HTTP_REQUEST_FLAG_METHOD_POST) != 0)
+ MD5_Update(&MD5state, (unsigned char*)"POST", 4);
+ else
+ MD5_Update(&MD5state, (unsigned char*)"GET", 3);
+ MD5_Update(&MD5state, (unsigned char*)":", 1);
+ MD5_Update(&MD5state, blob.pData, blob.uLength);
+ MD5_FinalToString(ha2, &MD5state);
+
+ // Find tokens to compute correct response
+ blob.pData = HttpString_nextToken(HTTP_AUTHENTICATE_NC, sizeof(HTTP_AUTHENTICATE_NC)-1, currentLocation);
+ // Ncount is missing
+ if (blob.pData == 0)
+ return;
+ blob.pData += sizeof(HTTP_AUTHENTICATE_NC) - 1;
+ blob.uLength = 8;
+
+ MD5_Init(&MD5state);
+ MD5_Update(&MD5state, g_authState.ha1, DIGEST_AUTHENTICATION_BUFFER_SIZE);
+ MD5_Update(&MD5state, (unsigned char*)":", 1);
+ MD5_Update(&MD5state, g_authState.nonce, DIGEST_AUTHENTICATION_BUFFER_SIZE);
+ MD5_Update(&MD5state, (unsigned char*)":", 1);
+ MD5_Update(&MD5state, blob.pData, blob.uLength);
+
+ blob.pData = NULL;
+ blob.uLength = HttpAuth_VerifyHeaderNameValue(¤tLocation, HTTP_AUTHENTICATE_CNONCE, sizeof(HTTP_AUTHENTICATE_CNONCE)-1, 0, 0, (char **)&blob.pData);
+ // Cnonce is missing
+ if (blob.uLength == 0)
+ return;
+ MD5_Update(&MD5state, (unsigned char*)":", 1);
+ MD5_Update(&MD5state, blob.pData, blob.uLength);
+ MD5_Update(&MD5state, (unsigned char*)":auth:", 6);
+ MD5_Update(&MD5state, ha2, DIGEST_AUTHENTICATION_BUFFER_SIZE);
+ MD5_FinalToString(correctResponse, &MD5state);
+
+ // Compare received response to the one computed locally - if equal then authorize
+ blob.pData = NULL;
+ blob.uLength = HttpAuth_VerifyHeaderNameValue(¤tLocation, HTTP_AUTHENTICATE_RESPONSE, sizeof(HTTP_AUTHENTICATE_RESPONSE)-1, 0, 0, (char **)&blob.pData);
+ // Response is missing
+ if (blob.uLength != DIGEST_AUTHENTICATION_BUFFER_SIZE)
+ return;
+
+ currentLocation.pData = correctResponse;
+ currentLocation.uLength = DIGEST_AUTHENTICATION_BUFFER_SIZE;
+ // if the responses are equal
+ if (HttpString_strcmp(blob, currentLocation) == 0)
+ pRequest->uFlags |= HTTP_REQUEST_FLAG_AUTHENTICATED;
+
+}
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/HttpAuth.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,92 @@
+/*****************************************************************************
+*
+* HttpAuth.h
+* 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 _HTTP_AUTH_H_
+#define _HTTP_AUTH_H_
+
+#include "HttpConfig.h"
+#include "HttpString.h"
+#include "HttpRequest.h"
+#ifdef HTTP_CORE_ENABLE_AUTH
+
+/**
+ * @defgroup HttpAuth HTTP Authentication
+ * This module implements the HTTP digest access authentication routines.
+ * Note this module is only compiled if HTTP_CORE_ENABLE_AUTH is defined in HttpConfig.h
+ *
+ * When a "not authorized" response is sent to the client, the WWW-Authenticate header is built using HttpAuth_ResponseAuthenticate()
+ * This in turn generates new nonce and opaque values which will be used for authentication.
+ * Note that since only a single nonce is kept, only one client may ever be authenticated simultaneously.
+ * When another request with Authorization header is received, it is verified using HttpAuth_RequestAuthenticate()
+ * If all authentication tests pass, then the appropriate flag is set in the request to indicate that.
+ *
+ * @{
+ */
+
+/**
+ * Initialize the authentication module, so that it accepts the specified username and password
+ * This function should be called during server initialization in order to set initial user credentials
+ * This function may then be called at any time during the operation of the server in order to set different user credentials
+ * @param username The authorized user's username
+ * @param password The authorized user's password
+ */
+void HttpAuth_Init(struct HttpBlob username, struct HttpBlob password);
+
+/**
+ * Builds and returns the WWW-Authenticate response header.
+ * This implies generating a new nonce, etc.
+ * Notes about return value:
+ * Upon entry, pWWWAuthenticate should point to the place in the packet-send buffer where the header needs to be generated, and also specify the maximum amount of bytes available for the header at that place
+ * Upon return, pWWWAuthenticate points to the same location, but specifies the actual length of the header.
+ * If the returned length is 0, this means that there was not enough room in the buffer for the header.
+ * In such a case, the core may try again with a larger buffer
+ * @param pRequest All data about the request
+ * @param[in,out] pWWWAuthenticate On entry specifies the memory location to build the header at, and the maximum size. On return, specifies the same location and the actual size of the header line
+ */
+void HttpAuth_ResponseAuthenticate(struct HttpRequest* pRequest, struct HttpBlob* pWWWAuthenticate);
+
+/**
+ * Check the authentication header in a request, and either authorize the request or deny it
+ * If the authorization succeeds, then HTTP_REQUEST_FLAG_AUTHENTICATED is added to the request flags
+ * @param pRequest All data about the request to authorize
+ * @param authorization The full string of the Authorization header
+ */
+void HttpAuth_RequestAuthenticate(struct HttpRequest* pRequest, struct HttpBlob authorization);
+
+/// @}
+
+#endif // HTTP_CORE_ENABLE_AUTH
+
+#endif // _HTTP_AUTH_H_
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/HttpConfig.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,58 @@
+/*****************************************************************************
+*
+* HttpConfig.h
+* 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 _HTTP_CONFIG_H_
+#define _HTTP_CONFIG_H_
+
+/**
+ * @defgroup HttpConfig HTTP Server compile-time configuration options
+ * This header file contains various compile-time options for the server
+ *
+ * @{
+ */
+
+/// Use HttpStatic module for static content
+#define HTTP_CORE_ENABLE_STATIC
+/// Use HttpDynamic module for dynamic content
+#define HTTP_CORE_ENABLE_DYNAMIC
+/// Use HttpAuth for HTTP digest-access authentication
+#define HTTP_CORE_ENABLE_AUTH
+/// Use HttpDebug module to generate debug traces
+//#define HTTP_CORE_ENABLE_DEBUG
+
+
+/// @}
+
+#endif //_HTTP_CONFIG_H_
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/HttpCore.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,1258 @@
+/*****************************************************************************
+*
+* HttpCore.c
+* 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.
+*
+*****************************************************************************/
+#include "mbed.h"
+#include "Common.h"
+#include "HttpHeaders.h"
+#include "HttpCore.h"
+#include "HttpResponse.h"
+#include "HttpRequest.h"
+#include "HttpAuth.h"
+#include "HttpDebug.h"
+#include "HttpDynamic.h"
+#include "HttpStatic.h"
+#include <string.h>
+#include "HttpConfig.h"
+
+// Include CC3000 bridged networking stack headers
+#include "cc3000_common.h"
+#include "socket.h"
+#include "netapp.h"
+#include "FlashDB.h"
+
+/**
+ * @addtogroup HttpCore
+ * @{
+ */
+
+
+/**
+ * This enumeration defines all possible states for a connection
+ */
+enum HttpConnectionState
+{
+ /// Connection is inactive. The connection's socket should be INVALID_SOCKET_HANDLE
+ Inactive,
+ /// Waiting for packet(s) with the request method
+ RequestMethod,
+ /// Waiting for packet(s) with request headers
+ RequestHeaders,
+ /// Currently receiving a header which is too long - Drop it and continue waiting for more headers
+ DropCurrentHeader,
+ /// Done parsing headers, waiting for POST data pakcets
+ RequestData,
+ /// Request is at the hands of the content module (static and/or dynamic), waiting for response headers.
+ Processing,
+ /// Response headers have been sent. Sending response content.
+ ResponseData,
+ /// Response complete. Possibility of another request.
+ ResponseComplete
+};
+
+/**
+ * This enumeration defines all possible request-handler modules
+ */
+enum HttpHandler
+{
+ /// No module is going to process this request (use the default 404 error)
+ None,
+ /// The HttpStatic module is going to process this request
+ HttpStatic,
+ /// The HttpDynamic module is going to process this request
+ HttpDynamic
+};
+
+/**
+ * This structure holds all information for an HTTP connection
+ */
+//#ifdef __CCS__
+//struct __attribute__ ((__packed__)) HttpConnectionData
+//#elif __IAR_SYSTEMS_ICC__
+//#pragma pack(1)
+struct HttpConnectionData
+//#endif
+{
+ /// The state of this connection
+ enum HttpConnectionState connectionState;
+ /// The data socket for this connection. Should be INVALID_SOCKET_HANDLE when in Inactive state
+ SOCKET dataSocket;
+ /// The current HTTP request on this connection
+ struct HttpRequest request;
+ /// Which handler is going to process the current request
+ enum HttpHandler handler;
+ /// An un-parsed chunk of header line
+ uint8 headerStart[HTTP_CORE_MAX_HEADER_LINE_LENGTH];
+ /// Amount of content left to be read in the request or sent in the response
+ uint32 uContentLeft;
+ /// If the headers will arrive in several packets the content will be buffered in the headers start buffer until a whole line is available
+ uint16 uSavedBufferSize;
+ /// Check weather the authentication is done or not
+ uint8 HttpAuth;
+};
+
+/**
+ * This structure holds all of the global state of the HTTP server
+ */
+//#ifdef __CCS__
+//struct __attribute__ ((__packed__)) HttpGlobalState
+//#elif __IAR_SYSTEMS_ICC__
+//#pragma pack(1)
+struct HttpGlobalState
+//#endif
+{
+ /// The listening socket
+ SOCKET listenSocket;
+ /// Number of active connections
+ uint16 uOpenConnections;
+ /// All possible connections
+ struct HttpConnectionData connections[HTTP_CORE_MAX_CONNECTIONS];
+ /// The packet-receive buffer
+ uint8 packetRecv[HTTP_CORE_MAX_PACKET_SIZE_RECEIVED];
+ /// Size of data in the packet-receive buffer
+ int packetRecvSize;
+ /// The packet-send buffer
+ uint8 packetSend[HTTP_CORE_MAX_PACKET_SIZE_SEND];
+ /// Size of data in the packet-send buffer
+ uint16 packetSendSize;
+};
+
+/// The global state of the HTTP server
+__no_init struct HttpGlobalState g_state;
+
+// Forward declarations for static functions
+static void HttpCore_InitWebServer();
+static void HttpCore_CloseConnection(uint16 uConnection);
+static int HttpCore_HandleRequestPacket(uint16 uConnection, struct HttpBlob packet);
+static int HttpCore_HandleMethodLine(uint16 uConnection, struct HttpBlob line);
+static int HttpCore_HandleHeaderLine(uint16 uConnection, struct HttpBlob line);
+static int HttpCore_HandleRequestData(uint16 uConnection, struct HttpBlob* pData);
+static void HttpCore_ProcessNotFound(uint16 uConnection);
+
+struct HttpBlob nullBlob = {NULL, 0};
+
+extern volatile char runSmartConfig;
+extern char DevServname[];
+extern unsigned char mDNSSend;
+extern char CheckSocket;
+extern signed char sd[];
+
+#define MAX_SENT_DATA 912
+
+/**
+ * Detect all error conditions from a sockets API return value, such as accpet()
+ * Note: This is different in Windows and CC3000
+ * Returns nonzero if valid socket, or zero if invalid socket
+ */
+static int HttpIsValidSocket(SOCKET sock)
+{
+#if (defined(WIN32) && !defined(HTTP_WEB_SERVER_ON_BRIDGE))
+ // The CC3000 API returns an int, and might return CC3000_INVALID_SOCKET
+ if ((sock == INVALID_SOCKET) ||
+ (sock == CC3000_INVALID_SOCKET))
+ return 0;
+#else
+ if (sock < 0)
+ return 0;
+#endif
+ return 1;
+}
+
+void HttpCloseServer()
+{
+ closesocket(g_state.listenSocket);
+}
+
+void HttpServerInitAndRun()
+{
+ uint16 uConnection;
+ sockaddr_in addr;
+ sockaddr_in clientAddr;
+ socklen_t addrLen = sizeof(clientAddr);
+ struct HttpBlob blob;
+ fd_set readsds, errorsds;
+ int ret = 0;
+ SOCKET maxFD;
+ timeval timeout;
+ signed char curSocket;
+ int optval, optlen;
+
+ memset(&timeout, 0, sizeof(timeval));
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+
+ // Initialize the server's global state
+ HttpCore_InitWebServer();
+
+ // Create the listener socket for HTTP Server.
+ g_state.listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if(g_state.listenSocket == INVALID_SOCKET)
+ {
+ HttpDebug("Failed to create listen socket");
+ printf("Failed to create listen socket\r\n");
+ return;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+#ifdef _WINSOCKAPI_
+ addr.sin_family = AF_INET;
+#else
+ addr.sin_family = htons(AF_INET);
+#endif
+ addr.sin_port = htons(HTTP_CORE_SERVER_PORT);
+ if (bind(g_state.listenSocket, (const sockaddr*)&addr, sizeof(addr)) != 0)
+ {
+ HttpDebug("bind() fail");
+ printf("bind() fail\r\n");
+ return;
+ }
+ if (listen(g_state.listenSocket, 10) != 0)
+ {
+ HttpDebug("listen() fail");
+ printf("listen() fail\r\n");
+ return;
+ }
+
+#ifdef HTTP_CORE_ENABLE_AUTH
+ struct HttpBlob user,pass;
+ user.pData = (uint8*)"cc3000";
+ user.uLength= 6;
+ pass.pData = (uint8*)"admin";
+ pass.uLength = 5;
+ int count;
+
+ HttpAuth_Init(user, pass);
+#endif
+
+ g_state.uOpenConnections = 0;
+
+ // Main loop of the server. Note: This is an infinite loop
+ while (1)
+ {
+ //printf("Server Loop...\r\n");
+ // Check if button is pressed for smart config
+ if(runSmartConfig == 1)
+ {
+ // Button is pressed for smart config. Close all active connections
+ for(uConnection = 0; uConnection < HTTP_CORE_MAX_CONNECTIONS; ++uConnection)
+ {
+ if (g_state.connections[uConnection].connectionState != Inactive)
+ {
+ HttpCore_CloseConnection(uConnection);
+ }
+ }
+
+ // Close listening socket
+ HttpCloseServer();
+ break;
+ }
+ if( mDNSSend ==1)
+ {
+ mdnsAdvertiser(1,DevServname, strlen(DevServname));
+ mDNSSend =0;
+ }
+
+ // Client socket is closed, close socket
+ if(CheckSocket == 1)
+ {
+ for(count = 0; count<9 ; count++)
+ {
+ if(sd[count] == 1)
+ {
+ HttpCore_CloseConnection(count);
+ sd[count] = 0;
+ }
+ }
+ for(uConnection = 0; uConnection < HTTP_CORE_MAX_CONNECTIONS; ++uConnection)
+ {
+ if (g_state.connections[uConnection].connectionState != Inactive)
+ {
+ // Check for socket timeouts
+ curSocket = getsockopt(g_state.connections[uConnection].dataSocket, SOL_SOCKET, SOCKOPT_RECV_NONBLOCK , &optval, (socklen_t*)&optlen);
+ if (curSocket == -57)
+ {
+ HttpCore_CloseConnection(uConnection);
+ }
+ }
+ }
+ CheckSocket = 0;
+ }
+
+ SOCKET newsock;
+
+ newsock = accept(g_state.listenSocket, (sockaddr*)&clientAddr, &addrLen);
+
+ // If new connection is returned - initialize the new connection object
+ if (HttpIsValidSocket(newsock))
+ {
+ if (g_state.uOpenConnections >= HTTP_CORE_MAX_CONNECTIONS)
+ {
+ //check if sockets are are available
+ for(uConnection = 0; uConnection < HTTP_CORE_MAX_CONNECTIONS; ++uConnection)
+ {
+ if (g_state.connections[uConnection].connectionState != Inactive)
+ {
+ //Check for Socket Timeout
+ curSocket = getsockopt(g_state.connections[uConnection].dataSocket, SOL_SOCKET, SOCKOPT_RECV_NONBLOCK , &optval, (socklen_t*)&optlen);
+ if (curSocket == -57)
+ {
+ HttpCore_CloseConnection(uConnection);
+ }
+ }
+ }
+ }
+
+ if(g_state.uOpenConnections < HTTP_CORE_MAX_CONNECTIONS)
+ {
+ for (uConnection = 0; uConnection < HTTP_CORE_MAX_CONNECTIONS; ++uConnection)
+ if (g_state.connections[uConnection].connectionState == Inactive)
+ break;
+
+ g_state.connections[uConnection].dataSocket = newsock;
+ g_state.uOpenConnections++;
+ g_state.connections[uConnection].connectionState = RequestMethod;
+ HttpDebug("Accepting new connection number %d", uConnection);
+ printf("Accepting new connection number %i\r\n", uConnection);
+ }
+ }
+
+
+
+
+ // Nothing more to do if no open connections
+ if (g_state.uOpenConnections == 0)
+ continue;
+
+ // Receive data on all open connections, and handle the new data
+ maxFD = (SOCKET)-1;
+ // Select only the active connections
+ FD_ZERO(&readsds);
+ FD_ZERO(&errorsds);
+ for (uConnection = 0; uConnection < HTTP_CORE_MAX_CONNECTIONS; ++uConnection)
+ {
+ // if connection is open and in one of the receiving states, then add this socket to the set
+ if (g_state.connections[uConnection].connectionState == RequestMethod ||
+ g_state.connections[uConnection].connectionState == RequestHeaders ||
+ g_state.connections[uConnection].connectionState == RequestData ||
+ g_state.connections[uConnection].connectionState == DropCurrentHeader)
+ {
+ FD_SET(g_state.connections[uConnection].dataSocket, &readsds);
+ FD_SET(g_state.connections[uConnection].dataSocket, &errorsds);
+ // Calculate the maximum socket number
+ if (maxFD <= g_state.connections[uConnection].dataSocket)
+ maxFD = g_state.connections[uConnection].dataSocket + 1;
+ }
+ }
+
+ ret = select(maxFD, &readsds, NULL, &errorsds, &timeout);
+
+ // Nothing more to do if no packet received
+ if (ret == 0)
+ {
+ continue;
+ }
+
+ for (uConnection = 0; uConnection < HTTP_CORE_MAX_CONNECTIONS; ++uConnection)
+ {
+ // Skip inactive connections
+ if (g_state.connections[uConnection].connectionState == Inactive)
+ continue;
+
+ // Close connections that were select()ed for error
+ if (FD_ISSET(g_state.connections[uConnection].dataSocket, &errorsds))
+ {
+ HttpCore_CloseConnection(uConnection);
+ continue;
+ }
+
+ // Skip connections that were not select()ed for reading
+ if (!FD_ISSET(g_state.connections[uConnection].dataSocket, &readsds))
+ continue;
+
+ // This connection has data that can be received now
+
+ // Receive the data into the global packet-receive buffer
+ memset(g_state.packetRecv, 0, HTTP_CORE_MAX_PACKET_SIZE_RECEIVED);
+ g_state.packetRecvSize = recv(g_state.connections[uConnection].dataSocket, (char *)(g_state.packetRecv), HTTP_CORE_MAX_PACKET_SIZE_RECEIVED, 0);
+
+ // Detect and handle errors
+ if (g_state.packetRecvSize <= 0)
+ {
+ HttpDebug("HTTP Connection recv error. connection=%d, error = %d", uConnection, g_state.packetRecvSize);
+ printf("HTTP Connection recv error. connection=%i, error = %i\r\n", uConnection, g_state.packetRecvSize);
+ HttpCore_CloseConnection(uConnection);
+ continue;
+ }
+
+ blob.uLength = (uint16)g_state.packetRecvSize;
+ blob.pData = g_state.packetRecv;
+ if (!HttpCore_HandleRequestPacket(uConnection, blob))
+ HttpCore_CloseConnection(uConnection);
+ }
+ }
+}
+
+/**
+ * Reset open connection after finishing HTPP transaction
+ */
+static void HttpCore_ResetConnection(uint16 uConnection)
+{
+ g_state.connections[uConnection].uContentLeft = 0;
+ g_state.connections[uConnection].uSavedBufferSize = 0;
+ g_state.connections[uConnection].handler = None;
+ g_state.connections[uConnection].request.requestContent.pData = NULL;
+ g_state.connections[uConnection].request.requestContent.uLength = 0;
+ g_state.connections[uConnection].request.uFlags = 0;
+}
+
+/**
+ * Initialize the server's global state structure
+ */
+static void HttpCore_InitWebServer()
+{
+ uint16 uConnection;
+ g_state.packetRecvSize = 0;
+ g_state.packetSendSize = 0;
+ g_state.uOpenConnections = 0;
+ g_state.listenSocket = INVALID_SOCKET;
+
+ for (uConnection = 0; uConnection < HTTP_CORE_MAX_CONNECTIONS; ++uConnection)
+ {
+ g_state.connections[uConnection].connectionState = Inactive;
+ g_state.connections[uConnection].dataSocket = INVALID_SOCKET;
+ g_state.connections[uConnection].request.uConnection = uConnection;
+ g_state.connections[uConnection].HttpAuth = 0;
+ HttpCore_ResetConnection(uConnection);
+ }
+
+ FlashDB_Init();
+}
+
+
+/**
+ * Close a connection and clean up its state
+ */
+static void HttpCore_CloseConnection(uint16 uConnection)
+{
+ HttpDebug("Close connection");
+ printf("Close connection\r\n");
+
+ closesocket(g_state.connections[uConnection].dataSocket);
+
+ g_state.connections[uConnection].connectionState = Inactive;
+ g_state.connections[uConnection].dataSocket = INVALID_SOCKET;
+ g_state.connections[uConnection].HttpAuth = 0;
+ HttpCore_ResetConnection(uConnection);
+ if(g_state.uOpenConnections > 0)
+ g_state.uOpenConnections--;
+}
+
+/**
+ * Getting the next line in the HTTP headers section
+ * This function is called to get the header lines one by one until an empty line is encountered which means the end of the header section
+ * The input is the connection and the remaining blob of the received packet
+ *
+ * @return zero if the whole packet was handled, and need to wait for more data (pLine is not set to anything yet)
+ * negative if some error occurred, and the connection should be closed.
+ * positive if successful. In this case pCurrentLocation is advanced to skip the line and pLine returns the next line, or NULL and 0 if it should be discarded
+ */
+static int HttpCore_GetNextLine(uint16 uConnection, struct HttpBlob* pCurrentLocation, struct HttpBlob* pLine)
+{
+ uint16 uLength;
+ uint8* nextLocation;
+ // Keep a pointer to the connection state object
+ struct HttpConnectionData* pConnection = &g_state.connections[uConnection];
+
+ // search for the line delimiter in the received data
+ nextLocation = HttpString_nextToken(HTTP_HEADER_DELIMITER, sizeof(HTTP_HEADER_DELIMITER)-1, *pCurrentLocation);
+ uLength = (uint16)(nextLocation - pCurrentLocation->pData);
+
+ if (pConnection->uSavedBufferSize > 0)
+ {
+ // There is previous saved data for this line, so need to concatenate
+ if ((pConnection->headerStart[pConnection->uSavedBufferSize - 1] == '\r') && (pCurrentLocation->pData[0] == '\n'))
+ {
+ // Handle special case where the headers were splitted exactly at the delimiter
+ pConnection->headerStart[pConnection->uSavedBufferSize + 1] = pCurrentLocation->pData[0];
+ pLine->pData = pConnection->headerStart;
+ // Account for the excessive \r in the buffer
+ pLine->uLength = pConnection->uSavedBufferSize - 1;
+ pConnection->uSavedBufferSize = 0;
+ // Advance the current location past this line
+ pCurrentLocation->pData += 1;
+ pCurrentLocation->uLength -= 1;
+ return 1;
+ }
+ else
+ {
+ // There is saved data, and the delimiter is not split between packets
+ if (nextLocation == NULL)
+ {
+ // No line delimiter was found in the current packet
+ if ((pConnection->uSavedBufferSize + pCurrentLocation->uLength) < HTTP_CORE_MAX_HEADER_LINE_LENGTH)
+ {
+ // There is enough space to append remaining header into saved buffer
+ memcpy(pConnection->headerStart + pConnection->uSavedBufferSize, pCurrentLocation->pData, pCurrentLocation->uLength);
+ pConnection->uSavedBufferSize += pCurrentLocation->uLength;
+ return 0;
+ }
+ else
+ // There is not enough space in the saved buffer. This header line will be discarded
+ if (pConnection->connectionState == RequestMethod)
+ {
+ // Connection awaits to receive the the HTTP method line
+ // The method line cannot be discarded, drop the connection
+ return -1;
+ }
+ else
+ {
+ // Connection awaits to receive the next header line which is not the method
+ // Clean saved buffer, and drop this header line
+ pConnection->uSavedBufferSize = 0;
+ pConnection->connectionState = DropCurrentHeader;
+ return 0;
+ }
+ }
+ else
+ {
+ // Header line delimiter was found in the current packet
+ if ((pConnection->uSavedBufferSize + uLength) < HTTP_CORE_MAX_HEADER_LINE_LENGTH)
+ {
+ // This header length is of legal size
+ // Concatenate data from the saved buffer and the current packet
+ memcpy(pConnection->headerStart + pConnection->uSavedBufferSize, pCurrentLocation->pData, uLength);
+ pConnection->uSavedBufferSize += uLength;
+ pLine->pData = pConnection->headerStart;
+ pLine->uLength = pConnection->uSavedBufferSize;
+ pConnection->uSavedBufferSize = 0;
+ }
+ else
+ {
+ // There is not enough space in the saved buffer. This header line will be discarded
+ if (pConnection->connectionState == RequestMethod)
+ {
+ // Connection awaits to receive the the HTTP method line
+ // The method line cannot be discarded, drop the connection
+ return -1;
+ }
+ // Return an epmty line since the header is too long
+ pLine->pData = NULL;
+ pLine->uLength = 0;
+ }
+ // Advance the current location past this line
+ pCurrentLocation->pData += uLength + sizeof(HTTP_HEADER_DELIMITER)-1;
+ pCurrentLocation->uLength -= uLength + sizeof(HTTP_HEADER_DELIMITER)-1;
+ return 1;
+
+ }
+ }
+ }
+ else
+ {
+ // There is no previously saved data for this line
+ if (nextLocation == NULL)
+ {
+ // No line delimiter was found in the current packet
+ if (pCurrentLocation->uLength < HTTP_CORE_MAX_HEADER_LINE_LENGTH)
+ {
+ // There is enough space to append remaining header into saved buffer
+ memcpy(pConnection->headerStart, pCurrentLocation->pData, pCurrentLocation->uLength);
+ pConnection->uSavedBufferSize = pCurrentLocation->uLength;
+ return 0;
+ }
+ else
+ // There is not enough space in the saved buffer
+ // This header line will be discarded
+ if (pConnection->connectionState == RequestMethod)
+ {
+ // Connection awaits to receive the the HTTP method line
+ // The method line cannot be discarded, drop the connection
+ return -1;
+ }
+ else
+ {
+ // Connection awaits to receive the next header line which is not the method
+ // Clean saved buffer, and drop this header line
+ pConnection->uSavedBufferSize = 0;
+ pConnection->connectionState = DropCurrentHeader;
+ return 0;
+ }
+ }
+ else
+ {
+ // Header line delimiter was found in the current packet
+ if (uLength < HTTP_CORE_MAX_HEADER_LINE_LENGTH)
+ {
+ // This header length is of legal size
+ // The whole line is in the packet buffer
+ pLine->pData = pCurrentLocation->pData;
+ pLine->uLength = uLength;
+ }
+ else
+ {
+ // There is not enough space to append remaining header into saved buffer
+ if (pConnection->connectionState == RequestMethod)
+ {
+ // Connection awaits to receive the HTTP method line
+ // The method line cannot be discarded, drop the connection
+ return -1;
+ }
+ // Return an epmty line since the header is too long
+ pLine->pData = NULL;
+ pLine->uLength = 0;
+ pConnection->connectionState = DropCurrentHeader;
+ }
+ // Advance the current location past this line
+ pCurrentLocation->pData += uLength + sizeof(HTTP_HEADER_DELIMITER)-1;
+ pCurrentLocation->uLength -= uLength + sizeof(HTTP_HEADER_DELIMITER)-1;
+ return 1;
+ }
+ }
+}
+
+
+/**
+ * The main state machine to handle an HTTP transaction
+ * Every received data packet for a connection is passed to this function for parsing and handling
+ *
+ * If there is an error the connection will be closed in the end of the transaction
+ * It will also be closed if "connection: close" header is received or HTTP version is 1.0
+ *
+ * @return zero to close the connection
+ * nonzero if packet was consumed successfully, and the connection can handle more data
+ */
+static int HttpCore_HandleRequestPacket(uint16 uConnection, struct HttpBlob packet)
+{
+ struct HttpBlob currentLocation, line;
+ int ret;
+
+ currentLocation.pData = packet.pData;
+ currentLocation.uLength = packet.uLength;
+
+ // when no more data is left and the HTTP transaction is not complete then return to wait for more data
+ while (1)
+ {
+ if (g_state.connections[uConnection].connectionState == RequestMethod ||
+ g_state.connections[uConnection].connectionState == RequestHeaders ||
+ g_state.connections[uConnection].connectionState == DropCurrentHeader)
+ {
+ // Parsing HTTP headers
+ int result;
+
+ // The received blob is empty, return to wait for more data
+ if (currentLocation.uLength < 1)
+ {
+ return 1;
+ }
+
+ // Get next header line if available
+ result = HttpCore_GetNextLine(uConnection, ¤tLocation, &line);
+
+ // Method line is too long, or some other error
+ if (result < 0)
+ return 0;
+
+ // Whole packet was consumed, and no line-break found. Wait for more data
+ if (result == 0)
+ return 1;
+
+ // Otherwise a new and legal header line is found
+ }
+
+ switch (g_state.connections[uConnection].connectionState)
+ {
+ case DropCurrentHeader:
+ g_state.connections[uConnection].connectionState = RequestHeaders;
+ break;
+ case RequestMethod:
+ //HttpAssert((line.pData != NULL) && (line.uLength > 0));
+ // If there is an error, then return error to drop the connection
+ if (!HttpCore_HandleMethodLine(uConnection, line))
+ return 0;
+ break;
+ case RequestHeaders:
+ if (!HttpCore_HandleHeaderLine(uConnection, line))
+ return 0;
+ break;
+ case RequestData:
+ ret = HttpCore_HandleRequestData(uConnection, ¤tLocation);
+ if (ret == 0)
+ return 1;
+ else
+ if (ret < 0)
+ return 0;
+ break;
+ case Processing:
+ // All the request data was received - start final processing of the headers and post data if exists
+ switch (g_state.connections[uConnection].handler)
+ {
+#ifdef HTTP_CORE_ENABLE_STATIC
+ case HttpStatic:
+ HttpStatic_ProcessRequest(&g_state.connections[uConnection].request);
+ break;
+#endif
+#ifdef HTTP_CORE_ENABLE_DYNAMIC
+ case HttpDynamic:
+ HttpDynamic_ProcessRequest(&g_state.connections[uConnection].request);
+ break;
+#endif
+ default:
+ HttpCore_ProcessNotFound(uConnection);
+ break;
+ }
+ break;
+ case ResponseData:
+ // This state should never be reached, it is set internally during the processing
+ HttpDebug("Response data state in request handling main loop!");
+ printf("Response data state in request handling main loop!\r\n");
+ HttpAssert(0);
+ break;
+ case ResponseComplete:
+ if ((g_state.connections[uConnection].request.uFlags & HTTP_REQUEST_FLAG_CLOSE)!=0 ||
+ (g_state.connections[uConnection].request.uFlags & HTTP_REQUEST_1_1) == 0)
+ {
+ // Connection should be closed - either "Connection: close" was received or the HTTP version is 1.0
+ // Return 0 to close the connection
+ return 0;
+ }
+ // The current HTTP transaction is complete - reset state for the next transaction on this connection
+ g_state.connections[uConnection].connectionState = RequestMethod;
+ HttpCore_ResetConnection(uConnection);
+ break;
+ default:
+ HttpDebug("Bad state in HttpCore!");
+ printf("Bad state in HttpCore!\r\n");
+ //HttpAssert(0);
+ break;
+ }
+ }
+}
+
+/**
+ * This function handles connection initial state
+ * Parse the first header line as a method header
+ *
+ * Method line should be in the form:
+ * GET /resource.html HTTP/1.1\r\n
+ *
+ * @return nonzero if success
+ */
+static int HttpCore_HandleMethodLine(uint16 uConnection, struct HttpBlob line)
+{
+ struct HttpBlob resource;
+ uint8* methodLocation;
+ uint8* versionLocation;
+ uint16 uMethodLength;
+ // Search for GET token in the input blob
+ methodLocation = HttpString_nextToken(HTTP_METHOD_GET, sizeof(HTTP_METHOD_GET)-1, line);
+ uMethodLength = sizeof(HTTP_METHOD_GET)-1;
+ if (methodLocation == NULL)
+ {
+ // The method is not GET
+ // Search for the POST token in the input blob
+ methodLocation = HttpString_nextToken(HTTP_METHOD_POST, sizeof(HTTP_METHOD_POST)-1, line);
+ uMethodLength = sizeof(HTTP_METHOD_POST)-1;
+ g_state.connections[uConnection].request.uFlags |= HTTP_REQUEST_FLAG_METHOD_POST;
+ }
+ else
+ {
+ // Method is GET
+ g_state.connections[uConnection].request.requestContent.uLength = 0;
+ g_state.connections[uConnection].request.uFlags &= ~HTTP_REQUEST_FLAG_METHOD_POST;
+ }
+ if (methodLocation != line.pData)
+ {
+ methodLocation = HttpString_nextToken(HTTP_METHOD_POST, sizeof(HTTP_METHOD_POST)-1, line);
+ uMethodLength = sizeof(HTTP_METHOD_POST)-1;
+ g_state.connections[uConnection].request.uFlags |= HTTP_REQUEST_FLAG_METHOD_POST;
+ if(methodLocation == NULL || methodLocation != line.pData)
+ {
+ // Header does not begin line with GET or POST as it should
+ HttpDebug("Unsupported method");
+ printf("Unsupported method\r\n");
+ return 0;
+ }
+ }
+
+ // Search for "HTTP/1.1" version token
+ versionLocation = HttpString_nextToken(HTTP_VERSION_1P1, sizeof(HTTP_VERSION_1P1)-1, line);
+ // Version is 1.1
+ if (versionLocation != NULL)
+ g_state.connections[uConnection].request.uFlags |= HTTP_REQUEST_1_1;
+ else
+ {
+ // Search for "HTTP/1.1" version token
+ versionLocation = HttpString_nextToken(HTTP_VERSION_1P0, sizeof(HTTP_VERSION_1P0)-1, line);
+ // Version is 1.0
+ if (versionLocation != NULL)
+ g_state.connections[uConnection].request.uFlags &= ~HTTP_REQUEST_1_1;
+ else
+ {
+ HttpDebug("Bad protocol version");
+ printf("Bad protocol version\r\n");
+ return 0;
+ }
+ }
+
+ HttpDebug("method Header: %.*s", line.uLength, line.pData);
+ //printf("method Header: %i , %c\r\n", line.uLength, line.pData);
+ // Find the URL part of the header
+ resource.pData = methodLocation + uMethodLength + 1;
+ resource.uLength = (uint16)(versionLocation - (methodLocation + uMethodLength + 1) - 1);
+
+ // Determine which handler is supposed to handle this request
+ // The handler functions are called according to a hardcoded priority - dynamic, static, default
+ // The first handler that returns non zero will handle this request
+#ifdef HTTP_CORE_ENABLE_DYNAMIC
+ if (HttpDynamic_InitRequest(uConnection, resource) != 0)
+ g_state.connections[uConnection].handler = HttpDynamic;
+ else
+#endif
+#ifdef HTTP_CORE_ENABLE_STATIC
+ if (HttpStatic_InitRequest(uConnection, resource) != 0)
+ g_state.connections[uConnection].handler = HttpStatic;
+ else
+#endif
+ g_state.connections[uConnection].handler = None;
+ g_state.connections[uConnection].connectionState = RequestHeaders;
+ return 1;
+}
+
+/**
+ * Handle The HTTP headers (after method) one by one
+ * If an empty header is received then the headers section is complete
+ * Searches for the headers tokens. If important data is found then it is saved in the connection object
+ *
+ * returns nonzero if sucessful
+ */
+static int HttpCore_HandleHeaderLine(uint16 uConnection, struct HttpBlob line)
+{
+ struct HttpBlob blobValue;
+ uint8* pFound;
+ uint32 length;
+
+ // NULL line is received when a header line is too long.
+ if (line.pData == NULL)
+ return 1;
+
+ // Length is 0, this means than End-Of-Headers marker was reached
+ // State of this connection is set to RequestData
+ if (line.uLength == 0)
+ {
+ g_state.connections[uConnection].connectionState = RequestData;
+ return 1;
+ }
+
+ // If "Accept-encoding" header then set or clear HTTP_REQUEST_FLAG_ACCEPT_GZIP flag
+ if (HttpString_nextToken(HTTP_ACCEPT_ENCODING, sizeof(HTTP_ACCEPT_ENCODING)-1, line))
+ {
+ line.pData += sizeof(HTTP_ACCEPT_ENCODING)-1 + 2;
+ line.uLength -= sizeof(HTTP_ACCEPT_ENCODING)-1 + 2;
+ pFound = HttpString_nextToken(HTTP_GZIP, sizeof(HTTP_GZIP)-1, line);
+ if (pFound != NULL)
+ g_state.connections[uConnection].request.uFlags |= HTTP_REQUEST_FLAG_ACCEPT_GZIP;
+ else
+ g_state.connections[uConnection].request.uFlags &= ~HTTP_REQUEST_FLAG_ACCEPT_GZIP;
+ return 1;
+ }
+
+ // If "Content-Length" header then parse the lenght and set uContentLeft to it
+ // GET and POST method behave the same
+ if (HttpString_nextToken(HTTP_CONTENT_LENGTH, sizeof(HTTP_CONTENT_LENGTH)-1, line) == line.pData)
+ {
+ line.pData += sizeof(HTTP_CONTENT_LENGTH)-1 + 2;
+ line.uLength -= sizeof(HTTP_CONTENT_LENGTH)-1 + 2;
+ blobValue.pData = line.pData;
+ blobValue.uLength = line.uLength - 2;
+ length = HttpString_atou(blobValue);
+ g_state.connections[uConnection].uContentLeft = length;
+ // Set ignore flag
+ if (g_state.connections[uConnection].uContentLeft > HTTP_CORE_MAX_HEADER_LINE_LENGTH)
+ g_state.connections[uConnection].request.uFlags |= HTTP_REQUEST_CONTENT_IGNORED;
+ // Prepare the request blob to buffer the content
+ g_state.connections[uConnection].request.requestContent.pData = g_state.connections[uConnection].headerStart;
+ g_state.connections[uConnection].request.requestContent.uLength = 0;
+ return 1;
+ }
+ // If "Connection" header then look for "close" and set or clear HTTP_REQUEST_FLAG_CLOSE flag
+ // The default behaviour for keep alive or no such header is to keep the connection open in http version 1.1
+ // In http version 1.0 the default behavior is to always close the socket
+ if (HttpString_nextToken(HTTP_CONNECTION_CLOSE, sizeof(HTTP_CONNECTION_CLOSE)-1, line) == line.pData)
+ {
+ line.pData += sizeof(HTTP_CONNECTION_CLOSE)-1 + 2;
+ line.uLength -= sizeof(HTTP_CONNECTION_CLOSE)-1 + 2;
+ pFound = HttpString_nextToken(HTTP_CLOSE, sizeof(HTTP_CLOSE)-1, line);
+ if (pFound != 0)
+ g_state.connections[uConnection].request.uFlags |= HTTP_REQUEST_FLAG_CLOSE;
+ else
+ g_state.connections[uConnection].request.uFlags &= ~HTTP_REQUEST_FLAG_CLOSE;
+ return 1;
+ }
+ // If "Authorization" header the handle authentication
+ if (HttpString_nextToken(HTTP_AUTHORIZATION, sizeof(HTTP_AUTHORIZATION)-1, line) == line.pData)
+ {
+ line.pData += sizeof(HTTP_AUTHORIZATION)-1 + 2;
+ line.uLength -= sizeof(HTTP_AUTHORIZATION)-1 + 2;
+ blobValue.pData = line.pData;
+ blobValue.uLength = line.uLength;
+ //TODO: handle the case when we don't support authentication
+#ifdef HTTP_CORE_ENABLE_AUTH
+ HttpAuth_RequestAuthenticate(&g_state.connections[uConnection].request, blobValue);
+#endif
+ return 1;
+ }
+ // None of the above mentioned headers was recognized so just ignore this header
+ return 1;
+}
+
+/**
+ * Handles request data for this transaction
+ * Behaves the same for POST and GET methods -
+ * If content length header was present then read the content for further processing
+ * If the content is too long then ignore it
+ *
+ * @return 1 if successful, pData is updated to skip the handled data
+ 0 if all data is consumed and need to read more data
+ * negative if an error occurs and the connection should be closed.
+ */
+static int HttpCore_HandleRequestData(uint16 uConnection, struct HttpBlob* pData)
+{
+ uint32 uLengthToHandle;
+
+ if (g_state.connections[uConnection].uContentLeft == 0)
+ {
+ HttpDebug("Received content. Length=%d, content:\r\n%.*s", g_state.connections[uConnection].request.requestContent.uLength, g_state.connections[uConnection].request.requestContent.uLength, g_state.connections[uConnection].headerStart);
+ g_state.connections[uConnection].connectionState = Processing;
+ return 1;
+ }
+
+ // Find minimum between the content left to handle and the current blob
+ uLengthToHandle = g_state.connections[uConnection].uContentLeft;
+ if (uLengthToHandle > pData->uLength)
+ uLengthToHandle = pData->uLength;
+
+ // If no new data is received - return and wait for more
+ if (uLengthToHandle == 0)
+ return 0;
+
+ if ( (g_state.connections[uConnection].request.uFlags & HTTP_REQUEST_CONTENT_IGNORED) != 0)
+ {
+ // Ignore Content
+ pData->pData += uLengthToHandle;
+ pData->uLength -= (uint16)uLengthToHandle;
+ g_state.connections[uConnection].uContentLeft -= uLengthToHandle;
+ }
+ else
+ {
+ // Read content
+ memcpy(g_state.connections[uConnection].headerStart + g_state.connections[uConnection].request.requestContent.uLength, pData->pData, uLengthToHandle);
+ pData->pData += uLengthToHandle;
+ pData->uLength -= (uint16)uLengthToHandle;
+ g_state.connections[uConnection].uContentLeft -= uLengthToHandle;
+ g_state.connections[uConnection].request.requestContent.uLength += (uint16)uLengthToHandle;
+ }
+
+ return 1;
+}
+
+/**
+ * Returns HTTP 404 not found response
+ */
+static void HttpCore_ProcessNotFound(uint16 uConnection)
+{
+ // call HttpResponse_CannedError with 404 NOT_FOUND
+ HttpResponse_CannedError(uConnection, HTTP_STATUS_ERROR_NOT_FOUND);
+}
+
+/**
+ * Sends the input blob over the connection socket
+ */
+static int HttpCore_SendPacket(uint16 uConnection, struct HttpBlob buffer)
+{
+ // Send the buffer over the data socket until all the buffer is sent
+ while (buffer.uLength > 0)
+ {
+ int sent;
+ if(buffer.uLength > MAX_SENT_DATA)
+ {
+ sent = send(g_state.connections[uConnection].dataSocket, (char*)buffer.pData, MAX_SENT_DATA, 0);
+ if (sent <= 0)
+ {
+ printf("Send failed...\r\n");
+ // Connection must be closed if send has failed
+ return 0;
+ }
+ }
+ else
+ {
+ sent = send(g_state.connections[uConnection].dataSocket, (char*)buffer.pData, buffer.uLength, 0);
+ if (sent <= 0)
+ {
+ printf("Send failed...\r\n");
+ // Connection must be closed if send has failed
+ return 0;
+ }
+ }
+ buffer.pData += sent;
+ buffer.uLength -= (uint16)sent;
+ }
+ return 1;
+}
+
+/**
+ * Add char to the response buffer
+ */
+static void HttpResponse_AddCharToResponseHeaders(char ch)
+{
+ //add char
+ g_state.packetSend[g_state.packetSendSize] = ch;
+ g_state.packetSendSize++;
+}
+
+/**
+ * Add uint32 number to the response buffer
+ */
+static void HttpResponse_AddNumberToResponseHeaders(uint32 num)
+{
+ struct HttpBlob resource;
+ resource.pData = g_state.packetSend + g_state.packetSendSize;
+ resource.uLength = 0;
+ HttpString_utoa(num, &resource);
+ g_state.packetSendSize += resource.uLength;
+}
+
+
+/**
+ * Add a string to the response buffer
+ */
+static void HttpResponse_AddStringToResponseHeaders(char * str, uint16 len)
+{
+ memcpy(g_state.packetSend + g_state.packetSendSize, str, len);
+ g_state.packetSendSize += len;
+}
+
+/**
+ * Add header line to response buffer
+ * Adds a line to the header with the provided name value pair
+ * Precondition to this function is that g_state.packetSendSize and g_state.packetSend are correct
+ */
+static void HttpResponse_AddHeaderLine(char * headerName, uint16 headerNameLen, char * headerValue, uint16 headerValueLen)
+{
+ HttpResponse_AddStringToResponseHeaders(headerName, headerNameLen);
+ HttpResponse_AddCharToResponseHeaders(':');
+ HttpResponse_AddCharToResponseHeaders(' ');
+ HttpResponse_AddStringToResponseHeaders(headerValue, headerValueLen);
+ HttpResponse_AddStringToResponseHeaders(HTTP_HEADER_DELIMITER, sizeof(HTTP_HEADER_DELIMITER)-1);
+}
+
+/**
+ * Add Header line to response buffer
+ * Adds a line to the header with the provided name value pair when the value is numeric
+ * precondition to this function is that g_state.packetSendSize and g_state.packetSend are correct
+ */
+static void HttpResponse_AddHeaderLineNumValue(char * headerName, uint16 uHeaderNameLen, uint32 headerValue)
+{
+ HttpResponse_AddStringToResponseHeaders(headerName, uHeaderNameLen);
+ HttpResponse_AddCharToResponseHeaders(':');
+ HttpResponse_AddCharToResponseHeaders(' ');
+ HttpResponse_AddNumberToResponseHeaders(headerValue);
+ HttpResponse_AddStringToResponseHeaders(HTTP_HEADER_DELIMITER, sizeof(HTTP_HEADER_DELIMITER)-1);
+}
+
+/**
+ * Returns status string according to status code
+ */
+static void HttpStatusString(uint16 uHttpStatus, struct HttpBlob* status)
+{
+ switch (uHttpStatus)
+ {
+ case HTTP_STATUS_OK:
+ HttpBlobSetConst(*status, HTTP_STATUS_OK_STR);
+ break;
+ case HTTP_STATUS_REDIRECT_PERMANENT:
+ HttpBlobSetConst(*status, HTTP_STATUS_REDIRECT_PERMANENT_STR);
+ break;
+ case HTTP_STATUS_REDIRECT_TEMPORARY:
+ HttpBlobSetConst(*status, HTTP_STATUS_REDIRECT_TEMPORARY_STR);
+ break;
+ case HTTP_STATUS_ERROR_UNAUTHORIZED:
+ HttpBlobSetConst(*status, HTTP_STATUS_ERROR_UNAUTHORIZED_STR);
+ break;
+ case HTTP_STATUS_ERROR_NOT_FOUND:
+ HttpBlobSetConst(*status, HTTP_STATUS_ERROR_NOT_FOUND_STR);
+ break;
+ case HTTP_STATUS_ERROR_NOT_ACCEPTED:
+ HttpBlobSetConst(*status, HTTP_STATUS_ERROR_NOT_ACCEPTED_STR);
+ break;
+ case HTTP_STATUS_ERROR_INTERNAL:
+ HttpBlobSetConst(*status, HTTP_STATUS_ERROR_INTERNAL_STR);
+ break;
+ default:
+ HttpDebug("Unknown response status");
+ printf("Unknown response status\r\n");
+ //HttpAssert(0);
+ break;
+ }
+}
+
+void HttpResponse_Headers(uint16 uConnection, uint16 uHttpStatus, uint16 uFlags, uint32 uContentLength, struct HttpBlob contentType, struct HttpBlob location)
+{
+ //printf("ResponseHeaders...\r\n");
+ struct HttpBlob status;
+ struct HttpBlob packet;
+ //HttpAssert(g_state.packetSendSize == 0);
+ //HttpAssert(g_state.connections[uConnection].connectionState == Processing);
+
+ // Get status string according to uHttpStatus
+ HttpStatusString(uHttpStatus, &status);
+
+ // Build the response status line in the packet-send buffer: "HTTP/1.1 " followed by the status number as string, a space, the status string, and "\r\n"
+ // For example: HTTP/1.1 200 OK\r\n
+
+ // Add http version to sent packet according to the version that was received in the request
+ if ( (g_state.connections[uConnection].request.uFlags & HTTP_REQUEST_1_1) != 0)
+ HttpResponse_AddStringToResponseHeaders(HTTP_VERSION_1P1, sizeof(HTTP_VERSION_1P1)-1);
+ else
+ HttpResponse_AddStringToResponseHeaders(HTTP_VERSION_1P0, sizeof(HTTP_VERSION_1P0)-1);
+ HttpResponse_AddCharToResponseHeaders(' ');
+ HttpResponse_AddNumberToResponseHeaders(uHttpStatus);
+ HttpResponse_AddCharToResponseHeaders(' ');
+ HttpResponse_AddStringToResponseHeaders((char*)status.pData, status.uLength);
+ HttpResponse_AddStringToResponseHeaders(HTTP_HEADER_DELIMITER, sizeof(HTTP_HEADER_DELIMITER)-1);
+
+
+ // Handle Authentication
+ if (uHttpStatus == HTTP_STATUS_ERROR_UNAUTHORIZED)
+ {
+#ifdef HTTP_CORE_ENABLE_AUTH
+ HttpResponse_GetPacketSendBuffer(&packet);
+ packet.pData = packet.pData + packet.uLength;
+ packet.uLength = HTTP_CORE_MAX_PACKET_SIZE_SEND - packet.uLength;
+ HttpAuth_ResponseAuthenticate(&g_state.connections[uConnection].request, &packet);
+ if (packet.uLength > 0)
+ g_state.packetSendSize += packet.uLength;
+ //printf("packet.uLength...%i\r\n",g_state.packetSendSize);
+#endif
+ }
+ //printf("Auth complete, now Handle content type...\r\n");
+ // Handle content type
+ // e.g. "Content-Type: text/html\r\n"
+ if ((contentType.pData != NULL) && (contentType.uLength > 0))
+ HttpResponse_AddHeaderLine(HTTP_CONTENT_TYPE, sizeof(HTTP_CONTENT_TYPE)-1, (char*)contentType.pData, contentType.uLength);
+
+ // Handle Content-length
+ // e.g. "Content-Length: 562\r\n"
+ //printf("Handle content-length...%i\r\n",uContentLength);
+ if (uContentLength > 0)
+ HttpResponse_AddHeaderLineNumValue(HTTP_CONTENT_LENGTH, sizeof(HTTP_CONTENT_LENGTH)-1, uContentLength);
+ g_state.connections[uConnection].uContentLeft = uContentLength;
+
+ // Handle compression
+ // e.g. "Content-Encoding: gzip\r\n"
+ //printf("Handle compression...\r\n");
+ if ((uFlags & HTTP_RESPONSE_FLAG_COMPRESSED) != 0)
+ HttpResponse_AddHeaderLine(HTTP_CONTENT_ENCODING, sizeof(HTTP_CONTENT_ENCODING)-1, HTTP_GZIP, sizeof(HTTP_GZIP)-1);
+
+ // Handle redirection/Location
+ // e.g. "Location: /otherpage.html\r\n"
+ //printf("Handle redirection/Location...\r\n");
+ if ((location.pData != NULL) && (location.uLength > 0))
+ HttpResponse_AddHeaderLine(HTTP_LOCATION, sizeof(HTTP_LOCATION)-1, (char*)location.pData, location.uLength);
+
+ // Add the end of headers marker (\r\n)
+ HttpResponse_AddStringToResponseHeaders(HTTP_HEADER_DELIMITER, sizeof(HTTP_HEADER_DELIMITER)-1);
+
+ // Send all response headers over the connection socket
+ //printf("Send all response headers...\r\n");
+ packet.pData = g_state.packetSend;
+ packet.uLength = g_state.packetSendSize;
+ //printf("packet.uLength...%i\r\n",packet.uLength);
+ if (!HttpCore_SendPacket(uConnection, packet)){
+ //printf("Send all response headers failed...\r\n");
+ return;
+ }
+ g_state.packetSendSize = 0;
+ //printf("Send all response headers complete...\r\n");
+ // advance state according to need to send content
+ if (uContentLength > 0)
+ g_state.connections[uConnection].connectionState = ResponseData;
+ else
+ g_state.connections[uConnection].connectionState = ResponseComplete;
+ /*
+ Todo: add logic to send the header packet at any point in the middle, if there is not enough room left in it.
+ */
+ printf("Finished send...\r\n");
+}
+
+void HttpResponse_GetPacketSendBuffer(struct HttpBlob* pPacketSendBuffer)
+{
+ pPacketSendBuffer->pData = g_state.packetSend;
+ pPacketSendBuffer->uLength = g_state.packetSendSize;
+}
+
+void HttpResponse_Content(uint16 uConnection, struct HttpBlob content)
+{
+ //HttpAssert(g_state.connections[uConnection].connectionState == ResponseData);
+ //HttpAssert(g_state.connections[uConnection].uContentLeft >= content.uLength);
+
+ // Send the specified content over the data socket
+ HttpCore_SendPacket(uConnection, content);
+
+ // Update uContentLeft
+ g_state.connections[uConnection].uContentLeft -= content.uLength;
+
+ // If no more content left to send then HTTP transaction is complete
+ if (g_state.connections[uConnection].uContentLeft == 0)
+ g_state.connections[uConnection].connectionState = ResponseComplete;
+}
+
+void HttpResponse_CannedRedirect(uint16 uConnection, struct HttpBlob location, uint16 bPermanent)
+{
+ struct HttpBlob status;
+ HttpStatusString((bPermanent==1? HTTP_STATUS_REDIRECT_PERMANENT:HTTP_STATUS_REDIRECT_TEMPORARY), &status);
+
+ HttpResponse_Headers(uConnection, (bPermanent==1? HTTP_STATUS_REDIRECT_PERMANENT:HTTP_STATUS_REDIRECT_TEMPORARY), 0, 0, nullBlob, location);
+}
+
+void HttpResponse_CannedError(uint16 uConnection, uint16 uHttpStatus)
+{
+ struct HttpBlob status;
+ HttpStatusString(uHttpStatus, &status);
+
+ HttpResponse_Headers(uConnection, uHttpStatus, 0, status.uLength, nullBlob, nullBlob);
+ HttpResponse_Content(uConnection, status);
+}
+
+
+/// @}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/HttpCore.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,69 @@
+/*****************************************************************************
+*
+* HttpCore.h
+* 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 _HTTP_CORE_H_
+#define _HTTP_CORE_H_
+
+/**
+ * @defgroup HttpCore HTTP Server core
+ * This module implements the HTTP server core
+ *
+ * @{
+ */
+
+/// The TCP port to listen on.
+#define HTTP_CORE_SERVER_PORT 80
+
+/// Maximum number of concurrent client connections. This should be one less than the CC3000 maximum number of sockets
+#define HTTP_CORE_MAX_CONNECTIONS 3
+
+/// Maximum size for a received or sent packet. Two buffers of this size must be allocated at all times.
+#define HTTP_CORE_MAX_PACKET_SIZE_RECEIVED 912
+
+/// Maximum size for a received or sent packet. Two buffers of this size must be allocated at all times.
+#define HTTP_CORE_MAX_PACKET_SIZE_SEND 912
+
+/// Maximum length of header line which might be buffered, per connection, if a line is broken between packets
+#define HTTP_CORE_MAX_HEADER_LINE_LENGTH 320
+
+/**
+ * Initialize and start the HTTP server.
+ * The Wifi interface of the CC3000 chip should be initialized by now, and connected to the network
+ */
+void HttpServerInitAndRun();
+
+/// @}
+
+#endif //_HTTP_CORE_H_
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/HttpDebug.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,89 @@
+/*****************************************************************************
+*
+* HttpDebug.c
+* 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.
+*
+*****************************************************************************/
+#include "HttpDebug.h"
+
+
+#ifdef HTTP_CORE_ENABLE_DEBUG
+#include "mbed.h"
+#ifdef WIN32
+
+#include <stdio.h>
+#include <stdarg.h>
+
+void HttpDebug(const char* pFormat, ...)
+{
+ char buffer[2048];
+ va_list argptr;
+ va_start(argptr, pFormat);
+
+ vsprintf_s(buffer, sizeof(buffer), pFormat, argptr);
+
+ va_end(argptr);
+
+ HttpDebugStr(buffer);
+}
+
+void HttpDebugStr(const char* pString)
+{
+ printf("%s\n", pString);
+}
+
+void HttpAssert(int condition)
+{
+ if (condition)
+ return;
+
+ printf("ASSERTION!\n");
+ while (1)
+ {
+ }
+}
+
+#endif
+#else
+void HttpDebug(const char* pFormat, ...)
+{
+
+}
+void HttpDebugStr(const char* pString)
+{
+
+}
+void HttpAssert(int condition)
+{
+
+}
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/HttpDebug.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,68 @@
+/*****************************************************************************
+*
+* HttpDebug.h
+* 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 _HTTP_DEBUG_H_
+#define _HTTP_DEBUG_H_
+
+#include "HttpConfig.h"
+
+/**
+ * @defgroup HttpDebug Debugging routines
+ * This module implements debug routines which enable debug traces to be sent to a logger
+ * Note this module is only compiled if HTTP_CORE_ENABLE_DEBUG is defined in HttpConfig.h
+ *
+ * @{
+ */
+
+/**
+ * Send formatted debug trace to logger
+ * @param pFormat The printf-style format to send
+ * @param ... The rest of the parameters
+ */
+void HttpDebug(const char* pFormat, ...);
+
+/**
+ * Send string debug trace to logger
+ * @param pString The string to send
+ */
+void HttpDebugStr(const char* pString);
+
+/**
+ * Assert that a certain condition is true
+ * @param condition A value that must be nonzero
+ */
+void HttpAssert(int condition);
+
+#endif // _HTTP_STRING_H_
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/HttpDynamic.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,260 @@
+/*****************************************************************************
+*
+* HttpDynamic.c
+* 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.
+*
+*****************************************************************************/
+#include "HttpDynamic.h"
+#include "HttpDynamicHandler.h"
+#include "HttpRequest.h"
+#include "HttpResponse.h"
+#include "HttpCore.h"
+#include "string.h"
+
+#ifdef HTTP_CORE_ENABLE_DYNAMIC
+
+/**
+ * @defgroup HttpDynamic Dynamic request handler module
+ * This module implements dynamic content processing for HTTP requests.
+ * All requests are handled by C code functions, and the response contents is returned via HttpResopnse routines
+ * Note this module is only compiled if HTTP_CORE_ENABLE_DYNAMIC is defined in HttpConfig.h
+ *
+ * @{
+ */
+
+char dynamicResourceName[HTTP_DYNAMIC_NUM_OF_RESOURCES][HTTP_DYNAMIC_MAX_RESOURCE_LEN] = {{"led"},
+ {"wheel"},
+ };
+
+
+char dynamicLedParam1[5] = {"num="};
+char dynamicLedParam2[8] = {"action="};
+
+/* text/html is currently the blob for content type */
+uint8 uDynamicContentType[10] = "text/html";
+
+uint8 uDynamicContentBody[HTTP_DYNAMIC_NUM_OF_RESOURCES][HTTP_DYNAMIC_CONTENT_BODY_LEN];
+
+PerConnDynamicContent dynamicContent[HTTP_CORE_MAX_CONNECTIONS];
+
+
+/**
+ * Initialize HttpDynamic module state for a new request, and identify the request
+ * This function must examine the specified resource string and determine whether it can commit to process this request
+ * Also, if the resource string includes any information that this module needs in order to process the request (such as the contents of the query string)
+ * then it is the responsibility of this function to parse this information and store it in a connection-specific struct.
+ * If this function returns nonzero, then the core will call HttpDynamic_ProcessRequest() with the rest of the request details.
+ * @param uConnection The number of the connection. This value is guaranteed to satisfy: 0 <= uConnection < HTTP_CORE_MAX_CONNECTIONS
+ * @param resource The resource part of the URL, as specified by the browser in the request, including any query string (and hash)
+ * Note: The resource string exists ONLY during the call to this function. The string pointer should not be copied by this function.
+ * @return nonzero if request is to be handled by this module. zero if not.
+ */
+int HttpDynamic_InitRequest(uint16 uConnection, struct HttpBlob resource)
+{
+/* Resource parsing follows the below assumptions:
+ 1. resource name is expected prior to query sign (just like a static page)
+ 2. query sign is expected. If not present, 0 is returned
+ 3. parameter name followed by a '=' sign is searched for. If not fully present, 0 is returned.
+ 4. parameters may arrive unordered */
+
+ uint16 uLoopCounter;
+ uint8 *cStr;
+ struct HttpBlob subBlob;
+
+ /* look for known resource names according to dynamicResourceName[][]*/
+ for (uLoopCounter = 0; uLoopCounter < HTTP_DYNAMIC_NUM_OF_RESOURCES; uLoopCounter++)
+ {
+ if (HttpString_nextToken(dynamicResourceName[uLoopCounter], strlen(dynamicResourceName[uLoopCounter]), resource) != NULL)
+ break;
+ }
+
+ /* dynamic resource not found */
+ if (uLoopCounter == HTTP_DYNAMIC_NUM_OF_RESOURCES)
+ return 0;
+
+ /* if got here, resource name is found on uLoopCounter index */
+ /* find "query" sign */
+ if (NULL == HttpString_nextToken("?", 1, resource))
+ return 0;
+
+ /* find "=" signs preceded by the parameter name */
+ switch ((enum HttpDynamicNumOfResources)uLoopCounter)
+ {
+ case LED:
+ {
+ /* search the LED number */
+ if ((cStr = HttpString_nextToken(dynamicLedParam1, HTTP_DYNAMIC_LED_NUM_LEN, resource)) != NULL)
+ {
+ dynamicContent[uConnection].dynamicHandlerInParam.uLedParam.uLedNumber = (enum HttpDynamicLedNumber)(*(cStr + HTTP_DYNAMIC_LED_NUM_LEN) - '0');
+ }
+ else
+ {
+ return 0;
+ }
+
+ /* search the LED action */
+ if ((cStr = HttpString_nextToken(dynamicLedParam2, HTTP_DYNAMIC_LED_ACTION_LEN, resource)) != NULL)
+ {
+ /* try to match LED action to the expected value exactly! */
+ subBlob.pData = cStr + HTTP_DYNAMIC_LED_ACTION_LEN;
+ subBlob.uLength = 6;
+ if (HttpString_nextToken("toggle", 6, subBlob) != NULL)
+ dynamicContent[uConnection].dynamicHandlerInParam.uLedParam.uLedAction = toggle;
+ else
+ {
+ subBlob.uLength = 2;
+ if (HttpString_nextToken("on", 2, subBlob) != NULL)
+ dynamicContent[uConnection].dynamicHandlerInParam.uLedParam.uLedAction = ON;
+ else
+ {
+ subBlob.uLength = 3;
+ if (HttpString_nextToken("off", 3, subBlob) != NULL)
+ dynamicContent[uConnection].dynamicHandlerInParam.uLedParam.uLedAction = OFF;
+ else
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ return 0;
+ }
+
+ dynamicContent[uConnection].pDynamicHandler = HttpDynamicHandler_ActOnLED;
+ dynamicContent[uConnection].resourceType = LED;
+ break;
+ }
+
+ case WHEEL:
+ {
+ if ((cStr = HttpString_nextToken(dynamicLedParam2, HTTP_DYNAMIC_LED_ACTION_LEN, resource)) != NULL)
+ {
+ subBlob.pData = cStr + HTTP_DYNAMIC_LED_ACTION_LEN;
+ subBlob.uLength = 9;
+ if (HttpString_nextToken("getstatus", 9 , subBlob) == NULL)
+ {
+ return 0;
+ }
+ }
+ else
+ return 0;
+
+ dynamicContent[uConnection].pDynamicHandler = HttpDynamicHandler_GetWheelValue;
+ dynamicContent[uConnection].resourceType = WHEEL;
+ break;
+ }
+ }
+
+ return 1;
+}
+
+/**
+ * Process a dynamic-content HTTP request
+ * This function is only be called by the core, if HttpDynamic_InitRequest() returns nonzero.
+ * This function processes the specified HTTP request, and send the response on the connection specified by request->uConnection.
+ * This function must call the HttpResponse_*() functions in order to send data back to the browser.
+ * Please refer to HttpResponse.h for more information.
+ * @param request Pointer to all data available about the request
+ */
+void HttpDynamic_ProcessRequest(struct HttpRequest* request)
+{
+ struct HttpBlob contentType, nullBlob = {0, NULL};
+ struct HttpBlob contentBody;
+ int count;
+
+
+ /* if HTTP_REQUEST_FLAG_AUTHENTICATED is not set and FLASHDB_FLAG_REQUIRE_AUTH is set then
+ call HttpResponse_CannedError() with status HTTP_STATUS_ERROR_UNAUTHORIZED */
+ if (((request->uFlags & HTTP_REQUEST_FLAG_AUTHENTICATED) == 0))
+ {
+ /* call HttpResponse_CannedError with 500 ERROR_INTERNAL */
+ HttpResponse_CannedError(request->uConnection, HTTP_STATUS_ERROR_UNAUTHORIZED);
+ return;
+ }
+
+ /* intialize the content body */
+ contentBody.pData =uDynamicContentBody[request->uConnection];
+ contentBody.uLength = 0;
+
+ contentType.pData = uDynamicContentType;
+ contentType.uLength = 9;
+
+ /* 1. call the dynamic handler as parsed in the init phase */
+ dynamicContent[request->uConnection].pDynamicHandler(dynamicContent[request->uConnection].dynamicHandlerInParam, &dynamicContent[request->uConnection].dynamicHandlerOutParam);
+ /* config the ContentLength according to the resource type */
+ switch (dynamicContent[request->uConnection].resourceType)
+ {
+ case LED:
+ {
+ contentBody.pData = (uint8*)"Done";
+ contentBody.uLength = 4;
+
+
+ break;
+ }
+ case WHEEL:
+ {
+ char tempdata[6];
+ struct HttpBlob tempContent;
+ tempContent.pData = (uint8 *)tempdata;
+ HttpString_utoa((uint32)dynamicContent[request->uConnection].dynamicHandlerOutParam.sWheelParam.uWheelPosition, &contentBody);
+ *(contentBody.pData + contentBody.uLength) = ':';
+ contentBody.uLength +=1;
+ HttpString_utoa((uint32)dynamicContent[request->uConnection].dynamicHandlerOutParam.sWheelParam.uWheelValue, &tempContent);
+ for(count=0; count<tempContent.uLength; count++)
+ {
+ *(contentBody.pData + (count+contentBody.uLength)) = *tempContent.pData;
+ tempContent.pData++;
+ }
+ contentBody.uLength += tempContent.uLength;
+ *(contentBody.pData + contentBody.uLength) = ':';
+ *(contentBody.pData + contentBody.uLength + 1) = dynamicContent[request->uConnection].dynamicHandlerOutParam.sWheelParam.uLedDummyOut;
+ contentBody.uLength += 2;
+ break;
+ }
+ }
+
+ /* 2. fill the header response (HTTP_RESPONSE_FLAG_COMPRESSED is not set for dynamic) */
+ HttpResponse_Headers(request->uConnection, HTTP_STATUS_OK, 0, contentBody.uLength, contentType, nullBlob);
+
+ /* 3. fill the content response (if exists) */
+ if (contentBody.uLength != 0)
+ {
+ HttpResponse_Content(request->uConnection, contentBody);
+ }
+
+}
+
+
+/// @}
+
+#endif // HTTP_CORE_ENABLE_DYNAMIC
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/HttpDynamic.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,170 @@
+/*****************************************************************************
+*
+* HttpDynamic.h
+* 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 _HTTP_DYNAMIC_H_
+#define _HTTP_DYNAMIC_H_
+
+#include "HttpConfig.h"
+
+#ifdef HTTP_CORE_ENABLE_DYNAMIC
+
+/**
+ * @defgroup HttpDynamic Dynamic request handler module
+ * This module implements dynamic content processing for HTTP requests.
+ * All requests are handled by C code functions, and the response contents is returned via HttpResopnse routines
+ * Note this module is only compiled if HTTP_CORE_ENABLE_DYNAMIC is defined in HttpConfig.h
+ *
+ * @{
+ */
+
+#include "HttpRequest.h"
+
+#define HTTP_DYNAMIC_NUM_OF_RESOURCES 2
+#define HTTP_DYNAMIC_MAX_RESOURCE_LEN 14
+#define HTTP_DYNAMIC_LED_NUM_LEN 4
+#define HTTP_DYNAMIC_LED_ACTION_LEN 7
+#define HTTP_DYNAMIC_TEMPR_UNIT_LEN 5
+#define HTTP_DYNAMIC_CONF_PROTO_LEN 6
+#define HTTP_DYNAMIC_CONTENT_BODY_LEN 17
+
+
+enum HttpDynamicNumOfResources
+{
+ LED,
+ WHEEL,
+};
+
+enum HttpDynamicLedNumber
+{
+ NOLED,
+ LED_1,
+ LED_2,
+ LED_3,
+ LED_4,
+ //LED_5,
+ //LED_6,
+ //LED_7,
+ //LED_8
+};
+
+enum HttpDynamicLedAction
+{
+ OFF,
+ ON,
+ toggle,
+};
+
+enum HttpDynamicWheelAction
+{
+ NONE,
+ GETSTATUS
+};
+
+
+/* input params structure */
+struct HttpDynamicLedInParam
+{
+ enum HttpDynamicLedNumber uLedNumber;
+ enum HttpDynamicLedAction uLedAction;
+};
+
+struct HttpDynamicWheelInParam
+{
+ enum HttpDynamicWheelAction uWheelAction;
+};
+
+
+typedef union
+{
+ struct HttpDynamicLedInParam uLedParam;
+ struct HttpDynamicWheelInParam uWheelParam;
+}inputParams;
+
+struct HttpDynamicLedOutParam
+{
+ uint8 uLedDummyOut;
+};
+
+struct HttpDynamicWheelOutParam
+{
+ uint8 uLedDummyOut;
+ uint8 uWheelPosition;
+ uint16 uWheelValue;
+};
+
+
+typedef union
+{
+ struct HttpDynamicLedOutParam uLedParam;
+ struct HttpDynamicWheelOutParam sWheelParam;
+}outputParams;
+
+typedef struct
+{
+ inputParams dynamicHandlerInParam;
+ outputParams dynamicHandlerOutParam;
+ enum HttpDynamicNumOfResources resourceType;
+ void (*pDynamicHandler)(inputParams, outputParams*);
+}PerConnDynamicContent;
+
+
+/**
+ * Initialize HttpDynamic module state for a new request, and identify the request
+ * This function must examine the specified resource string and determine whether it can commit to process this request
+ * Also, if the resource string includes any information that this module needs in order to process the request (such as the contents of the query string)
+ * then it is the responsibility of this function to parse this information and store it in a connection-specific struct.
+ * If this function returns nonzero, then the core will call HttpDynamic_ProcessRequest() with the rest of the request details.
+ * @param uConnection The number of the connection. This value is guaranteed to satisfy: 0 <= uConnection < HTTP_CORE_MAX_CONNECTIONS
+ * @param resource The resource part of the URL, as specified by the browser in the request, including any query string (and hash)
+ * Note: The resource string exists ONLY during the call to this function. The string pointer should not be copied by this function.
+ * @return nonzero if request is to be handled by this module. zero if not.
+ */
+int HttpDynamic_InitRequest(uint16 uConnection, struct HttpBlob resource);
+
+/**
+ * Process a dynamic-content HTTP request
+ * This function is only be called by the core, if HttpDynamic_InitRequest() returns nonzero.
+ * This function processes the specified HTTP request, and send the response on the connection specified by request->uConnection.
+ * This function must call the HttpResponse_*() functions in order to send data back to the browser.
+ * Please refer to HttpResponse.h for more information.
+ * @param request Pointer to all data available about the request
+ */
+void HttpDynamic_ProcessRequest(struct HttpRequest* request);
+
+/// @}
+
+#endif // HTTP_CORE_ENABLE_DYNAMIC
+
+#endif // _HTTP_DYNAMIC_H_
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/HttpDynamicHandler.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,100 @@
+/*****************************************************************************
+*
+* HttpDynamicHandler.c
+* 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.
+*
+*****************************************************************************/
+#include "mbed.h"
+#include "HttpDynamicHandler.h"
+#include "netapp.h"
+#include "wlan.h"
+#include "string.h"
+#include "Board.h"
+//#include "Wheel.h"
+
+/**
+ * @addtogroup HttpDynamicHandler
+ * @{
+ */
+
+#ifdef HTTP_CORE_ENABLE_DYNAMIC
+
+/**
+ * @defgroup HttpDynamicHandler Handlers methods requested by HttpDynamic module
+ * This module implements methods requested by HttpDynamic module.
+ * Note this module is only compiled if HTTP_CORE_ENABLE_DYNAMIC is defined in HttpConfig.h
+ *
+ * @{
+ */
+
+/**
+ * This function applies an operation on a LED.
+ * It is assumed that the parameters are ordered as denoted below.
+ * @param uLedParams Includes the LED parameters: LED number and LED action
+ * @return no return value
+ */
+void HttpDynamicHandler_ActOnLED(inputParams uLedInParams, outputParams *uLedOutParams)
+{
+ switch(uLedInParams.uLedParam.uLedAction)
+ {
+ case OFF:
+ turnLedOff(uLedInParams.uLedParam.uLedNumber);
+ break;
+ case ON:
+ turnLedOn(uLedInParams.uLedParam.uLedNumber);
+ break;
+ case toggle:
+ toggleLed(uLedInParams.uLedParam.uLedNumber);
+ break;
+ default:
+ break;
+ }
+}
+
+
+/**
+ * This function gets a temperature reading.
+ * @param uTempInParams Denotes the temerature units, Celsius or Fahrenheit
+ * @param uTempOutParams Denotes the temerature value
+ * @return no return value
+ */
+void HttpDynamicHandler_GetWheelValue(inputParams uWheelInParams, outputParams *uWheelOutParams)
+{
+ uWheelOutParams->sWheelParam.uLedDummyOut = GetLEDStatus();
+ uWheelOutParams->sWheelParam.uLedDummyOut = uWheelOutParams->sWheelParam.uLedDummyOut >> 3;
+ // uWheelOutParams->sWheelParam.uWheelPosition = Wheel_getPosition();
+ // uWheelOutParams->sWheelParam.uWheelValue = Wheel_getValue();
+}
+/// @}
+
+#endif // HTTP_CORE_ENABLE_DYNAMIC
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/HttpDynamicHandler.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,81 @@
+/*****************************************************************************
+*
+* HttpDynamicHandler.h
+* 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 _HTTP_DYNAMIC_HANDLER_H_
+#define _HTTP_DYNAMIC_HANDLER_H_
+
+#include "HttpConfig.h"
+#include "HttpDynamic.h"
+//#include <msp430.h>
+
+#ifdef HTTP_CORE_ENABLE_DYNAMIC
+
+/**
+ * @defgroup HttpDynamicHandler Handlers methods requested by HttpDynamic module
+ * This module implements methods requested by HttpDynamic module.
+ * Note this module is only compiled if HTTP_CORE_ENABLE_DYNAMIC is defined in HttpConfig.h
+ *
+ * @{
+ */
+
+
+
+/**
+ * This function applies an operation on a LED.
+ * It is assumed that the parameters are ordered as denoted below.
+ * @param uLedInParams Includes the LED parameters: LED number and LED action
+ * @param uLedOutParams NA. No return parameter is expected.
+ * @return no return value
+ */
+void HttpDynamicHandler_ActOnLED(inputParams uLedInParams, outputParams *uLedOutParams);
+
+
+
+/**
+ * This function gets a temperature reading.
+ * @param uTempInParams Denotes the temerature units, Celsius or Fahrenheit
+ * @param uTempOutParams Denotes the temerature value
+ * @return no return value
+ */
+void HttpDynamicHandler_GetWheelValue(inputParams uWheelInParams, outputParams *uWheelOutParams);
+
+
+
+
+/// @}
+
+#endif // HTTP_CORE_ENABLE_DYNAMIC
+
+#endif // _HTTP_DYNAMIC_HANDLER_H_
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/HttpHeaders.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,75 @@
+/*****************************************************************************
+*
+* HttpHeaders.h
+* 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 _HTTP_HEADERS_H_
+#define _HTTP_HEADERS_H_
+
+/**
+ * @defgroup HttpHeaders HTTP header strings
+ * This header file predefines various HTTP request and response header strings
+ *
+ * @{
+ */
+
+#include "Common.h"
+
+char HTTP_HEADER_DELIMITER[] = "\r\n";
+
+// HTTP method line strings
+char HTTP_METHOD_GET[] = "get";
+char HTTP_METHOD_POST[] = "post";
+char HTTP_VERSION_1P1[] = "http/1.1";
+char HTTP_VERSION_1P0[] = "http/1.0";
+
+// HTTP request/response header line strings
+char HTTP_CONTENT_TYPE[] = "content-type";
+char HTTP_CONTENT_LENGTH[] = "content-length";
+char HTTP_ACCEPT_ENCODING[] = "accept-encoding";
+char HTTP_AUTHORIZATION[] = "authorization";
+char HTTP_CONNECTION_CLOSE[] = "connection";
+char HTTP_GZIP[] = "gzip";
+char HTTP_CLOSE[] = "close";
+char HTTP_LOCATION[] = "location";
+char HTTP_CONTENT_ENCODING[] = "content-encoding";
+
+// HTTP response status line strings
+char HTTP_STATUS_OK_STR[] = "ok";
+char HTTP_STATUS_REDIRECT_PERMANENT_STR[] = "moved permanently";
+char HTTP_STATUS_REDIRECT_TEMPORARY_STR[] = "moved temporarily";
+char HTTP_STATUS_ERROR_UNAUTHORIZED_STR[] = "unauthorized";
+char HTTP_STATUS_ERROR_NOT_FOUND_STR[] = "not found";
+char HTTP_STATUS_ERROR_NOT_ACCEPTED_STR[] = "not accepted";
+char HTTP_STATUS_ERROR_INTERNAL_STR[] = "internal server error";
+
+#endif //_HTTP_HEADERS_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/HttpRequest.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,80 @@
+/*****************************************************************************
+*
+* HttpRequest.h
+* 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 _HTTP_REQUEST_H_
+#define _HTTP_REQUEST_H_
+
+/**
+ * @defgroup HttpRequest HTTP Request definitions
+ * This header file defines the structure which holds information about an HTTP request.
+ * Such a structure is generated by the core module and then passed to a content handler module for processing.
+ *
+ * @{
+ */
+
+#include "Common.h"
+#include "HttpString.h"
+
+/// The client wishes to close the connection after this request
+#define HTTP_REQUEST_FLAG_CLOSE (1 << 0)
+/// The client accepts gzip-compressed content
+#define HTTP_REQUEST_FLAG_ACCEPT_GZIP (1 << 1)
+/// The request is POST. Otherwise it's GET.
+#define HTTP_REQUEST_FLAG_METHOD_POST (1 << 2)
+/// The request was authenticated correctly
+#define HTTP_REQUEST_FLAG_AUTHENTICATED (1 << 3)
+/// The request uses HTTP/1.1 otherwise HTTP/1.0
+#define HTTP_REQUEST_1_1 (1 << 4)
+/// The request containes content, longer than supported
+#define HTTP_REQUEST_CONTENT_IGNORED (1 << 5)
+
+
+/**
+ * A structure to hold all data about an HTTP request
+ * Note: The request's resource string is not passed as part of this structure, but rather directly to the Http*_InitRequest() function
+ */
+struct HttpRequest
+{
+ /// Flags. See HTTP_REQUEST_FLAG_*
+ uint16 uFlags;
+ /// Connection number in HttpCore. This value is guaranteed to satisfy: 0 <= uConnection < HTTP_CORE_MAX_CONNECTIONS
+ uint16 uConnection;
+ /// Request content information (e.g. POST data). uLength value of 0 indicates no content was sent in the request.
+ struct HttpBlob requestContent;
+};
+
+/// @}
+
+#endif //_HTTP_REQUEST_H_
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/HttpResponse.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,114 @@
+/*****************************************************************************
+*
+* HttpResponse.h
+* 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 _HTTP_RESPONSE_H_
+#define _HTTP_RESPONSE_H_
+
+#include "Common.h"
+#include "HttpString.h"
+
+/**
+ * @defgroup HttpResponse HTTP Response modules
+ * This module implements routines to allow content handler modules to build and send HTTP responses back to the client.
+ * There are two layers in this module:
+ * - The lower layer consists of HttpResponse_Headers() and HttpResponse_Content(). These routines allow the caller to specify all details of the response.
+ * - The higher layer consists of HttpResponse_Canned*(). These routines emit canned (pre-made) responses, such as redirects and errors, which are useful in many situations.
+ *
+ * @{
+ */
+
+/**
+ * @defgroup HttpStatus Supported HTTP status codes
+ * @{
+ */
+#define HTTP_STATUS_OK 200
+#define HTTP_STATUS_REDIRECT_PERMANENT 301
+#define HTTP_STATUS_REDIRECT_TEMPORARY 302
+#define HTTP_STATUS_ERROR_UNAUTHORIZED 401
+#define HTTP_STATUS_ERROR_NOT_FOUND 404
+#define HTTP_STATUS_ERROR_NOT_ACCEPTED 406
+#define HTTP_STATUS_ERROR_INTERNAL 500
+
+/// @}
+
+/// The response data is gzip-compressed. Implies the header Content-Encoding: gzip
+#define HTTP_RESPONSE_FLAG_COMPRESSED (1 << 0)
+
+/**
+ * Respond with the specified HTTP status and headers
+ * @param uConnection The connection number, as it appears in the HttpRequest structure
+ * @param uHttpStatus The HTTP status number to response with. Must be one of HTTP_STATUS_*
+ * @param uFlags Flags which are manifested in the response headers. See HTTP_RESPONSE_FLAG_*
+ * @param uContentLength The total length of content which will be sent via HttpResponse_Content()
+ * @param contentType The content type string, or NULL to omit the content type
+ * @param location A string which will be used for the Location header, or NULL to omit the Location header
+ */
+void HttpResponse_Headers(uint16 uConnection, uint16 uHttpStatus, uint16 uFlags, uint32 uContentLength, struct HttpBlob contentType, struct HttpBlob location);
+
+/**
+ * Retrieves the pointer and size of the packet-send buffer
+ * This function should be called by content handlers that wish to use the already-allocated packet-send buffer in calls to HttpResponse_Content()
+ * @param[out] pPacketSendBuffer Returns the pointer and size of the packet-send buffer
+ */
+void HttpResponse_GetPacketSendBuffer(struct HttpBlob* pPacketSendBuffer);
+
+/**
+ * Send response content to the client.
+ * This function may be called more than once, until all the content is sent.
+ * @param uConnection The connection number, as it appears in the HttpRequest structure
+ * @param content Content blob to send to the client.
+ */
+void HttpResponse_Content(uint16 uConnection, struct HttpBlob content);
+
+/**
+ * Sends a canned response, with an HTTP redirect
+ * This function should be called *instead* of HttpResponse_Status(), HttpResponse_Headers() and HttpResponse_Content()
+ * @param uConnection The connection number, as it appears in the HttpRequest structure
+ * @param pLocation The redirect URL
+ * @param bPermanent zero for temporary redirect, nonzero for permanent redirect
+ */
+void HttpResponse_CannedRedirect(uint16 uConnection, struct HttpBlob location, uint16 bPermanent);
+
+/**
+ * Sends a canned response, with an error message
+ * This function should be called *instead* of HttpResponse_Status(), HttpResponse_Headers() and HttpResponse_Content()
+ * @param uConnection The connection number, as it appears in the HttpRequest structure
+ * @param uHttpStatus The HTTP error status. Must be one of HTTP_STATUS_ERROR_*
+ */
+void HttpResponse_CannedError(uint16 uConnection, uint16 uHttpStatus);
+
+/// @}
+
+#endif //_HTTP_RESPONSE_H_
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/HttpStatic.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,129 @@
+/*****************************************************************************
+*
+* HttpStatic.c
+* 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.
+*
+*****************************************************************************/
+#include "HttpStatic.h"
+
+#ifdef HTTP_CORE_ENABLE_STATIC
+
+#include "HttpRequest.h"
+#include "HttpResponse.h"
+#include "HttpCore.h"
+#include "FlashDB.h"
+
+/**
+ * @addtogroup HttpStatic
+ * @{
+ */
+
+/**
+ * @defgroup HttpStatic Static request handler module
+ * This module implements static content processing for HTTP requests.
+ * All requests are handled by looking up the URL's resource in the flash database, and returning the content in the response.
+ * Note this module is only compiled if HTTP_CORE_ENABLE_STATIC is defined in HttpConfig.h
+ *
+ * @{
+ */
+
+
+struct FlashDBContent pFlashDBContent[HTTP_CORE_MAX_CONNECTIONS];
+
+/**
+ * Initialize HttpStatic module state for a new request, and identify the request
+ * This function examines the specified resource string, and looks it up in the Flash Database.
+ * Note: During FlashDB lookup, ignore the query part (?) and anchor part (#) of URL
+ * If found, it commits to process this request by returning nonzero. Otherwise it returns zero.
+ * @param uConnection The number of the connection. This value is guaranteed to satisfy: 0 <= uConnection < HTTP_CORE_MAX_CONNECTIONS
+ * @param resource The resource part of the URL, as specified by the browser in the request, including any query string (and hash).
+ * Note: The resource string exists ONLY during the call to this function. The string pointer should not be copied by this function.
+ * @return nonzero if request is to be handled by this module. zero if not.
+ */
+int HttpStatic_InitRequest(uint16 uConnection, struct HttpBlob resource)
+{
+ if (FlashDB_FindContent(resource, &pFlashDBContent[uConnection]) == 0)
+ return 0;
+
+ return 1;
+}
+
+/**
+ * Process a static-content HTTP request
+ * This function is called after a request was already initialized, and a FlashDB content entry was identified during a call to HttpStatic_InitRequest()
+ * This function calls HttpResponse_*() to send the content data to the browser.
+ * @param request Pointer to all data available about the request
+ * @return nonzero if request was handled. zero if not.
+ */
+void HttpStatic_ProcessRequest(struct HttpRequest* request)
+{
+ struct HttpBlob contentType, nullBlob = {0, NULL};
+
+ /* if HTTP_REQUEST_FLAG_METHOD_POST==1 (i.e. it is POST)
+ HttpResponse_CannedError() responds to client with status HTTP_STATUS_ERROR_INTERNAL
+ POST method is not supported for static pages */
+ if (request->uFlags & HTTP_REQUEST_FLAG_METHOD_POST)
+ {
+ /* HttpResponse_CannedError responds to client with 500 ERROR_INTERNAL */
+ HttpResponse_CannedError(request->uConnection, HTTP_STATUS_ERROR_INTERNAL);
+ return;
+ }
+
+ /* if HTTP_REQUEST_FLAG_ACCEPT_GZIP is not set and FLASHDB_FLAG_COMPRESSED is set then
+ HttpResponse_CannedError() responds to client with status HTTP_STATUS_ERROR_NOT_ACCEPTED */
+ if ((((char)(request->uFlags) & (char)HTTP_REQUEST_FLAG_ACCEPT_GZIP) == 0) && (((char)(pFlashDBContent[request->uConnection].uFlags) & (char)FLASHDB_FLAG_COMPRESSED)))
+ {
+ /* call HttpResponse_CannedError responds to client with 500 ERROR_INTERNAL */
+ HttpResponse_CannedError(request->uConnection, HTTP_STATUS_ERROR_NOT_ACCEPTED);
+ return;
+ }
+ /* if HTTP_REQUEST_FLAG_AUTHENTICATED is not set and FLASHDB_FLAG_REQUIRE_AUTH is set then
+ HttpResponse_CannedError() responds to client with status HTTP_STATUS_ERROR_UNAUTHORIZED */
+ if (((request->uFlags & HTTP_REQUEST_FLAG_AUTHENTICATED) == 0))
+ {
+ /* HttpResponse_CannedError responds to client with 500 ERROR_INTERNAL */
+ HttpResponse_CannedError(request->uConnection, HTTP_STATUS_ERROR_UNAUTHORIZED);
+ return;
+ }
+
+ /* if got here than it is a GET method
+ HttpResponse_Headers() responds to client with status HTTP_STATUS_OK */
+ FlashDB_FindContentType(pFlashDBContent[request->uConnection].uContentType, &contentType);
+ HttpResponse_Headers(request->uConnection, HTTP_STATUS_OK, pFlashDBContent[request->uConnection].uFlags, pFlashDBContent[request->uConnection].contentBlob.uLength, contentType, nullBlob);
+ /* HttpResponse_Content() sends requested page to the client */
+ HttpResponse_Content(request->uConnection, pFlashDBContent[request->uConnection].contentBlob);
+
+}
+
+/// @}
+
+#endif // HTTP_CORE_ENABLE_STATIC
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/HttpStatic.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,79 @@
+/*****************************************************************************
+*
+* HttpStatic.h
+* 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 _HTTP_STATIC_H_
+#define _HTTP_STATIC_H_
+
+#include "HttpConfig.h"
+
+#ifdef HTTP_CORE_ENABLE_STATIC
+
+/**
+ * @defgroup HttpStatic Static request handler module
+ * This module implements static content processing for HTTP requests.
+ * All requests are handled by looking up the URL's resource in the flash database, and returning the content in the response.
+ * Note this module is only compiled if HTTP_CORE_ENABLE_STATIC is defined in HttpConfig.h
+ *
+ * @{
+ */
+
+#include "HttpRequest.h"
+
+/**
+ * Initialize HttpStatic module state for a new request, and identify the request
+ * This function examines the specified resource string, and looks it up in the Flash Database.
+ * Note: During FlashDB lookup, ignore the query part (?) and anchor part (#) of URL
+ * If found, it commits to process this request by returning nonzero. Otherwise it returns zero.
+ * @param uConnection The number of the connection. This value is guaranteed to satisfy: 0 <= uConnection < HTTP_CORE_MAX_CONNECTIONS
+ * @param resource The resource part of the URL, as specified by the browser in the request, including any query string (and hash).
+ * Note: The resource string exists ONLY during the call to this function. The string pointer should not be copied by this function.
+ * @return nonzero if request is to be handled by this module. zero if not.
+ */
+int HttpStatic_InitRequest(uint16 uConnection, struct HttpBlob resource);
+
+/**
+ * Process a static-content HTTP request
+ * This function is called after a request was already initialized, and a FlashDB content entry was identified during a call to HttpStatic_InitRequest()
+ * This function calls HttpResponse_*() to send the content data to the browser.
+ * @param request Pointer to all data available about the request
+ * @return nonzero if request was handled. zero if not.
+ */
+void HttpStatic_ProcessRequest(struct HttpRequest* request);
+
+/// @}
+
+#endif // HTTP_CORE_ENABLE_STATIC
+
+#endif // _HTTP_STATIC_H_
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/HttpString.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,183 @@
+/*****************************************************************************
+*
+* HttpString.c
+* 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.
+*
+*****************************************************************************/
+#include "mbed.h"
+#include "string.h"
+#include <stdlib.h>
+#include "HttpString.h"
+
+/**
+ * @addtogroup HttpString
+ * @{
+ */
+
+char digits[] = "0123456789";
+char hexDigits[] = "0123456789abcdef";
+
+int HttpString_strcmp(struct HttpBlob first, struct HttpBlob second)
+{
+ int min,res;
+ if (first.uLength > second.uLength)
+ min = second.uLength;
+ else
+ min = first.uLength;
+
+ // Compare a common length which might be equal
+ res = memcmp(first.pData, second.pData, min);
+ if (res != 0)
+ return res;
+
+ // Common length is equal, so the longer blob is "larger"
+ if (first.uLength > second.uLength)
+ return 1;
+ else if (first.uLength < second.uLength)
+ return -1;
+ else
+ return 0;
+}
+
+static void ToLower(char * str, uint16 len)
+{
+ int i;
+ for (i=0 ; i<=len; i++)
+ {
+ if (str[i]>='A' && str[i]<='Z')
+ str[i] = str[i] + 32;
+ }
+}
+
+uint8* HttpString_nextToken(char* pToken, uint16 uTokenLength, struct HttpBlob blob)
+{
+ uint8* pch = blob.pData;
+ struct HttpBlob partialBlob;
+ struct HttpBlob token;
+ token.pData = (uint8*)pToken;
+ token.uLength = uTokenLength;
+ ToLower((char *)blob.pData, blob.uLength);
+ while (pch < blob.pData + blob.uLength)
+ {
+ // Calculate how many blob bytes we should search
+ int nMaxCount = blob.uLength - (pch - blob.pData) - uTokenLength + 1;
+ if (nMaxCount < 1)
+ return NULL;
+
+ // Search for the first character of the token
+ pch = (uint8*)memchr(pch, pToken[0], nMaxCount);
+ if (pch==NULL)
+ return NULL;
+
+ // Found first character, now compare the rest
+ partialBlob.pData = pch;
+ partialBlob.uLength = uTokenLength;
+ if (HttpString_strcmp(token, partialBlob)==0)
+ return pch;
+
+ // Skip this byte, and look for the token in the rest of the blob
+ ++pch;
+ }
+ return NULL;
+}
+
+uint32 HttpString_atou(struct HttpBlob string)
+{
+ return atoi((const char*)string.pData);
+}
+
+void HttpString_utoa(uint32 uNum, struct HttpBlob* pString)
+{
+ char* ptr;
+ uint32 uTemp = uNum;
+
+ // value 0 is a special format
+ if (uNum == 0)
+ {
+ pString->uLength = 1;
+ *pString->pData = '0';
+ return;
+ }
+
+ // Find out the length of the number, in decimal base
+ pString->uLength = 0;
+ while (uTemp > 0)
+ {
+ uTemp /= 10;
+ pString->uLength++;
+ }
+
+ // Do the actual formatting, right to left
+ uTemp = uNum;
+ ptr = (char*)pString->pData + pString->uLength;
+ while (uTemp > 0)
+ {
+ --ptr;
+ *ptr = digits[uTemp % 10];
+ uTemp /= 10;
+ }
+}
+
+void HttpString_htoa(uint32 uNum, struct HttpBlob* pString, uint8 bPadZero)
+{
+ uint8* ptr;
+ uint32 uTemp = uNum;
+
+ if (!bPadZero)
+ {
+ // value 0 is a special format
+ if (uNum == 0)
+ {
+ pString->uLength = 1;
+ *pString->pData = '0';
+ return;
+ }
+
+ // Find out the length of the number, in hexadecimal base
+ pString->uLength = 0;
+ while (uTemp > 0)
+ {
+ uTemp /= 16;
+ pString->uLength++;
+ }
+ }
+
+ // Do the actual formatting, right to left
+ uTemp = uNum;
+ ptr = pString->pData + pString->uLength;
+ while (ptr > pString->pData)
+ {
+ --ptr;
+ *ptr = (uint8)hexDigits[uTemp % 16];
+ uTemp /= 16;
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/HttpString.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,112 @@
+/*****************************************************************************
+*
+* HTTPString.h
+* 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 _HTTP_STRING_H_
+#define _HTTP_STRING_H_
+
+/**
+ * @defgroup HttpString String routines helper module
+ * This module implements some string and buffer-related helper routines
+ *
+ * @{
+ */
+
+#include "Common.h"
+
+/**
+ * A structure to hold a string or buffer which is not null-terminated
+ */
+//#ifdef __CCS__
+//struct __attribute__ ((__packed__)) HttpBlob
+//#elif __IAR_SYSTEMS_ICC__
+//#pragma pack(1)
+struct HttpBlob
+//#endif
+{
+ uint16 uLength;
+ uint8* pData;
+};
+
+/**
+ * Utility macro which sets an existing blob
+ */
+#define HttpBlobSetConst(blob, constString) \
+ { \
+ (blob).pData = (uint8*)constString; \
+ (blob).uLength = sizeof(constString) - 1; \
+ }
+
+/**
+ * Perform string comparison between two strings.
+ * @param first Pointer to data about the first blob or string
+ * @param second Pointer to data about the second blob or string
+ * @return zero if equal, positive if first is later in order, negative if second is later in order
+ */
+int HttpString_strcmp(struct HttpBlob first, struct HttpBlob second);
+
+/**
+ * return pointer to the next token
+ * @param token Pointer to data of the first token
+ * @param blob Pointer to data of the search string/blob
+ * @return pointer if found, otherwize NULL
+ */
+uint8* HttpString_nextToken(char* pToken, uint16 uTokenLength, struct HttpBlob blob);
+
+/**
+ * Parse a string representation of an unsigned decimal number
+ * Stops at any non-digit character.
+ * @param string The string to parse
+ * @return The parsed value
+ */
+uint32 HttpString_atou(struct HttpBlob string);
+
+/**
+ * Format an unsigned decimal number as a string
+ * @param uNum The number to format
+ * @param[in,out] pString A string buffer which returns the formatted string. On entry, uLength is the maximum length of the buffer, upon return uLength is the actual length of the formatted string
+ */
+void HttpString_utoa(uint32 uNum, struct HttpBlob* pString);
+
+/**
+ * Format an unsigned decimal number as an hexdecimal string
+ * @param uNum The number to format
+ * @param bPadZero nonzero to pad with zeros up to the string length, or zero to use minimal length required to represent the number
+ * @param[in,out] pString A string buffer which returns the formatted string. On entry, uLength is the maximum length of the buffer, upon return uLength is the actual length of the formatted string
+ */
+void HttpString_htoa(uint32 uNum, struct HttpBlob* pString, uint8 bPadZero);
+
+/// @}
+
+#endif // _HTTP_STRING_H_
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/WebServerApp.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,296 @@
+/*****************************************************************************
+*
+* WebServerApp.c - CC3000 Slim 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.
+*
+*****************************************************************************/
+#include "mbed.h"
+#include "wlan.h"
+#include "evnt_handler.h" // callback function declaration
+#include "nvmem.h"
+#include "socket.h"
+#include "netapp.h"
+#include "host_driver_version.h"
+#include "cc3000.h"
+#include "Common.h"
+#include "demo_config.h"
+#include "HttpString.h"
+
+//#include <msp430.h>
+#include "Board.h"
+#include "HttpCore.h"
+//#include "Wheel.h"
+#include "dispatcher.h"
+
+#define FALSE 0
+#define SERVERAPPVERSION "v1.10.11.6.8.1"
+
+volatile unsigned long ulCC3000Connected,ulCC3000DHCP,OkToDoShutDown;
+unsigned char obtainIpInfoFlag = FALSE;
+unsigned char ConnectUsingSmartConfig;
+tNetappIpconfigRetArgs *ipconfig;
+char DevServname[] = {'C','C','3','0','0','0'};
+volatile char runSmartConfig = 0;
+unsigned char mDNSValid, skipCount, mDNSSend;
+int8_t isInitialized = FALSE;
+
+void ManualConnect(void);
+
+int String_utoa(int uNum, char *pString)
+{
+ char digits[] = "0123456789";
+ char* ptr;
+ int uLength;
+ int uTemp = uNum;
+
+ // value 0 is a special format
+ if (uNum == 0)
+ {
+ uLength = 1;
+ *pString = '0';
+ return uLength;
+ }
+
+ // Find out the length of the number, in decimal base
+ uLength = 0;
+ while (uTemp > 0)
+ {
+ uTemp /= 10;
+ uLength++;
+ }
+
+ // Do the actual formatting, right to left
+ uTemp = uNum;
+ ptr = (char*)pString + uLength;
+ while (uTemp > 0)
+ {
+ --ptr;
+ *ptr = digits[uTemp % 10];
+ uTemp /= 10;
+ }
+ return uLength;
+}
+
+int iptostring(unsigned char *ip, char *ipstring)
+{
+ int temp,i, length, uLength;
+ char *ptr;
+ ip =ip +3;
+ ptr = ipstring;
+ uLength = 0;
+ for (i=0; i<4; i++)
+ {
+ temp = *ip;
+ length = String_utoa((unsigned long) temp, ptr);
+ ptr = ptr + length;
+ uLength += length;
+ *ptr = '.';
+ ptr++;
+ uLength++;
+ ip--;
+ }
+ return (uLength-1);
+}
+
+//*****************************************************************************
+//
+//! main
+//!
+//! \param None
+//!
+//! \return none
+//!
+//! \brief The main loop is executed here
+//
+//*****************************************************************************
+
+int main()
+{
+ char ipvalue[15];
+ int length;
+ runSmartConfig = 0;
+ obtainIpInfoFlag = 0;
+ skipCount = 0;
+ mDNSValid = 0;
+ mDNSSend =0;
+ unsigned char buff[5];
+ int rval;
+ //Stop watch dog timer, In IAR this is done in low_level_init.c file
+//#ifdef __CCS__
+// WDTCTL = WDTPW + WDTHOLD;
+//#endif
+
+ // Start CC3000 State Machine
+ resetCC3000StateMachine();
+
+ //
+ // Board Initialization start
+ //
+
+ initDriver();
+ isInitialized = TRUE; // For manual connect
+ //Wheel_init();
+ //Wheel_enable();
+ //__enable_interrupt();
+ DispatcherUartSendPacket("\r\n\r\n--Initializing Application--",32);
+ DispatcherUartSendPacket("\r\nWeb Server App Version=",25);
+ DispatcherUartSendPacket(SERVERAPPVERSION,14);
+ DispatcherUartSendPacket("\r\n", 2);
+
+ if (nvmem_read_sp_version(buff)!=0){
+ printf("nvmem_read_sp_version failed...\r\n");
+ }
+ else
+ {
+ printf("Firmware version: %d.%d\r\n",buff[0], buff[1]);
+ }
+
+
+ while(1)
+ {
+ // Perform Smart Config if button pressed
+ if(runSmartConfig == 1)
+ {
+ mDNSValid = 0;
+ // Turn Off PAD LED's
+ turnLedOff(ind1);
+ turnLedOff(ind2);
+ turnLedOff(ind3);
+ turnLedOff(ind4);
+ turnLedOff(LED8);
+
+ // Start the Smart Config Process
+ StartSmartConfig();
+ runSmartConfig = 0;
+ }
+
+ if(!(currentCC3000State() & CC3000_ASSOC))
+ {
+ //Connect via profile (unsol connect) or :-
+ // ManualConnect();
+
+ // Wait until connection is finished
+ while (!(currentCC3000State() & CC3000_ASSOC))
+ {
+
+ wait_us(5);
+ //__delay_cycles(100);
+ // Check if user pressed button to do Smart Config
+ if(runSmartConfig == 1)
+ break;
+ }
+ }
+
+ // Print out connection status
+ if(currentCC3000State() & CC3000_IP_ALLOC && obtainIpInfoFlag == FALSE)
+ {
+ // Set flag so we don't constantly obtain the IP info
+ obtainIpInfoFlag = TRUE;
+ turnLedOn(CC3000_IP_ALLOC_IND);
+ }
+
+ if(currentCC3000State() & CC3000_IP_ALLOC && obtainIpInfoFlag == TRUE)
+ {
+ //If smart config was done was broadcast mdns signal
+ if (ConnectUsingSmartConfig==1)
+ {
+ mdnsAdvertiser(1,DevServname, sizeof(DevServname));
+ ConnectUsingSmartConfig = 0;
+ }
+ mDNSValid =1;
+ skipCount =0;
+ ipconfig = getCC3000Info();
+ length = iptostring(ipconfig->aucIP, ipvalue);
+ DispatcherUartSendPacket("\r\nIP = ", 7);
+ DispatcherUartSendPacket(ipvalue, length);
+ DispatcherUartSendPacket("\r\n", 2);
+ //Initialize and start the HTTP server
+ HttpServerInitAndRun();
+ }
+ }
+ return 1;
+}
+
+/************************************************************************************
+// This is an example of how you'd connect the CC3000 to an AP without using
+// Smart Config or a stored profile.
+//
+// All the code above wlan_connect() is just for this demo program; if you're
+// always going to connect to your network this way you wouldn't need it.
+************************************************************************************/
+
+void ManualConnect() {
+
+ char ssidName[] = "*********";
+ //char AP_KEY[] = "********";//Refer to demo_config.h
+ int8_t rval;
+
+ if (!isInitialized) {
+ printf("CC3000 not initialized; can't run manual connect.\r\n");
+ return;
+ }
+
+ printf("Starting manual connect...\r\n");
+
+ printf((" Disabling auto-connect policy...\r\n"));
+ rval = wlan_ioctl_set_connection_policy(0, 0, 0);
+
+ printf(" Deleting all existing profiles...\r\n");
+ rval = wlan_ioctl_del_profile(255);
+
+ printf(" Waiting until disconnected...\r\n");
+ while (ulCC3000Connected == 1) {
+ wait_ms(100);
+ }
+
+ printf(" Manually connecting...\r\n");
+
+ // Parameter 1 is the security type: WLAN_SEC_UNSEC, WLAN_SEC_WEP,
+ // WLAN_SEC_WPA or WLAN_SEC_WPA2
+ // Parameter 3 is the MAC adddress of the AP. All the TI examples
+ // use NULL. I suppose you would want to specify this
+ // if you were security paranoid.
+ rval = wlan_connect(WLAN_SEC_WPA2,
+ ssidName,
+ strlen(ssidName),
+ NULL,
+ (unsigned char *)AP_KEY,
+ strlen(AP_KEY));
+
+ if (rval==0) {
+ printf(" Manual connect success.\r\n");
+ }
+ else {
+ printf(" Unusual return value: ");
+ printf("%d\r\n",rval);
+ }
+ return;
+ }
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebServer/application_version.h Sat Sep 14 17:38:41 2013 +0000 @@ -0,0 +1,54 @@ +/***************************************************************************** +* +* application_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 __APPLICATION_VERSION_H__ +#define __APPLICATION_VERSION_H__ + +#define APPLICATION_VERSION 11 // version 11 + +#endif // __VERSION_H__ + + + + + + + + + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/cc3000.cpp Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,588 @@
+/*****************************************************************************
+*
+* cc3000.c - CC3000 Functions 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.
+*
+*****************************************************************************/
+
+#include "mbed.h"
+#include "cc3000.h"
+//#include <msp430.h>
+#include "wlan.h"
+#include "evnt_handler.h" // callback function declaration
+#include "nvmem.h"
+#include "socket.h"
+#include "Common.h"
+#include "netapp.h"
+//#include "common.h"
+#include "demo_config.h"
+#include "spi.h"
+#include "Board.h"
+#include "dispatcher.h"
+#include "spi_version.h"
+#include "application_version.h"
+#include "host_driver_version.h"
+#include "security.h"
+
+#define PALTFORM_VERSION (6)
+
+
+// Variable to indicate whether the Smart Config Process has finished
+volatile unsigned long ulSmartConfigFinished = 0;
+
+unsigned char pucIP_Addr[4];
+unsigned char pucIP_DefaultGWAddr[4];
+unsigned char pucSubnetMask[4];
+unsigned char pucDNS[4];
+
+tNetappIpconfigRetArgs ipinfo;
+
+// Smart Config Prefix - Texas Instruments
+char aucCC3000_prefix[3] = {'T', 'T', 'T'};
+extern char digits[];
+
+const unsigned char smartconfigkey[] = {0x73,0x6d,0x61,0x72,0x74,0x63,0x6f,0x6e,0x66,0x69,0x67,0x41,0x45,0x53,0x31,0x36};
+
+const unsigned char pucUARTExampleAppString[] = {'\f', '\r','E', 'x', 'a', 'm', 'p', 'l', 'e', ' ', 'A', 'p', 'p', ':', 'd', 'r', 'i', 'v', 'e', 'r', ' ', 'v', 'e', 'r', 's', 'i', 'o', 'n', ' ' };
+
+char cc3000state = CC3000_UNINIT;
+
+extern unsigned char ConnectUsingSmartConfig;
+extern volatile unsigned long ulCC3000Connected;
+char CheckSocket = 0;
+signed char sd[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+//*****************************************************************************
+//
+//! ConnectUsingSSID
+//!
+//! \param ssidName is a string of the AP's SSID
+//!
+//! \return none
+//!
+//! \brief Connect to an Access Point using the specified SSID
+//
+//*****************************************************************************
+int ConnectUsingSSID(char * ssidName)
+{
+
+ unsetCC3000MachineState(CC3000_ASSOC);
+
+ // Disable Profiles and Fast Connect
+ wlan_ioctl_set_connection_policy(0, 0, 0);
+
+ wlan_disconnect();
+ wait_us(500);
+ //__delay_cycles(10000);
+
+ // This triggers the CC3000 to connect to specific AP with certain parameters
+ //sends a request to connect (does not necessarily connect - callback checks that for me)
+#ifndef CC3000_TINY_DRIVER
+ wlan_connect(0, ssidName, strlen(ssidName), NULL, NULL, 0);
+#else
+ wlan_connect(ssidName, strlen(ssidName));
+#endif
+ // We don't wait for connection. This is handled somewhere else (in the main
+ // loop for example).
+
+ return 0;
+}
+
+
+//*****************************************************************************
+//
+//! itoa
+//!
+//! @param[in] integer number to convert
+//!
+//! @param[in/out] output string
+//!
+//! @return number of ASCII parameters
+//!
+//! @brief Convert integer to ASCII in decimal base
+//
+//*****************************************************************************
+unsigned short itoa(char cNum, char *cString)
+{
+ char* ptr;
+ char uTemp = cNum;
+ unsigned short length;
+
+ // value 0 is a special case
+ if (cNum == 0)
+ {
+ length = 1;
+ *cString = '0';
+
+ return length;
+ }
+
+ // Find out the length of the number, in decimal base
+ length = 0;
+ while (uTemp > 0)
+ {
+ uTemp /= 10;
+ length++;
+ }
+
+ // Do the actual formatting, right to left
+ uTemp = cNum;
+ ptr = cString + length;
+ while (uTemp > 0)
+ {
+ --ptr;
+ *ptr = digits[uTemp % 10];
+ uTemp /= 10;
+ }
+
+ return length;
+}
+
+
+//*****************************************************************************
+//
+//! sendDriverPatch
+//!
+//! \param pointer to the length
+//!
+//! \return none
+//!
+//! \brief The function returns a pointer to the driver patch: since there is no patch yet -
+//! it returns 0
+//
+//*****************************************************************************
+char *sendDriverPatch(unsigned long *Length)
+{
+ *Length = 0;
+ return NULL;
+}
+
+
+//*****************************************************************************
+//
+//! sendBootLoaderPatch
+//!
+//! \param pointer to the length
+//!
+//! \return none
+//!
+//! \brief The function returns a pointer to the boot loader patch: since there is no patch yet -
+//! it returns 0
+//
+//*****************************************************************************
+char *sendBootLoaderPatch(unsigned long *Length)
+{
+ *Length = 0;
+ return NULL;
+}
+
+//*****************************************************************************
+//
+//! sendWLFWPatch
+//!
+//! \param pointer to the length
+//!
+//! \return none
+//!
+//! \brief The function returns a pointer to the FW patch: since there is no patch yet - it returns 0
+//
+//*****************************************************************************
+
+char *sendWLFWPatch(unsigned long *Length)
+{
+ *Length = 0;
+ return NULL;
+}
+
+
+//*****************************************************************************
+//
+//! CC3000_UsynchCallback
+//!
+//! \param Event type
+//!
+//! \return none
+//!
+//! \brief The function handles asynchronous events that come from CC3000 device
+//! and operates a LED4 to have an on-board indication
+//
+//*****************************************************************************
+
+void CC3000_UsynchCallback(long lEventType, char * data, unsigned char length)
+{
+ if (lEventType == HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE)
+ {
+ ulSmartConfigFinished = 1;
+ }
+
+ if (lEventType == HCI_EVNT_WLAN_UNSOL_INIT)
+ {
+ setCC3000MachineState(CC3000_INIT);
+ }
+ if (lEventType == HCI_EVNT_WLAN_UNSOL_CONNECT)
+ {
+ ulCC3000Connected = 1;
+ setCC3000MachineState(CC3000_ASSOC);
+
+ }
+
+ if (lEventType == HCI_EVNT_WLAN_UNSOL_DISCONNECT)
+ {
+ ulCC3000Connected = 0;
+ //restartMSP430();
+ unsetCC3000MachineState(CC3000_ASSOC);
+
+ }
+ if (lEventType == HCI_EVNT_WLAN_UNSOL_DHCP)
+ {
+ setCC3000MachineState(CC3000_IP_ALLOC);
+ }
+
+ // This Event is gengerated when the TCP connection is Half closed
+ if (lEventType == HCI_EVNT_BSD_TCP_CLOSE_WAIT)
+ {
+ sd[data[0]] = 1;
+ CheckSocket = 1;
+ }
+
+ //if (lEventType == HCI_EVENT_CC3000_CAN_SHUT_DOWN){
+ //OkToDoShutDown = 1;
+ // printf("CC3000 Usync event: OK to shut down\r\n");
+ // }
+}
+
+//*****************************************************************************
+//
+//! initDriver
+//!
+//! \param None
+//!
+//! \return none
+//!
+//! \brief The function initializes a CC3000 device and triggers it to start operation
+//
+//*****************************************************************************
+int
+ initDriver(void)
+{
+ // Init GPIO's
+ //pio_init();
+
+ // Init SPI
+ init_spi();
+
+ DispatcherUARTConfigure();
+
+ // Globally enable interrupts
+ //__enable_interrupt();
+
+ //
+ // WLAN On API Implementation
+ //
+ wlan_init( CC3000_UsynchCallback, sendWLFWPatch, sendDriverPatch, sendBootLoaderPatch, ReadWlanInterruptPin, WlanInterruptEnable, WlanInterruptDisable, WriteWlanPin);
+
+ //
+ // Trigger a WLAN device
+ //
+ wlan_start(0);
+
+ //
+ // Mask out all non-required events from CC3000
+ //
+
+ wlan_set_event_mask(HCI_EVNT_WLAN_KEEPALIVE|HCI_EVNT_WLAN_ASYNC_PING_REPORT|HCI_EVNT_WLAN_UNSOL_INIT);
+
+ // Generate event to CLI: send a version string
+ char cc3000IP[50];
+ char *ccPtr;
+ unsigned short ccLen;
+
+ DispatcherUartSendPacket((const char*)pucUARTExampleAppString, sizeof(pucUARTExampleAppString));
+
+ ccPtr = &cc3000IP[0];
+ ccLen = itoa(PALTFORM_VERSION, ccPtr);
+ ccPtr += ccLen;
+ *ccPtr++ = '.';
+ ccLen = itoa(APPLICATION_VERSION, ccPtr);
+ ccPtr += ccLen;
+ *ccPtr++ = '.';
+ ccLen = itoa(SPI_VERSION_NUMBER, ccPtr);
+ ccPtr += ccLen;
+ *ccPtr++ = '.';
+ ccLen = itoa(DRIVER_VERSION_NUMBER, ccPtr);
+ ccPtr += ccLen;
+ *ccPtr++ = '\r';
+ *ccPtr++ = '\n';
+ *ccPtr++ = '\0';
+ ccLen = strlen(cc3000IP);
+
+ DispatcherUartSendPacket((const char*)cc3000IP, strlen(cc3000IP));
+
+ // CC3000 has been initialized
+ setCC3000MachineState(CC3000_INIT);
+
+ unsigned long aucDHCP, aucARP, aucKeepalive, aucInactivity;
+
+ aucDHCP = 14400;
+ aucARP = 3600;
+ aucKeepalive = 10;
+ aucInactivity = 100;
+
+ if(netapp_timeout_values(&(aucDHCP), &(aucARP), &(aucKeepalive), &(aucInactivity)) != 0)
+ {
+ while(1);
+ }
+
+ return(0);
+}
+
+
+//*****************************************************************************
+//
+//! \brief Return the highest state which we're in
+//!
+//! \param None
+//!
+//! \return none
+//!
+//
+//*****************************************************************************
+char highestCC3000State()
+{
+ // We start at the highest state and go down, checking if the state
+ // is set.
+ char mask = 0x80;
+ while(!(cc3000state & mask))
+ {
+ mask = mask >> 1;
+ }
+
+ return mask;
+}
+
+//*****************************************************************************
+//
+//! \brief Return the current state bits
+//!
+//! \param None
+//!
+//! \return none
+//!
+//
+//*****************************************************************************
+char currentCC3000State()
+{
+ return cc3000state;
+}
+
+void setCC3000MachineState(char stat)
+{
+ char bitmask = stat;
+ cc3000state |= bitmask;
+
+ int i = FIRST_STATE_LED_NUM;
+
+ // Find LED number which needs to be set
+ while(bitmask < 0x80)
+ {
+ bitmask = bitmask << 1;
+ i++;
+ }
+ turnLedOn(NUM_STATES-i+2);
+
+}
+
+
+//*****************************************************************************
+//
+//! \brief Unsets a state from the state machine
+//! Also handles LEDs
+//!
+//! \param None
+//!
+//! \return none
+//!
+//
+//*****************************************************************************
+void unsetCC3000MachineState(char stat)
+{
+ char bitmask = stat;
+ cc3000state &= ~bitmask;
+
+ int i = FIRST_STATE_LED_NUM;
+ int k = NUM_STATES; // Set to last element in state list
+
+ // Set all upper bits to 0 as well since state machine cannot have
+ // those states.
+ while(bitmask < 0x80)
+ {
+ cc3000state &= ~bitmask;
+ bitmask = bitmask << 1;
+ i++;
+ }
+
+ // Turn off all upper state LEDs
+ for(; i > FIRST_STATE_LED_NUM; i--)
+ {
+ turnLedOff(k);
+ k--;
+ }
+}
+
+//*****************************************************************************
+//
+//! \brief Resets the State Machine
+//!
+//! \param None
+//!
+//! \return none
+//!
+//
+//*****************************************************************************
+void resetCC3000StateMachine()
+{
+ cc3000state = CC3000_UNINIT;
+
+ // Turn off all Board LEDs
+
+ turnLedOff(CC3000_ON_IND);
+ turnLedOff(CC3000_ASSOCIATED_IND);
+ turnLedOff(CC3000_IP_ALLOC_IND);
+ turnLedOff(CC3000_SERVER_INIT_IND);
+ turnLedOff(CC3000_CLIENT_CONNECTED_IND);
+ turnLedOff(CC3000_SENDING_DATA_IND);
+ turnLedOff(CC3000_UNUSED1_IND);
+ turnLedOff(CC3000_FTC_IND);
+}
+
+//*****************************************************************************
+//
+//! \brief Obtains the CC3000 Connection Information from the CC3000
+//!
+//! \param None
+//!
+//! \return none
+//!
+//
+//*****************************************************************************
+#ifndef CC3000_TINY_DRIVER
+tNetappIpconfigRetArgs * getCC3000Info()
+{
+ netapp_ipconfig(&ipinfo);
+ return (&ipinfo);
+}
+#endif
+
+//*****************************************************************************
+//
+//! StartSmartConfig
+//!
+//! \param None
+//!
+//! \return none
+//!
+//! \brief The function triggers a smart configuration process on CC3000.
+//! it exists upon completion of the process
+//
+//*****************************************************************************
+
+void StartSmartConfig(void)
+{
+
+ // Reset all the previous configuration
+ //
+ wlan_ioctl_set_connection_policy(0, 0, 0);
+ wlan_ioctl_del_profile(255);
+
+ //Wait until CC3000 is dissconected
+ while (ulCC3000Connected == 1)
+ {
+ wait_us(5);
+ //__delay_cycles(100);
+ }
+
+ // Start blinking LED6 during Smart Configuration process
+ turnLedOn(LED6);
+ wlan_smart_config_set_prefix(aucCC3000_prefix);
+ //wlan_first_time_config_set_prefix(aucCC3000_prefix);
+ turnLedOff(ind4);
+
+ // Start the SmartConfig start process
+ wlan_smart_config_start(1);
+ turnLedOn(ind4);
+
+ //
+ // Wait for Smart config finished
+ //
+ while (ulSmartConfigFinished == 0)
+ {
+ //__delay_cycles(6000000);
+ wait_ms(250);
+ turnLedOn(ind4);
+
+ //__delay_cycles(6000000);
+ wait_ms(250);
+ turnLedOff(ind4);
+ }
+
+ turnLedOff(ind4);
+
+ // create new entry for AES encryption key
+ nvmem_create_entry(NVMEM_AES128_KEY_FILEID,16);
+
+ // write AES key to NVMEM
+ aes_write_key((unsigned char *)(&smartconfigkey[0]));
+
+ // Decrypt configuration information and add profile
+ wlan_smart_config_process();
+
+ //
+ // Configure to connect automatically to the AP retrieved in the
+ // Smart config process
+ //
+ wlan_ioctl_set_connection_policy(0, 0, 1);
+
+ //
+ // reset the CC3000
+ //
+ wlan_stop();
+ wait_ms(250);
+ //__delay_cycles(600000);
+ wlan_start(0);
+
+ ConnectUsingSmartConfig = 1;
+ ulSmartConfigFinished = 0;
+ //
+ // Mask out all non-required events
+ //
+ wlan_set_event_mask(HCI_EVNT_WLAN_KEEPALIVE|HCI_EVNT_WLAN_UNSOL_INIT|HCI_EVNT_WLAN_ASYNC_PING_REPORT);
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebServer/cc3000.h Sat Sep 14 17:38:41 2013 +0000
@@ -0,0 +1,91 @@
+/*****************************************************************************
+*
+* cc3000.h - CC3000 Function Definitions
+* 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 CC3000_H
+#define CC3000_H
+
+#include "netapp.h"
+
+
+#define NUM_STATES 6
+#define FIRST_STATE_LED_NUM 1
+#define MAX_SSID_LEN 32
+
+// CC3000 State Machine Definitions
+enum cc3000StateEnum
+{
+ CC3000_UNINIT = 0x01, // CC3000 Driver Uninitialized
+ CC3000_INIT = 0x02, // CC3000 Driver Initialized
+ CC3000_ASSOC = 0x04, // CC3000 Associated to AP
+ CC3000_IP_ALLOC = 0x08, // CC3000 has IP Address
+ CC3000_SERVER_INIT = 0x10, // CC3000 Server Initialized
+};
+
+
+
+int ConnectUsingSSID(char * ssidName);
+void setupLocalSocket(void);
+void ConnectToServer(void);
+void ConnectToServer(void);
+
+
+char *sendDriverPatch(unsigned long *Length);
+char *sendBootLoaderPatch(unsigned long *Length);
+char *sendWLFWPatch(unsigned long *Length);
+
+void CC3000_UsynchCallback(long lEventType, char * data, unsigned char length);
+
+int initDriver(void);
+void StartSmartConfig(void);
+void closeLocalSocket(void);
+void disconnectAll();
+
+char isFTCSet();
+void setFTCFlag();
+
+
+// Machine State
+char currentCC3000State();
+void setCC3000MachineState(char stat);
+void unsetCC3000MachineState(char stat);
+void resetCC3000StateMachine();
+char highestCC3000State();
+//static void StartUnsolicitedEventTimer(void);
+static void DemoInitSpi(void);
+
+tNetappIpconfigRetArgs * getCC3000Info();
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebServer/config_defs.h Sat Sep 14 17:38:41 2013 +0000 @@ -0,0 +1,51 @@ +/***************************************************************************** +* +* config_defs.h - Common Configuration Definitions +* 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 CONFIG_DEFS +#define CONFIG_DEFS + + + +#define USE_DHCP 1 +#define USE_STATIC_IP 2 + +#define NONE 0 +#define WEP 1 +#define WPA 2 +#define WPA2 3 + + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebServer/demo_config.h Sat Sep 14 17:38:41 2013 +0000 @@ -0,0 +1,62 @@ +/***************************************************************************** +* +* demo_config.h - Sensor Demo Configuration File +* 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 DEMO_CONFIG_H +#define DEMO_CONFIG_H + +#include "config_defs.h" + +// +// Modify the following settings as necessary to run the demo +// + +#define IP_ALLOC_METHOD USE_DHCP +//#define USE_STATIC_IP + +// Default SSID Settings +#define DEFAULT_OUT_OF_BOX_SSID "TP-LINK" +#define AP_SECURITY WPA2 +#define AP_KEY "************" + +#if IP_ALLOC_METHOD == USE_STATIC_IP +#define STATIC_IP_OCT1 192 +#define STATIC_IP_OCT2 168 +#define STATIC_IP_OCT3 1 +#define STATIC_IP_OCT4 104 +#endif + +#define SERVER_PORT 1204 +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Sat Sep 14 17:38:41 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/9c8f0e3462fb \ No newline at end of file