David Fletcher / Mbed 2 deprecated CC3000WebServer

Dependencies:   mbed

Revision:
0:6ad60d78b315
diff -r 000000000000 -r 6ad60d78b315 CC3000HostDriver/evnt_handler.cpp
--- /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 *)&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, 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.
+//! @}
+//
+//*****************************************************************************
+