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

Dependents:   CC3000Test

Revision:
0:9cb694f00b7b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/evnt_handler.cpp	Fri Aug 02 15:06:15 2013 +0000
@@ -0,0 +1,857 @@
+/*****************************************************************************
+*
+*  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 "mbed.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 *
+hci_event_handler(char *pRetParams, unsigned char *from, unsigned char *fromlen)
+{
+    unsigned char *pucReceivedData, ucArgsize;
+    unsigned short usLength = 0;
+    unsigned char *pucReceivedParams;
+    unsigned short usReceivedEventOpcode = 0;
+    unsigned long retValue32;
+  unsigned char * RecvParams;
+  char *RetParams;
+    
+    
+    while (1)
+    {
+    
+        if (tSLInformation.usEventOrDataReceived != 0)
+        { 
+                  
+            pucReceivedData = (tSLInformation.pucReceivedData);
+            
+            
+            if (*pucReceivedData == HCI_TYPE_EVNT)
+            {
+                
+                // Event Received
+                STREAM_TO_UINT16((char *)pucReceivedData, HCI_EVENT_OPCODE_OFFSET, usReceivedEventOpcode);
+                pucReceivedParams = pucReceivedData + HCI_EVENT_HEADER_SIZE;        
+                RecvParams = pucReceivedParams;
+                RetParams = 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 *)&params, 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, long* 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((char*)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((char*)pBuf, from, fromlen);
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
+