cc3000 driver with expanded buffers.
Fork of cc3000_hostdriver_mbedsocket by
Diff: cc3000_event.cpp
- Revision:
- 20:30b6ed7bf8fd
- Parent:
- 17:14b6a3a2b622
- Child:
- 22:d23c59fec0dc
diff -r 9fdf8b4e41bf -r 30b6ed7bf8fd cc3000_event.cpp --- a/cc3000_event.cpp Thu Oct 03 09:49:03 2013 +0200 +++ b/cc3000_event.cpp Thu Oct 03 17:15:45 2013 +0200 @@ -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 *)¶ms, 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 { + +#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 *)¶ms, 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 */