cc3000 driver with expanded buffers.

Fork of cc3000_hostdriver_mbedsocket by Martin Kojtal

Revision:
23:fed7f64dd520
Parent:
17:14b6a3a2b622
Child:
26:456f73ed2a75
diff -r fb34ac8d9af5 -r fed7f64dd520 cc3000_event.cpp
--- a/cc3000_event.cpp	Thu Oct 03 20:22:45 2013 +0000
+++ b/cc3000_event.cpp	Thu Oct 03 21:00:00 2013 +0000
@@ -1,664 +1,664 @@
-/*****************************************************************************
-*
-*  C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
-*  Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
-*  provided help.
-*
-*  This version of "host driver" uses CC3000 Host Driver Implementation. Thus
-*  read the following copyright:
-*
-*  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 "cc3000.h"
-#include "cc3000_event.h"
-#include "cc3000_netapp.h"
-
-namespace mbed_cc3000 {
-
-#if CC3000_DEBUG == 1
-const char *HCI_EVENT_STR[] =
-{
-    "Socket",
-    "Bind",
-    "Send",
-    "Recv",
-    "Accept",
-    "Listen",
-    "Connect",
-    "BSD Select",
-    "Set Socket Options",
-    "Get Socket Options",
-    "Close Socket",
-    "Unknown",
-    "Recv From",
-    "Write",
-    "Send To",
-    "Get Hostname",
-    "mDNS Advertise"
-};
-
-const char *HCI_NETAPP_STR[] =
-{
-    "DHCP",
-    "Ping Sent",
-    "Ping Report",
-    "Ping Stop",
-    "IP Config",
-    "ARP Flush",
-    "Unknown",
-    "Set Debug level",
-    "Set Timers"
-};
-
-// from 0-7
-const char *HCI_MISC_STR[] =
-{
-    "BASE - Error?",
-    "Connecting",
-    "Disconnect",
-    "Scan Param",
-    "Connect Policy",
-    "Add Profile",
-    "Del Profile",
-    "Get Scan Res",
-    "Event Mask",
-    "Status Req",
-    "Config Start",
-    "Config Stop",
-    "Config Set Prefix",
-    "Config Patch",
-};
-#endif
-
-cc3000_event::cc3000_event(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_spi &spi, cc3000 &cc3000)
-    : socket_active_status(SOCKET_STATUS_INIT_VAL), _simple_link(simplelink), _hci(hci), _spi(spi), _cc3000(cc3000) {
-
-}
-
-cc3000_event::~cc3000_event() {
-
-}
-
-/* TODO removed buffer, set it in init */
-void cc3000_event::received_handler(uint8_t *buffer) {
-    _simple_link.set_data_received_flag(1);
-    _simple_link.set_received_data(buffer);
-
-    hci_unsolicited_event_handler();
-}
-
-void cc3000_event::hci_unsol_handle_patch_request(uint8_t *event_hdr) {
-    uint8_t *params = (uint8_t *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
-    uint32_t length = 0;
-    uint8_t *patch;
-
-    switch (*params)
-    {
-        case HCI_EVENT_PATCHES_DRV_REQ:
-        {
-            tDriverPatches func_pointer = (tDriverPatches)_simple_link.get_func_pointer(DRIVER_PATCHES);
-            if (func_pointer)
-            {
-                patch = func_pointer(&length);
-                if (patch)
-                {
-                    _hci.patch_send(HCI_EVENT_PATCHES_DRV_REQ, _simple_link.get_transmit_buffer(), patch, length);
-                    return;
-                }
-            }
-
-            // Send 0 length Patches response event
-            _hci.patch_send(HCI_EVENT_PATCHES_DRV_REQ, _simple_link.get_transmit_buffer(), 0, 0);
-            break;
-        }
-        case HCI_EVENT_PATCHES_FW_REQ:
-        {
-            tFWPatches func_pointer = (tFWPatches)_simple_link.get_func_pointer(FW_PATCHES);
-            if (func_pointer)
-            {
-                patch = func_pointer(&length);
-                // Build and send a patch
-                if (patch)
-                {
-                    _hci.patch_send(HCI_EVENT_PATCHES_FW_REQ, _simple_link.get_transmit_buffer(), patch, length);
-                    return;
-                }
-            }
-            // Send 0 length Patches response event
-            _hci.patch_send(HCI_EVENT_PATCHES_FW_REQ, _simple_link.get_transmit_buffer(), 0, 0);
-            break;
-        }
-        case HCI_EVENT_PATCHES_BOOTLOAD_REQ:
-        {
-            tBootLoaderPatches func_pointer = (tBootLoaderPatches)_simple_link.get_func_pointer(BOOTLOADER_PATCHES);
-            if (func_pointer)
-            {
-                patch = func_pointer(&length);
-                if (patch)
-                {
-                    _hci.patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, _simple_link.get_transmit_buffer(), patch, length);
-                    return;
-                }
-            }
-            // Send 0 length Patches response event
-            _hci.patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, _simple_link.get_transmit_buffer(), 0, 0);
-            break;
-        }
-    }
-}
-
-static void hci_event_debug_print(uint16_t hciEventNo)
-{
-#if CC3000_DEBUG == 1
-    if ((hciEventNo > HCI_CMND_SOCKET_BASE) && ( hciEventNo <= HCI_CMND_MDNS_ADVERTISE))
-    {
-        DBG_HCI("Event Received : 0x%04X - %s", hciEventNo, HCI_EVENT_STR[hciEventNo-HCI_CMND_SOCKET]);
-    }
-    else if ((hciEventNo > HCI_CMND_NETAPP_BASE) && ( hciEventNo <= HCI_NETAPP_SET_TIMERS))
-    {
-        DBG_HCI("Event Received : 0x%04X - %s", hciEventNo, HCI_NETAPP_STR[hciEventNo-HCI_NETAPP_DHCP]);
-    }
-    else if (hciEventNo < HCI_CMND_WLAN_CONFIGURE_PATCH+1)
-    {
-        DBG_HCI("Event Received : 0x%04X - %s", hciEventNo, HCI_MISC_STR[hciEventNo]);
-    }
-    else
-    {
-        DBG_HCI("Event Received : 0x%04X", hciEventNo);
-    }
-#endif
-}
-
-uint8_t *cc3000_event::hci_event_handler(void *ret_param, uint8_t *from, uint8_t *fromlen) {
-    uint8_t *received_data, argument_size;
-    uint16_t length;
-    uint8_t *pucReceivedParams;
-    uint16_t received_op_code = 0;
-    uint32_t return_value;
-    uint8_t * RecvParams;
-    uint8_t *RetParams;
-
-    while (1)
-    {
-        if (_simple_link.get_data_received_flag() != 0)
-        {
-            received_data = _simple_link.get_received_data();
-            if (*received_data == HCI_TYPE_EVNT)
-            {
-                // Event Received
-                STREAM_TO_UINT16((uint8_t *)received_data, HCI_EVENT_OPCODE_OFFSET,received_op_code);
-                pucReceivedParams = received_data + HCI_EVENT_HEADER_SIZE;
-                RecvParams = pucReceivedParams;
-                RetParams = (uint8_t *)ret_param;
-
-                // unsolicited event received - finish handling
-                if (hci_unsol_event_handler((uint8_t *)received_data) == 0)
-                {
-                    STREAM_TO_UINT8(received_data, HCI_DATA_LENGTH_OFFSET, length);
-
-                    hci_event_debug_print( received_op_code );
-
-                    switch(received_op_code)
-                    {
-                    case HCI_CMND_READ_BUFFER_SIZE:
-                        {
-                            uint16_t temp = _simple_link.get_number_free_buffers();
-                            STREAM_TO_UINT8((uint8_t *)pucReceivedParams, 0, temp);
-                            _simple_link.set_number_free_buffers(temp);
-
-                            temp = _simple_link.get_buffer_length();
-                            STREAM_TO_UINT16((uint8_t *)pucReceivedParams, 1, temp);
-                            _simple_link.set_buffer_length(temp);
-                        }
-                        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(received_data, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)ret_param);
-                        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((uint8_t *)pucReceivedParams,0, *(uint32_t *)ret_param);
-                        break;
-
-                    case HCI_EVNT_READ_SP_VERSION:
-
-                        STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)ret_param);
-                        ret_param = ((uint8_t *)ret_param) + 1;
-                        STREAM_TO_UINT32((uint8_t *)pucReceivedParams, 0, return_value);
-                        UINT32_TO_STREAM((uint8_t *)ret_param, return_value);
-                        break;
-
-                    case HCI_EVNT_BSD_GETHOSTBYNAME:
-
-                        STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_HOST_BY_NAME_RETVAL_OFFSET,*(uint32_t *)ret_param);
-                        ret_param = ((uint8_t *)ret_param) + 4;
-                        STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_HOST_BY_NAME_ADDR_OFFSET,*(uint32_t *)ret_param);
-                        break;
-
-                    case HCI_EVNT_ACCEPT:
-                        {
-                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,ACCEPT_SD_OFFSET,*(uint32_t *)ret_param);
-                            ret_param = ((uint8_t *)ret_param) + 4;
-                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,ACCEPT_RETURN_STATUS_OFFSET,*(uint32_t *)ret_param);
-                            ret_param = ((uint8_t *)ret_param) + 4;
-
-                            //This argument returns in network order
-                            memcpy((uint8_t *)ret_param, pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr));
-                            break;
-                        }
-
-                    case HCI_EVNT_RECV:
-                    case HCI_EVNT_RECVFROM:
-                        {
-                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(uint32_t *)ret_param);
-                            ret_param = ((uint8_t *)ret_param) + 4;
-                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(uint32_t *)ret_param);
-                            ret_param = ((uint8_t *)ret_param) + 4;
-                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(uint32_t *)ret_param);
-
-                            if(((tBsdReadReturnParams *)ret_param)->iNumberOfBytes == ERROR_SOCKET_INACTIVE)
-                            {
-                                set_socket_active_status(((tBsdReadReturnParams *)ret_param)->iSocketDescriptor,SOCKET_STATUS_INACTIVE);
-                            }
-                            break;
-                        }
-
-                    case HCI_EVNT_SEND:
-                    case HCI_EVNT_SENDTO:
-                        {
-                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(uint32_t *)ret_param);
-                            ret_param = ((uint8_t *)ret_param) + 4;
-                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(uint32_t *)ret_param);
-                            ret_param = ((uint8_t *)ret_param) + 4;
-
-                            break;
-                        }
-
-                    case HCI_EVNT_SELECT:
-                        {
-                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_STATUS_OFFSET,*(uint32_t *)ret_param);
-                            ret_param = ((uint8_t *)ret_param) + 4;
-                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_READFD_OFFSET,*(uint32_t *)ret_param);
-                            ret_param = ((uint8_t *)ret_param) + 4;
-                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(uint32_t *)ret_param);
-                            ret_param = ((uint8_t *)ret_param) + 4;
-                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_EXFD_OFFSET,*(uint32_t *)ret_param);
-                            break;
-                        }
-
-                    case HCI_CMND_GETSOCKOPT:
-
-                        STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)ret_param)->iStatus);
-                        //This argument returns in network order
-                        memcpy((uint8_t *)ret_param, pucReceivedParams, 4);
-                        break;
-
-                    case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS:
-
-                        STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(uint32_t *)ret_param);
-                        ret_param = ((uint8_t *)ret_param) + 4;
-                        STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(uint32_t *)ret_param);
-                        ret_param = ((uint8_t *)ret_param) + 4;
-                        STREAM_TO_UINT16((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(uint32_t *)ret_param);
-                        ret_param = ((uint8_t *)ret_param) + 2;
-                        STREAM_TO_UINT16((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(uint32_t *)ret_param);
-                        ret_param = ((uint8_t *)ret_param) + 2;
-                        memcpy((uint8_t *)ret_param, (uint8_t *)(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 (received_op_code == _simple_link.get_op_code())
-                {
-                    _simple_link.set_op_code(0);
-                }
-            }
-            else
-            {
-                pucReceivedParams = received_data;
-                STREAM_TO_UINT8((uint8_t *)received_data, HCI_PACKET_ARGSIZE_OFFSET, argument_size);
-
-                STREAM_TO_UINT16((uint8_t *)received_data, HCI_PACKET_LENGTH_OFFSET, length);
-
-                // 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((uint8_t *)(received_data + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(uint32_t *)fromlen);
-                    memcpy(from, (received_data + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen);
-                }
-
-                memcpy(ret_param, pucReceivedParams + HCI_DATA_HEADER_SIZE + argument_size, length - argument_size);
-
-                _simple_link.set_pending_data(0);
-            }
-
-            _simple_link.set_data_received_flag(0);
-
-            //tWlanInterruptEnable func_pointer = (tWlanInterruptEnable)_simple_link.get_func_pointer(WLAN_INTERRUPT_ENABLE);
-            //func_pointer();
-            _spi.wlan_irq_enable();
-
-            // Since we are going to TX - we need to handle this event after the ResumeSPi since we need interrupts
-            if ((*received_data == HCI_TYPE_EVNT) && (received_op_code == HCI_EVNT_PATCHES_REQ))
-            {
-                hci_unsol_handle_patch_request((uint8_t *)received_data);
-            }
-            if ((_simple_link.get_op_code() == 0) && (_simple_link.get_pending_data() == 0))
-            {
-                return NULL;
-            }
-        }
-    }
-}
-
-int32_t cc3000_event::hci_unsol_event_handler(uint8_t *event_hdr) {
-    uint8_t *data = NULL;
-    int32_t event_type;
-    uint32_t number_of_released_packets;
-    uint32_t number_of_sent_packets;
-
-    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);
-
-                number_of_released_packets = _simple_link.get_released_packets();
-                number_of_sent_packets = _simple_link.get_sent_packets();
-
-                if (number_of_released_packets == number_of_sent_packets)
-                {
-                    if (_simple_link.get_tx_complete_signal())
-                    {
-                        //tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB);
-                        _cc3000.usync_callback(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:
-            // {
-                // tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB);
-                // if( func_pointer )
-                // {
-                //     func_pointer(event_type, 0, 0);
-                // }
-                _cc3000.usync_callback(event_type, 0, 0);
-                break;
-            // }
-            case HCI_EVNT_WLAN_UNSOL_DHCP:
-            {
-                uint8_t params[NETAPP_IPCONFIG_MAC_OFFSET + 1]; // extra byte is for the status
-                uint8_t *recParams = params;
-                data = (uint8_t *)(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);
-
-                // tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB);
-                // if( func_pointer )
-                // {
-                    _cc3000.usync_callback(event_type, (uint8_t  *)params, sizeof(params));
-                // }
-                break;
-            }
-            case HCI_EVNT_WLAN_ASYNC_PING_REPORT:
-            {
-                netapp_pingreport_args_t params;
-                data = (uint8_t *)(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);
-
-                // tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB);
-                // if (func_pointer)
-                // {
-                    _cc3000.usync_callback(event_type, (uint8_t  *)&params, sizeof(params));
-                // }
-                break;
-            }
-            case HCI_EVNT_BSD_TCP_CLOSE_WAIT:
-            {
-                // tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB);
-                // if (func_pointer)
-                // {
-                    _cc3000.usync_callback(event_type, NULL, 0);
-                // }
-                break;
-            }
-
-            //'default' case which means "event not supported"
-            default:
-                return (0);
-        }
-        return(1);
-    }
-
-    if ((event_type == HCI_EVNT_SEND) || (event_type == HCI_EVNT_SENDTO) || (event_type == HCI_EVNT_WRITE)) {
-        uint8_t *pArg;
-        int32_t 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
-            int32_t transmit_error  = _simple_link.get_transmit_error();
-            STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, transmit_error);
-            _simple_link.set_transmit_error(transmit_error);
-            update_socket_active_status(M_BSD_RESP_PARAMS_OFFSET(event_hdr));
-            return (1);
-        }
-        else {
-            return (0);
-        }
-    }
-    return(0);
-}
-
-int32_t cc3000_event::hci_unsolicited_event_handler(void) {
-    uint32_t res = 0;
-    uint8_t *received_data;
-
-    if (_simple_link.get_data_received_flag() != 0) {
-        received_data = (_simple_link.get_received_data());
-
-        if (*received_data == HCI_TYPE_EVNT) {
-            // unsolicited event received - finish handling
-            if (hci_unsol_event_handler((uint8_t *)received_data) == 1) {
-                // An unsolicited event was received:
-                // release the buffer and clean the event received
-                _simple_link.set_data_received_flag(0);
-
-                res = 1;
-                _spi.wlan_irq_enable();
-            }
-        }
-    }
-    return res;
-}
-
-void cc3000_event::set_socket_active_status(int32_t sd, int32_t 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 */
-    }
-}
-
-int32_t cc3000_event::hci_event_unsol_flowcontrol_handler(uint8_t *event) {
-    int32_t temp, value;
-    uint16_t i;
-    uint16_t pusNumberOfHandles=0;
-    uint8_t *pReadPayload;
-
-    STREAM_TO_UINT16((uint8_t *)event,HCI_EVENT_HEADER_SIZE,pusNumberOfHandles);
-    pReadPayload = ((uint8_t *)event + 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;
-    }
-
-    _simple_link.set_number_free_buffers(_simple_link.get_number_free_buffers() + temp);
-    _simple_link.set_number_of_released_packets(_simple_link.get_released_packets() + temp);
-
-    return(ESUCCESS);
-}
-
-int32_t cc3000_event::get_socket_active_status(int32_t sd) {
-    if(M_IS_VALID_SD(sd)) {
-        return (socket_active_status & (1 << sd)) ? SOCKET_STATUS_INACTIVE : SOCKET_STATUS_ACTIVE;
-    } else {
-        return SOCKET_STATUS_INACTIVE;
-    }
-}
-
-void cc3000_event::update_socket_active_status(uint8_t *resp_params) {
-    int32_t 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);
-    }
-}
-
-void cc3000_event::simplelink_wait_event(uint16_t op_code, void *ret_param) {
-    // In the blocking implementation the control to caller will be returned only
-    // after the end of current transaction
-    _simple_link.set_op_code(op_code);
-    hci_event_handler(ret_param, 0, 0);
-}
-
-void cc3000_event::simplelink_wait_data(uint8_t *pBuf, uint8_t *from, uint8_t *fromlen) {
-    // In the blocking implementation the control to caller will be returned only
-    // after the end of current transaction, i.e. only after data will be received
-    _simple_link.set_pending_data(1);
-    hci_event_handler(pBuf, from, fromlen);
-}
-
-
-} /* end of cc3000 namespace */
+/*****************************************************************************
+*
+*  C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
+*  Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
+*  provided help.
+*
+*  This version of "host driver" uses CC3000 Host Driver Implementation. Thus
+*  read the following copyright:
+*
+*  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 "cc3000.h"
+#include "cc3000_event.h"
+#include "cc3000_netapp.h"
+
+namespace mbed_cc3000 {
+
+#ifdef CC3000_DEBUG_HCI_RX
+const char *HCI_EVENT_STR[] =
+{
+    "Socket",
+    "Bind",
+    "Send",
+    "Recv",
+    "Accept",
+    "Listen",
+    "Connect",
+    "BSD Select",
+    "Set Socket Options",
+    "Get Socket Options",
+    "Close Socket",
+    "Unknown",
+    "Recv From",
+    "Write",
+    "Send To",
+    "Get Hostname",
+    "mDNS Advertise"
+};
+
+const char *HCI_NETAPP_STR[] =
+{
+    "DHCP",
+    "Ping Sent",
+    "Ping Report",
+    "Ping Stop",
+    "IP Config",
+    "ARP Flush",
+    "Unknown",
+    "Set Debug level",
+    "Set Timers"
+};
+
+// from 0-7
+const char *HCI_MISC_STR[] =
+{
+    "BASE - Error?",
+    "Connecting",
+    "Disconnect",
+    "Scan Param",
+    "Connect Policy",
+    "Add Profile",
+    "Del Profile",
+    "Get Scan Res",
+    "Event Mask",
+    "Status Req",
+    "Config Start",
+    "Config Stop",
+    "Config Set Prefix",
+    "Config Patch",
+};
+#endif
+
+cc3000_event::cc3000_event(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_spi &spi, cc3000 &cc3000)
+    : socket_active_status(SOCKET_STATUS_INIT_VAL), _simple_link(simplelink), _hci(hci), _spi(spi), _cc3000(cc3000) {
+
+}
+
+cc3000_event::~cc3000_event() {
+
+}
+
+/* TODO removed buffer, set it in init */
+void cc3000_event::received_handler(uint8_t *buffer) {
+    _simple_link.set_data_received_flag(1);
+    _simple_link.set_received_data(buffer);
+
+    hci_unsolicited_event_handler();
+}
+
+void cc3000_event::hci_unsol_handle_patch_request(uint8_t *event_hdr) {
+    uint8_t *params = (uint8_t *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
+    uint32_t length = 0;
+    uint8_t *patch;
+
+    switch (*params)
+    {
+        case HCI_EVENT_PATCHES_DRV_REQ:
+        {
+            tDriverPatches func_pointer = (tDriverPatches)_simple_link.get_func_pointer(DRIVER_PATCHES);
+            if (func_pointer)
+            {
+                patch = func_pointer(&length);
+                if (patch)
+                {
+                    _hci.patch_send(HCI_EVENT_PATCHES_DRV_REQ, _simple_link.get_transmit_buffer(), patch, length);
+                    return;
+                }
+            }
+
+            // Send 0 length Patches response event
+            _hci.patch_send(HCI_EVENT_PATCHES_DRV_REQ, _simple_link.get_transmit_buffer(), 0, 0);
+            break;
+        }
+        case HCI_EVENT_PATCHES_FW_REQ:
+        {
+            tFWPatches func_pointer = (tFWPatches)_simple_link.get_func_pointer(FW_PATCHES);
+            if (func_pointer)
+            {
+                patch = func_pointer(&length);
+                // Build and send a patch
+                if (patch)
+                {
+                    _hci.patch_send(HCI_EVENT_PATCHES_FW_REQ, _simple_link.get_transmit_buffer(), patch, length);
+                    return;
+                }
+            }
+            // Send 0 length Patches response event
+            _hci.patch_send(HCI_EVENT_PATCHES_FW_REQ, _simple_link.get_transmit_buffer(), 0, 0);
+            break;
+        }
+        case HCI_EVENT_PATCHES_BOOTLOAD_REQ:
+        {
+            tBootLoaderPatches func_pointer = (tBootLoaderPatches)_simple_link.get_func_pointer(BOOTLOADER_PATCHES);
+            if (func_pointer)
+            {
+                patch = func_pointer(&length);
+                if (patch)
+                {
+                    _hci.patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, _simple_link.get_transmit_buffer(), patch, length);
+                    return;
+                }
+            }
+            // Send 0 length Patches response event
+            _hci.patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, _simple_link.get_transmit_buffer(), 0, 0);
+            break;
+        }
+    }
+}
+
+static void hci_event_debug_print(uint16_t hciEventNo)
+{
+#ifdef CC3000_DEBUG_HCI_RX
+    if ((hciEventNo > HCI_CMND_SOCKET_BASE) && ( hciEventNo <= HCI_CMND_MDNS_ADVERTISE))
+    {
+        DBG_HCI("Event Received : 0x%04X - %s", hciEventNo, HCI_EVENT_STR[hciEventNo-HCI_CMND_SOCKET]);
+    }
+    else if ((hciEventNo > HCI_CMND_NETAPP_BASE) && ( hciEventNo <= HCI_NETAPP_SET_TIMERS))
+    {
+        DBG_HCI("Event Received : 0x%04X - %s", hciEventNo, HCI_NETAPP_STR[hciEventNo-HCI_NETAPP_DHCP]);
+    }
+    else if (hciEventNo < HCI_CMND_WLAN_CONFIGURE_PATCH+1)
+    {
+        DBG_HCI("Event Received : 0x%04X - %s", hciEventNo, HCI_MISC_STR[hciEventNo]);
+    }
+    else
+    {
+        DBG_HCI("Event Received : 0x%04X", hciEventNo);
+    }
+#endif
+}
+
+uint8_t *cc3000_event::hci_event_handler(void *ret_param, uint8_t *from, uint8_t *fromlen) {
+    uint8_t *received_data, argument_size;
+    uint16_t length;
+    uint8_t *pucReceivedParams;
+    uint16_t received_op_code = 0;
+    uint32_t return_value;
+    uint8_t * RecvParams;
+    uint8_t *RetParams;
+
+    while (1)
+    {
+        if (_simple_link.get_data_received_flag() != 0)
+        {
+            received_data = _simple_link.get_received_data();
+            if (*received_data == HCI_TYPE_EVNT)
+            {
+                // Event Received
+                STREAM_TO_UINT16((uint8_t *)received_data, HCI_EVENT_OPCODE_OFFSET,received_op_code);
+                pucReceivedParams = received_data + HCI_EVENT_HEADER_SIZE;
+                RecvParams = pucReceivedParams;
+                RetParams = (uint8_t *)ret_param;
+
+                // unsolicited event received - finish handling
+                if (hci_unsol_event_handler((uint8_t *)received_data) == 0)
+                {
+                    STREAM_TO_UINT8(received_data, HCI_DATA_LENGTH_OFFSET, length);
+
+                    hci_event_debug_print( received_op_code );
+
+                    switch(received_op_code)
+                    {
+                    case HCI_CMND_READ_BUFFER_SIZE:
+                        {
+                            uint16_t temp = _simple_link.get_number_free_buffers();
+                            STREAM_TO_UINT8((uint8_t *)pucReceivedParams, 0, temp);
+                            _simple_link.set_number_free_buffers(temp);
+
+                            temp = _simple_link.get_buffer_length();
+                            STREAM_TO_UINT16((uint8_t *)pucReceivedParams, 1, temp);
+                            _simple_link.set_buffer_length(temp);
+                        }
+                        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(received_data, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)ret_param);
+                        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((uint8_t *)pucReceivedParams,0, *(uint32_t *)ret_param);
+                        break;
+
+                    case HCI_EVNT_READ_SP_VERSION:
+
+                        STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)ret_param);
+                        ret_param = ((uint8_t *)ret_param) + 1;
+                        STREAM_TO_UINT32((uint8_t *)pucReceivedParams, 0, return_value);
+                        UINT32_TO_STREAM((uint8_t *)ret_param, return_value);
+                        break;
+
+                    case HCI_EVNT_BSD_GETHOSTBYNAME:
+
+                        STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_HOST_BY_NAME_RETVAL_OFFSET,*(uint32_t *)ret_param);
+                        ret_param = ((uint8_t *)ret_param) + 4;
+                        STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_HOST_BY_NAME_ADDR_OFFSET,*(uint32_t *)ret_param);
+                        break;
+
+                    case HCI_EVNT_ACCEPT:
+                        {
+                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,ACCEPT_SD_OFFSET,*(uint32_t *)ret_param);
+                            ret_param = ((uint8_t *)ret_param) + 4;
+                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,ACCEPT_RETURN_STATUS_OFFSET,*(uint32_t *)ret_param);
+                            ret_param = ((uint8_t *)ret_param) + 4;
+
+                            //This argument returns in network order
+                            memcpy((uint8_t *)ret_param, pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr));
+                            break;
+                        }
+
+                    case HCI_EVNT_RECV:
+                    case HCI_EVNT_RECVFROM:
+                        {
+                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(uint32_t *)ret_param);
+                            ret_param = ((uint8_t *)ret_param) + 4;
+                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(uint32_t *)ret_param);
+                            ret_param = ((uint8_t *)ret_param) + 4;
+                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(uint32_t *)ret_param);
+
+                            if(((tBsdReadReturnParams *)ret_param)->iNumberOfBytes == ERROR_SOCKET_INACTIVE)
+                            {
+                                set_socket_active_status(((tBsdReadReturnParams *)ret_param)->iSocketDescriptor,SOCKET_STATUS_INACTIVE);
+                            }
+                            break;
+                        }
+
+                    case HCI_EVNT_SEND:
+                    case HCI_EVNT_SENDTO:
+                        {
+                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(uint32_t *)ret_param);
+                            ret_param = ((uint8_t *)ret_param) + 4;
+                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(uint32_t *)ret_param);
+                            ret_param = ((uint8_t *)ret_param) + 4;
+
+                            break;
+                        }
+
+                    case HCI_EVNT_SELECT:
+                        {
+                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_STATUS_OFFSET,*(uint32_t *)ret_param);
+                            ret_param = ((uint8_t *)ret_param) + 4;
+                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_READFD_OFFSET,*(uint32_t *)ret_param);
+                            ret_param = ((uint8_t *)ret_param) + 4;
+                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(uint32_t *)ret_param);
+                            ret_param = ((uint8_t *)ret_param) + 4;
+                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_EXFD_OFFSET,*(uint32_t *)ret_param);
+                            break;
+                        }
+
+                    case HCI_CMND_GETSOCKOPT:
+
+                        STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)ret_param)->iStatus);
+                        //This argument returns in network order
+                        memcpy((uint8_t *)ret_param, pucReceivedParams, 4);
+                        break;
+
+                    case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS:
+
+                        STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(uint32_t *)ret_param);
+                        ret_param = ((uint8_t *)ret_param) + 4;
+                        STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(uint32_t *)ret_param);
+                        ret_param = ((uint8_t *)ret_param) + 4;
+                        STREAM_TO_UINT16((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(uint32_t *)ret_param);
+                        ret_param = ((uint8_t *)ret_param) + 2;
+                        STREAM_TO_UINT16((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(uint32_t *)ret_param);
+                        ret_param = ((uint8_t *)ret_param) + 2;
+                        memcpy((uint8_t *)ret_param, (uint8_t *)(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 (received_op_code == _simple_link.get_op_code())
+                {
+                    _simple_link.set_op_code(0);
+                }
+            }
+            else
+            {
+                pucReceivedParams = received_data;
+                STREAM_TO_UINT8((uint8_t *)received_data, HCI_PACKET_ARGSIZE_OFFSET, argument_size);
+
+                STREAM_TO_UINT16((uint8_t *)received_data, HCI_PACKET_LENGTH_OFFSET, length);
+
+                // 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((uint8_t *)(received_data + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(uint32_t *)fromlen);
+                    memcpy(from, (received_data + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen);
+                }
+
+                memcpy(ret_param, pucReceivedParams + HCI_DATA_HEADER_SIZE + argument_size, length - argument_size);
+
+                _simple_link.set_pending_data(0);
+            }
+
+            _simple_link.set_data_received_flag(0);
+
+            //tWlanInterruptEnable func_pointer = (tWlanInterruptEnable)_simple_link.get_func_pointer(WLAN_INTERRUPT_ENABLE);
+            //func_pointer();
+            _spi.wlan_irq_enable();
+
+            // Since we are going to TX - we need to handle this event after the ResumeSPi since we need interrupts
+            if ((*received_data == HCI_TYPE_EVNT) && (received_op_code == HCI_EVNT_PATCHES_REQ))
+            {
+                hci_unsol_handle_patch_request((uint8_t *)received_data);
+            }
+            if ((_simple_link.get_op_code() == 0) && (_simple_link.get_pending_data() == 0))
+            {
+                return NULL;
+            }
+        }
+    }
+}
+
+int32_t cc3000_event::hci_unsol_event_handler(uint8_t *event_hdr) {
+    uint8_t *data = NULL;
+    int32_t event_type;
+    uint32_t number_of_released_packets;
+    uint32_t number_of_sent_packets;
+
+    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);
+
+                number_of_released_packets = _simple_link.get_released_packets();
+                number_of_sent_packets = _simple_link.get_sent_packets();
+
+                if (number_of_released_packets == number_of_sent_packets)
+                {
+                    if (_simple_link.get_tx_complete_signal())
+                    {
+                        //tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB);
+                        _cc3000.usync_callback(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:
+            // {
+                // tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB);
+                // if( func_pointer )
+                // {
+                //     func_pointer(event_type, 0, 0);
+                // }
+                _cc3000.usync_callback(event_type, 0, 0);
+                break;
+            // }
+            case HCI_EVNT_WLAN_UNSOL_DHCP:
+            {
+                uint8_t params[NETAPP_IPCONFIG_MAC_OFFSET + 1]; // extra byte is for the status
+                uint8_t *recParams = params;
+                data = (uint8_t *)(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);
+
+                // tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB);
+                // if( func_pointer )
+                // {
+                    _cc3000.usync_callback(event_type, (uint8_t  *)params, sizeof(params));
+                // }
+                break;
+            }
+            case HCI_EVNT_WLAN_ASYNC_PING_REPORT:
+            {
+                netapp_pingreport_args_t params;
+                data = (uint8_t *)(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);
+
+                // tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB);
+                // if (func_pointer)
+                // {
+                    _cc3000.usync_callback(event_type, (uint8_t  *)&params, sizeof(params));
+                // }
+                break;
+            }
+            case HCI_EVNT_BSD_TCP_CLOSE_WAIT:
+            {
+                // tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB);
+                // if (func_pointer)
+                // {
+                    _cc3000.usync_callback(event_type, NULL, 0);
+                // }
+                break;
+            }
+
+            //'default' case which means "event not supported"
+            default:
+                return (0);
+        }
+        return(1);
+    }
+
+    if ((event_type == HCI_EVNT_SEND) || (event_type == HCI_EVNT_SENDTO) || (event_type == HCI_EVNT_WRITE)) {
+        uint8_t *pArg;
+        int32_t 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
+            int32_t transmit_error  = _simple_link.get_transmit_error();
+            STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, transmit_error);
+            _simple_link.set_transmit_error(transmit_error);
+            update_socket_active_status(M_BSD_RESP_PARAMS_OFFSET(event_hdr));
+            return (1);
+        }
+        else {
+            return (0);
+        }
+    }
+    return(0);
+}
+
+int32_t cc3000_event::hci_unsolicited_event_handler(void) {
+    uint32_t res = 0;
+    uint8_t *received_data;
+
+    if (_simple_link.get_data_received_flag() != 0) {
+        received_data = (_simple_link.get_received_data());
+
+        if (*received_data == HCI_TYPE_EVNT) {
+            // unsolicited event received - finish handling
+            if (hci_unsol_event_handler((uint8_t *)received_data) == 1) {
+                // An unsolicited event was received:
+                // release the buffer and clean the event received
+                _simple_link.set_data_received_flag(0);
+
+                res = 1;
+                _spi.wlan_irq_enable();
+            }
+        }
+    }
+    return res;
+}
+
+void cc3000_event::set_socket_active_status(int32_t sd, int32_t 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 */
+    }
+}
+
+int32_t cc3000_event::hci_event_unsol_flowcontrol_handler(uint8_t *event) {
+    int32_t temp, value;
+    uint16_t i;
+    uint16_t pusNumberOfHandles=0;
+    uint8_t *pReadPayload;
+
+    STREAM_TO_UINT16((uint8_t *)event,HCI_EVENT_HEADER_SIZE,pusNumberOfHandles);
+    pReadPayload = ((uint8_t *)event + 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;
+    }
+
+    _simple_link.set_number_free_buffers(_simple_link.get_number_free_buffers() + temp);
+    _simple_link.set_number_of_released_packets(_simple_link.get_released_packets() + temp);
+
+    return(ESUCCESS);
+}
+
+int32_t cc3000_event::get_socket_active_status(int32_t sd) {
+    if(M_IS_VALID_SD(sd)) {
+        return (socket_active_status & (1 << sd)) ? SOCKET_STATUS_INACTIVE : SOCKET_STATUS_ACTIVE;
+    } else {
+        return SOCKET_STATUS_INACTIVE;
+    }
+}
+
+void cc3000_event::update_socket_active_status(uint8_t *resp_params) {
+    int32_t 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);
+    }
+}
+
+void cc3000_event::simplelink_wait_event(uint16_t op_code, void *ret_param) {
+    // In the blocking implementation the control to caller will be returned only
+    // after the end of current transaction
+    _simple_link.set_op_code(op_code);
+    hci_event_handler(ret_param, 0, 0);
+}
+
+void cc3000_event::simplelink_wait_data(uint8_t *pBuf, uint8_t *from, uint8_t *fromlen) {
+    // In the blocking implementation the control to caller will be returned only
+    // after the end of current transaction, i.e. only after data will be received
+    _simple_link.set_pending_data(1);
+    hci_event_handler(pBuf, from, fromlen);
+}
+
+
+} /* end of cc3000 namespace */