Jack Berkhout / cc3000_hostdriver_mbedsocket

Fork of cc3000_hostdriver_mbedsocket by Martin Kojtal

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cc3000_event.cpp Source File

cc3000_event.cpp

00001 /*****************************************************************************
00002 *
00003 *  C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
00004 *  Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
00005 *  provided help.
00006 *
00007 *  This version of "host driver" uses CC3000 Host Driver Implementation. Thus
00008 *  read the following copyright:
00009 *
00010 *  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
00011 *
00012 *  Redistribution and use in source and binary forms, with or without
00013 *  modification, are permitted provided that the following conditions
00014 *  are met:
00015 *
00016 *    Redistributions of source code must retain the above copyright
00017 *    notice, this list of conditions and the following disclaimer.
00018 *
00019 *    Redistributions in binary form must reproduce the above copyright
00020 *    notice, this list of conditions and the following disclaimer in the
00021 *    documentation and/or other materials provided with the
00022 *    distribution.
00023 *
00024 *    Neither the name of Texas Instruments Incorporated nor the names of
00025 *    its contributors may be used to endorse or promote products derived
00026 *    from this software without specific prior written permission.
00027 *
00028 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00029 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00030 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00031 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00032 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00033 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00034 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00035 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00036 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00037 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00038 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00039 *
00040 *****************************************************************************/
00041 #include "cc3000.h"
00042 #include "cc3000_event.h"
00043 #include "cc3000_netapp.h"
00044 
00045 namespace mbed_cc3000 {
00046 
00047 #if (CC3000_DEBUG_HCI_RX == 1)
00048 const char *HCI_EVENT_STR[] =
00049 {
00050     "Socket",
00051     "Bind",
00052     "Send",
00053     "Recv",
00054     "Accept",
00055     "Listen",
00056     "Connect",
00057     "BSD Select",
00058     "Set Socket Options",
00059     "Get Socket Options",
00060     "Close Socket",
00061     "Unknown",
00062     "Recv From",
00063     "Write",
00064     "Send To",
00065     "Get Hostname",
00066     "mDNS Advertise"
00067 };
00068 
00069 const char *HCI_NETAPP_STR[] =
00070 {
00071     "DHCP",
00072     "Ping Sent",
00073     "Ping Report",
00074     "Ping Stop",
00075     "IP Config",
00076     "ARP Flush",
00077     "Unknown",
00078     "Set Debug level",
00079     "Set Timers"
00080 };
00081 
00082 // from 0-7
00083 const char *HCI_MISC_STR[] =
00084 {
00085     "BASE - Error?",
00086     "Connecting",
00087     "Disconnect",
00088     "Scan Param",
00089     "Connect Policy",
00090     "Add Profile",
00091     "Del Profile",
00092     "Get Scan Res",
00093     "Event Mask",
00094     "Status Req",
00095     "Config Start",
00096     "Config Stop",
00097     "Config Set Prefix",
00098     "Config Patch",
00099 };
00100 #endif
00101 
00102 cc3000_event::cc3000_event(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_spi &spi, cc3000 &cc3000)
00103     : socket_active_status(SOCKET_STATUS_INIT_VAL), _simple_link(simplelink), _hci(hci), _spi(spi), _cc3000(cc3000) {
00104 
00105 }
00106 
00107 cc3000_event::~cc3000_event() {
00108 
00109 }
00110 
00111 /* TODO removed buffer, set it in init */
00112 void cc3000_event::received_handler(uint8_t *buffer) {
00113     _simple_link.set_data_received_flag(1);
00114     _simple_link.set_received_data(buffer);
00115 
00116     hci_unsolicited_event_handler();
00117 }
00118 
00119 void cc3000_event::hci_unsol_handle_patch_request(uint8_t *event_hdr) {
00120     uint8_t *params = (uint8_t *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
00121     uint32_t length = 0;
00122     uint8_t *patch;
00123 
00124     switch (*params)
00125     {
00126         case HCI_EVENT_PATCHES_DRV_REQ:
00127         {
00128             tDriverPatches func_pointer = (tDriverPatches)_simple_link.get_func_pointer(DRIVER_PATCHES);
00129             if (func_pointer)
00130             {
00131                 patch = func_pointer(&length);
00132                 if (patch)
00133                 {
00134                     _hci.patch_send(HCI_EVENT_PATCHES_DRV_REQ, _simple_link.get_transmit_buffer(), patch, length);
00135                     return;
00136                 }
00137             }
00138 
00139             // Send 0 length Patches response event
00140             _hci.patch_send(HCI_EVENT_PATCHES_DRV_REQ, _simple_link.get_transmit_buffer(), 0, 0);
00141             break;
00142         }
00143         case HCI_EVENT_PATCHES_FW_REQ:
00144         {
00145             tFWPatches func_pointer = (tFWPatches)_simple_link.get_func_pointer(FW_PATCHES);
00146             if (func_pointer)
00147             {
00148                 patch = func_pointer(&length);
00149                 // Build and send a patch
00150                 if (patch)
00151                 {
00152                     _hci.patch_send(HCI_EVENT_PATCHES_FW_REQ, _simple_link.get_transmit_buffer(), patch, length);
00153                     return;
00154                 }
00155             }
00156             // Send 0 length Patches response event
00157             _hci.patch_send(HCI_EVENT_PATCHES_FW_REQ, _simple_link.get_transmit_buffer(), 0, 0);
00158             break;
00159         }
00160         case HCI_EVENT_PATCHES_BOOTLOAD_REQ:
00161         {
00162             tBootLoaderPatches func_pointer = (tBootLoaderPatches)_simple_link.get_func_pointer(BOOTLOADER_PATCHES);
00163             if (func_pointer)
00164             {
00165                 patch = func_pointer(&length);
00166                 if (patch)
00167                 {
00168                     _hci.patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, _simple_link.get_transmit_buffer(), patch, length);
00169                     return;
00170                 }
00171             }
00172             // Send 0 length Patches response event
00173             _hci.patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, _simple_link.get_transmit_buffer(), 0, 0);
00174             break;
00175         }
00176     }
00177 }
00178 
00179 static void hci_event_debug_print(uint16_t hciEventNo)
00180 {
00181 #if (CC3000_DEBUG_HCI_RX == 1)
00182     if ((hciEventNo > HCI_CMND_SOCKET_BASE) && ( hciEventNo <= HCI_CMND_MDNS_ADVERTISE))
00183     {
00184         DBG_HCI("Event Received : 0x%04X - %s", hciEventNo, HCI_EVENT_STR[hciEventNo-HCI_CMND_SOCKET]);
00185     }
00186     else if ((hciEventNo > HCI_CMND_NETAPP_BASE) && ( hciEventNo <= HCI_NETAPP_SET_TIMERS))
00187     {
00188         DBG_HCI("Event Received : 0x%04X - %s", hciEventNo, HCI_NETAPP_STR[hciEventNo-HCI_NETAPP_DHCP]);
00189     }
00190     else if (hciEventNo < HCI_CMND_WLAN_CONFIGURE_PATCH+1)
00191     {
00192         DBG_HCI("Event Received : 0x%04X - %s", hciEventNo, HCI_MISC_STR[hciEventNo]);
00193     }
00194     else
00195     {
00196         DBG_HCI("Event Received : 0x%04X", hciEventNo);
00197     }
00198 #endif
00199 }
00200 
00201 uint8_t *cc3000_event::hci_event_handler(void *ret_param, uint8_t *from, uint8_t *fromlen) {
00202     uint8_t *received_data, argument_size;
00203     uint16_t length;
00204     uint8_t *pucReceivedParams;
00205     uint16_t received_op_code = 0;
00206     uint32_t return_value;
00207     uint8_t * RecvParams;
00208     uint8_t *RetParams;
00209 
00210     while (1)
00211     {
00212         if (_simple_link.get_data_received_flag() != 0)
00213         {
00214             received_data = _simple_link.get_received_data();
00215             if (*received_data == HCI_TYPE_EVNT)
00216             {
00217                 // Event Received
00218                 STREAM_TO_UINT16((uint8_t *)received_data, HCI_EVENT_OPCODE_OFFSET,received_op_code);
00219                 pucReceivedParams = received_data + HCI_EVENT_HEADER_SIZE;
00220                 RecvParams = pucReceivedParams;
00221                 RetParams = (uint8_t *)ret_param;
00222 
00223                 // unsolicited event received - finish handling
00224                 if (hci_unsol_event_handler((uint8_t *)received_data) == 0)
00225                 {
00226                     STREAM_TO_UINT8(received_data, HCI_DATA_LENGTH_OFFSET, length);
00227 
00228                     hci_event_debug_print( received_op_code );
00229 
00230                     switch(received_op_code)
00231                     {
00232                     case HCI_CMND_READ_BUFFER_SIZE:
00233                         {
00234                             uint16_t temp = _simple_link.get_number_free_buffers();
00235                             STREAM_TO_UINT8((uint8_t *)pucReceivedParams, 0, temp);
00236                             _simple_link.set_number_free_buffers(temp);
00237 
00238                             temp = _simple_link.get_buffer_length();
00239                             STREAM_TO_UINT16((uint8_t *)pucReceivedParams, 1, temp);
00240                             _simple_link.set_buffer_length(temp);
00241                         }
00242                         break;
00243 
00244                     case HCI_CMND_WLAN_CONFIGURE_PATCH:
00245                     case HCI_NETAPP_DHCP:
00246                     case HCI_NETAPP_PING_SEND:
00247                     case HCI_NETAPP_PING_STOP:
00248                     case HCI_NETAPP_ARP_FLUSH:
00249                     case HCI_NETAPP_SET_DEBUG_LEVEL:
00250                     case HCI_NETAPP_SET_TIMERS:
00251                     case HCI_EVNT_NVMEM_READ:
00252                     case HCI_EVNT_NVMEM_CREATE_ENTRY:
00253                     case HCI_CMND_NVMEM_WRITE_PATCH:
00254                     case HCI_NETAPP_PING_REPORT:
00255                     case HCI_EVNT_MDNS_ADVERTISE:
00256 
00257                         STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)ret_param);
00258                         break;
00259 
00260                     case HCI_CMND_SETSOCKOPT:
00261                     case HCI_CMND_WLAN_CONNECT:
00262                     case HCI_CMND_WLAN_IOCTL_STATUSGET:
00263                     case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE:
00264                     case HCI_CMND_WLAN_IOCTL_DEL_PROFILE:
00265                     case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY:
00266                     case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM:
00267                     case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START:
00268                     case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP:
00269                     case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX:
00270                     case HCI_CMND_EVENT_MASK:
00271                     case HCI_EVNT_WLAN_DISCONNECT:
00272                     case HCI_EVNT_SOCKET:
00273                     case HCI_EVNT_BIND:
00274                     case HCI_CMND_LISTEN:
00275                     case HCI_EVNT_CLOSE_SOCKET:
00276                     case HCI_EVNT_CONNECT:
00277                     case HCI_EVNT_NVMEM_WRITE:
00278 
00279                         STREAM_TO_UINT32((uint8_t *)pucReceivedParams,0, *(uint32_t *)ret_param);
00280                         break;
00281 
00282                     case HCI_EVNT_READ_SP_VERSION:
00283 
00284                         STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)ret_param);
00285                         ret_param = ((uint8_t *)ret_param) + 1;
00286                         STREAM_TO_UINT32((uint8_t *)pucReceivedParams, 0, return_value);
00287                         UINT32_TO_STREAM((uint8_t *)ret_param, return_value);
00288                         break;
00289 
00290                     case HCI_EVNT_BSD_GETHOSTBYNAME:
00291 
00292                         STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_HOST_BY_NAME_RETVAL_OFFSET,*(uint32_t *)ret_param);
00293                         ret_param = ((uint8_t *)ret_param) + 4;
00294                         STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_HOST_BY_NAME_ADDR_OFFSET,*(uint32_t *)ret_param);
00295                         break;
00296 
00297                     case HCI_EVNT_ACCEPT:
00298                         {
00299                             STREAM_TO_UINT32((uint8_t *)pucReceivedParams,ACCEPT_SD_OFFSET,*(uint32_t *)ret_param);
00300                             ret_param = ((uint8_t *)ret_param) + 4;
00301                             STREAM_TO_UINT32((uint8_t *)pucReceivedParams,ACCEPT_RETURN_STATUS_OFFSET,*(uint32_t *)ret_param);
00302                             ret_param = ((uint8_t *)ret_param) + 4;
00303 
00304                             //This argument returns in network order
00305                             memcpy((uint8_t *)ret_param, pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr));
00306                             break;
00307                         }
00308 
00309                     case HCI_EVNT_RECV:
00310                     case HCI_EVNT_RECVFROM:
00311                         {
00312                             STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(uint32_t *)ret_param);
00313                             ret_param = ((uint8_t *)ret_param) + 4;
00314                             STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(uint32_t *)ret_param);
00315                             ret_param = ((uint8_t *)ret_param) + 4;
00316                             STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(uint32_t *)ret_param);
00317 
00318                             if(((tBsdReadReturnParams *)ret_param)->iNumberOfBytes == ERROR_SOCKET_INACTIVE)
00319                             {
00320                                 set_socket_active_status(((tBsdReadReturnParams *)ret_param)->iSocketDescriptor,SOCKET_STATUS_INACTIVE);
00321                             }
00322                             break;
00323                         }
00324 
00325                     case HCI_EVNT_SEND:
00326                     case HCI_EVNT_SENDTO:
00327                         {
00328                             STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(uint32_t *)ret_param);
00329                             ret_param = ((uint8_t *)ret_param) + 4;
00330                             STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(uint32_t *)ret_param);
00331                             ret_param = ((uint8_t *)ret_param) + 4;
00332 
00333                             break;
00334                         }
00335 
00336                     case HCI_EVNT_SELECT:
00337                         {
00338                             STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_STATUS_OFFSET,*(uint32_t *)ret_param);
00339                             ret_param = ((uint8_t *)ret_param) + 4;
00340                             STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_READFD_OFFSET,*(uint32_t *)ret_param);
00341                             ret_param = ((uint8_t *)ret_param) + 4;
00342                             STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(uint32_t *)ret_param);
00343                             ret_param = ((uint8_t *)ret_param) + 4;
00344                             STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_EXFD_OFFSET,*(uint32_t *)ret_param);
00345                             break;
00346                         }
00347 
00348                     case HCI_CMND_GETSOCKOPT:
00349 
00350                         STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)ret_param)->iStatus);
00351                         //This argument returns in network order
00352                         memcpy((uint8_t *)ret_param, pucReceivedParams, 4);
00353                         break;
00354 
00355                     case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS:
00356 
00357                         STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(uint32_t *)ret_param);
00358                         ret_param = ((uint8_t *)ret_param) + 4;
00359                         STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(uint32_t *)ret_param);
00360                         ret_param = ((uint8_t *)ret_param) + 4;
00361                         STREAM_TO_UINT16((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(uint32_t *)ret_param);
00362                         ret_param = ((uint8_t *)ret_param) + 2;
00363                         STREAM_TO_UINT16((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(uint32_t *)ret_param);
00364                         ret_param = ((uint8_t *)ret_param) + 2;
00365                         memcpy((uint8_t *)ret_param, (uint8_t *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH);
00366                         break;
00367 
00368                     case HCI_CMND_SIMPLE_LINK_START:
00369                         break;
00370 
00371                     case HCI_NETAPP_IPCONFIG:
00372 
00373                         //Read IP address
00374                         STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
00375                         RecvParams += 4;
00376 
00377                         //Read subnet
00378                         STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
00379                         RecvParams += 4;
00380 
00381                         //Read default GW
00382                         STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
00383                         RecvParams += 4;
00384 
00385                         //Read DHCP server
00386                         STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
00387                         RecvParams += 4;
00388 
00389                         //Read DNS server
00390                         STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
00391                         RecvParams += 4;
00392 
00393                         //Read Mac address
00394                         STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH);
00395                         RecvParams += 6;
00396 
00397                         //Read SSID
00398                         STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH);
00399                         break;
00400 
00401                     default :
00402                         DBG_HCI("UNKNOWN Event Received : 0x%04X ", received_op_code);
00403                         break;
00404                     }
00405 
00406                 }
00407                 if (received_op_code == _simple_link.get_op_code())
00408                 {
00409                     _simple_link.set_op_code(0);
00410                 }
00411             }
00412             else
00413             {
00414                 pucReceivedParams = received_data;
00415                 STREAM_TO_UINT8((uint8_t *)received_data, HCI_PACKET_ARGSIZE_OFFSET, argument_size);
00416 
00417                 STREAM_TO_UINT16((uint8_t *)received_data, HCI_PACKET_LENGTH_OFFSET, length);
00418 
00419                 // Data received: note that the only case where from and from length
00420                 // are not null is in recv from, so fill the args accordingly
00421                 if (from)
00422                 {
00423                     STREAM_TO_UINT32((uint8_t *)(received_data + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(uint32_t *)fromlen);
00424                     memcpy(from, (received_data + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen);
00425                 }
00426 
00427                 memcpy(ret_param, pucReceivedParams + HCI_DATA_HEADER_SIZE + argument_size, length - argument_size);
00428 
00429                 _simple_link.set_pending_data(0);
00430             }
00431 
00432             _simple_link.set_data_received_flag(0);
00433             _spi.wlan_irq_enable();
00434 
00435             // Since we are going to TX - we need to handle this event after the ResumeSPi since we need interrupts
00436             if ((*received_data == HCI_TYPE_EVNT) && (received_op_code == HCI_EVNT_PATCHES_REQ))
00437             {
00438                 hci_unsol_handle_patch_request((uint8_t *)received_data);
00439             }
00440             if ((_simple_link.get_op_code() == 0) && (_simple_link.get_pending_data() == 0))
00441             {
00442                 return NULL;
00443             }
00444         }
00445     }
00446 }
00447 
00448 int32_t cc3000_event::hci_unsol_event_handler(uint8_t *event_hdr) {
00449     uint8_t *data = NULL;
00450     int32_t event_type;
00451     uint32_t number_of_released_packets;
00452     uint32_t number_of_sent_packets;
00453 
00454     STREAM_TO_UINT16(event_hdr, HCI_EVENT_OPCODE_OFFSET,event_type);
00455 
00456     if (event_type & HCI_EVNT_UNSOL_BASE) {
00457         switch(event_type) {
00458             case HCI_EVNT_DATA_UNSOL_FREE_BUFF:
00459             {
00460                 hci_event_unsol_flowcontrol_handler(event_hdr);
00461 
00462                 number_of_released_packets = _simple_link.get_released_packets();
00463                 number_of_sent_packets = _simple_link.get_sent_packets();
00464 
00465                 if (number_of_released_packets == number_of_sent_packets)
00466                 {
00467                     if (_simple_link.get_tx_complete_signal())
00468                     {
00469                         //tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB);
00470                         _cc3000.usync_callback(HCI_EVENT_CC3000_CAN_SHUT_DOWN, NULL, 0);
00471                     }
00472                 }
00473                 return 1;
00474             }
00475         }
00476     }
00477 
00478     if (event_type & HCI_EVNT_WLAN_UNSOL_BASE) {
00479         switch(event_type) {
00480             case HCI_EVNT_WLAN_KEEPALIVE:
00481             case HCI_EVNT_WLAN_UNSOL_CONNECT:
00482             case HCI_EVNT_WLAN_UNSOL_DISCONNECT:
00483             case HCI_EVNT_WLAN_UNSOL_INIT:
00484             case HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE:
00485                  _cc3000.usync_callback(event_type, 0, 0);
00486                 break;
00487             case HCI_EVNT_WLAN_UNSOL_DHCP:
00488             {
00489                 uint8_t params[NETAPP_IPCONFIG_MAC_OFFSET + 1]; // extra byte is for the status
00490                 uint8_t *recParams = params;
00491                 data = (uint8_t *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
00492 
00493                 //Read IP address
00494                 STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
00495                 data += 4;
00496                 //Read subnet
00497                 STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
00498                 data += 4;
00499                 //Read default GW
00500                 STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
00501                 data += 4;
00502                 //Read DHCP server
00503                 STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
00504                 data += 4;
00505                 //Read DNS server
00506                 STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
00507                 // read the status
00508                 STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, *recParams);
00509 
00510                 _cc3000.usync_callback(event_type, (uint8_t  *)params, sizeof(params));
00511 
00512                 break;
00513             }
00514             case HCI_EVNT_WLAN_ASYNC_PING_REPORT:
00515             {
00516                 netapp_pingreport_args_t params;
00517                 data = (uint8_t *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
00518                 STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_SENT_OFFSET, params.packets_sent);
00519                 STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_RCVD_OFFSET, params.packets_received);
00520                 STREAM_TO_UINT32(data, NETAPP_PING_MIN_RTT_OFFSET, params.min_round_time);
00521                 STREAM_TO_UINT32(data, NETAPP_PING_MAX_RTT_OFFSET, params.max_round_time);
00522                 STREAM_TO_UINT32(data, NETAPP_PING_AVG_RTT_OFFSET, params.avg_round_time);
00523 
00524                 _cc3000.usync_callback(event_type, (uint8_t  *)&params, sizeof(params));
00525                 break;
00526             }
00527             case HCI_EVNT_BSD_TCP_CLOSE_WAIT:
00528             {
00529                 _cc3000.usync_callback(event_type, NULL, 0);
00530                 break;
00531             }
00532 
00533             //'default' case which means "event not supported"
00534             default:
00535                 return (0);
00536         }
00537         return(1);
00538     }
00539 
00540     if ((event_type == HCI_EVNT_SEND) || (event_type == HCI_EVNT_SENDTO) || (event_type == HCI_EVNT_WRITE)) {
00541         uint8_t *pArg;
00542         int32_t status;
00543         pArg = M_BSD_RESP_PARAMS_OFFSET(event_hdr);
00544         STREAM_TO_UINT32(pArg, BSD_RSP_PARAMS_STATUS_OFFSET,status);
00545         if (ERROR_SOCKET_INACTIVE == status) {
00546             // The only synchronous event that can come from SL device in form of
00547             // command complete is "Command Complete" on data sent, in case SL device
00548             // was unable to transmit
00549             int32_t transmit_error  = _simple_link.get_transmit_error();
00550             STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, transmit_error);
00551             _simple_link.set_transmit_error(transmit_error);
00552             update_socket_active_status(M_BSD_RESP_PARAMS_OFFSET(event_hdr));
00553             return (1);
00554         }
00555         else {
00556             return (0);
00557         }
00558     }
00559     return(0);
00560 }
00561 
00562 int32_t cc3000_event::hci_unsolicited_event_handler(void) {
00563     uint32_t res = 0;
00564     uint8_t *received_data;
00565 
00566     if (_simple_link.get_data_received_flag() != 0) {
00567         received_data = (_simple_link.get_received_data());
00568 
00569         if (*received_data == HCI_TYPE_EVNT) {
00570             // unsolicited event received - finish handling
00571             if (hci_unsol_event_handler((uint8_t *)received_data) == 1) {
00572                 // An unsolicited event was received:
00573                 // release the buffer and clean the event received
00574                 _simple_link.set_data_received_flag(0);
00575 
00576                 res = 1;
00577                 _spi.wlan_irq_enable();
00578             }
00579         }
00580     }
00581     return res;
00582 }
00583 
00584 void cc3000_event::set_socket_active_status(int32_t sd, int32_t status) {
00585     if (M_IS_VALID_SD(sd) && M_IS_VALID_STATUS(status)) {
00586         socket_active_status &= ~(1 << sd);      /* clean socket's mask */
00587         socket_active_status |= (status << sd); /* set new socket's mask */
00588     }
00589 }
00590 
00591 int32_t cc3000_event::hci_event_unsol_flowcontrol_handler(uint8_t *event) {
00592     int32_t temp, value;
00593     uint16_t i;
00594     uint16_t pusNumberOfHandles=0;
00595     uint8_t *pReadPayload;
00596 
00597     STREAM_TO_UINT16((uint8_t *)event,HCI_EVENT_HEADER_SIZE,pusNumberOfHandles);
00598     pReadPayload = ((uint8_t *)event + HCI_EVENT_HEADER_SIZE + sizeof(pusNumberOfHandles));
00599     temp = 0;
00600 
00601     for(i = 0; i < pusNumberOfHandles; i++) {
00602         STREAM_TO_UINT16(pReadPayload, FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET, value);
00603         temp += value;
00604         pReadPayload += FLOW_CONTROL_EVENT_SIZE;
00605     }
00606 
00607     _simple_link.set_number_free_buffers(_simple_link.get_number_free_buffers() + temp);
00608     _simple_link.set_number_of_released_packets(_simple_link.get_released_packets() + temp);
00609 
00610     return(ESUCCESS);
00611 }
00612 
00613 int32_t cc3000_event::get_socket_active_status(int32_t sd) {
00614     if (M_IS_VALID_SD(sd)) {
00615         return (socket_active_status & (1 << sd)) ? SOCKET_STATUS_INACTIVE : SOCKET_STATUS_ACTIVE;
00616     } else {
00617         return SOCKET_STATUS_INACTIVE;
00618     }
00619 }
00620 
00621 void cc3000_event::update_socket_active_status(uint8_t *resp_params) {
00622     int32_t status, sd;
00623 
00624     STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_SOCKET_OFFSET,sd);
00625     STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_STATUS_OFFSET,status);
00626 
00627     if (ERROR_SOCKET_INACTIVE == status) {
00628         set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
00629     }
00630 }
00631 
00632 void cc3000_event::simplelink_wait_event(uint16_t op_code, void *ret_param) {
00633     // In the blocking implementation the control to caller will be returned only
00634     // after the end of current transaction
00635     _simple_link.set_op_code(op_code);
00636     hci_event_handler(ret_param, 0, 0);
00637 }
00638 
00639 void cc3000_event::simplelink_wait_data(uint8_t *pBuf, uint8_t *from, uint8_t *fromlen) {
00640     // In the blocking implementation the control to caller will be returned only
00641     // after the end of current transaction, i.e. only after data will be received
00642     _simple_link.set_pending_data(1);
00643     hci_event_handler(pBuf, from, fromlen);
00644 }
00645 
00646 
00647 } // end of cc3000