Added mutex for multiple SPI devices on the same SPI bus
Fork of cc3000_hostdriver_mbedsocket by
Diff: cc3000_event.cpp
- Revision:
- 20:30b6ed7bf8fd
- Parent:
- 17:14b6a3a2b622
- Child:
- 22:d23c59fec0dc
--- 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 */
