summaryrefslogtreecommitdiffstatshomepage
path: root/stmhal/cc3k/evnt_handler.c
diff options
context:
space:
mode:
Diffstat (limited to 'stmhal/cc3k/evnt_handler.c')
-rw-r--r--stmhal/cc3k/evnt_handler.c873
1 files changed, 873 insertions, 0 deletions
diff --git a/stmhal/cc3k/evnt_handler.c b/stmhal/cc3k/evnt_handler.c
new file mode 100644
index 0000000000..5a75fadcc0
--- /dev/null
+++ b/stmhal/cc3k/evnt_handler.c
@@ -0,0 +1,873 @@
+/*****************************************************************************
+*
+* evnt_handler.c - CC3000 Host Driver Implementation.
+* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
+* & Limor Fried for Adafruit Industries
+* This library works with the Adafruit CC3000 breakout
+* ----> https://www.adafruit.com/products/1469
+* Adafruit invests time and resources providing this open source code,
+* please support Adafruit and open-source hardware by purchasing
+* products from Adafruit!
+*
+* 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 <stdint.h>
+
+#include "cc3000_common.h"
+#include "string.h"
+#include "hci.h"
+#include "evnt_handler.h"
+#include "wlan.h"
+#include "socket.h"
+#include "netapp.h"
+#include "ccspi.h"
+#include "ccdebug.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)
+ {
+ cc3k_int_poll();
+
+ 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);
+ //tBsdReadReturnParams *tread = (tBsdReadReturnParams *)pRetParams; // unused
+ 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);
+
+ DEBUGPRINT_F("\tHCI_UNSOL_EVT: ");
+ DEBUGPRINT_HEX16(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 *)&params, sizeof(params));
+ }
+ }
+ break;
+ case HCI_EVNT_BSD_TCP_CLOSE_WAIT:
+ {
+ DEBUGPRINT_F("\tTCP Close Wait\n\r");
+ uint8_t socketnum;
+ data = (char*)(event_hdr) + HCI_EVENT_HEADER_SIZE;
+ /*
+ printHex(data[0]); PRINT_F("\t");
+ printHex(data[1]); PRINT_F("\t");
+ printHex(data[2]); PRINT_F("\t");
+ printHex(data[3]); PRINT_F("\t");
+ printHex(data[4]); PRINT_F("\t");
+ printHex(data[5]); PRINT_F("\t");
+ */
+ socketnum = data[0];
+ //STREAM_TO_UINT16(data, 0, socketnum);
+ if( tSLInformation.sWlanCB )
+ {
+ tSLInformation.sWlanCB(event_type, (char *)&socketnum, 1);
+ }
+ }
+ 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;
+
+ DEBUGPRINT_F("\tSEND event response\n\r");
+
+ 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.
+//! @}
+//
+//*****************************************************************************