Eric Wu / Mbed 2 deprecated WifiRobot

Dependencies:   mbed

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 
00213         if (_simple_link.get_data_received_flag() != 0)
00214         {
00215             received_data = _simple_link.get_received_data();
00216             if (*received_data == HCI_TYPE_EVNT)
00217             {
00218                 // Event Received
00219                 STREAM_TO_UINT16((uint8_t *)received_data, HCI_EVENT_OPCODE_OFFSET,received_op_code);
00220                 pucReceivedParams = received_data + HCI_EVENT_HEADER_SIZE;
00221                 RecvParams = pucReceivedParams;
00222                 RetParams = (uint8_t *)ret_param;
00223 
00224                 // unsolicited event received - finish handling
00225                 if (hci_unsol_event_handler((uint8_t *)received_data) == 0)
00226                 {
00227                     STREAM_TO_UINT8(received_data, HCI_DATA_LENGTH_OFFSET, length);
00228                     hci_event_debug_print( received_op_code );
00229                     switch(received_op_code)
00230                     {   
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                             /*
00358                         char snake[20];
00359                         for (int i = 12; i < 30; ++i) {
00360                             snake[i-12] = (char) *(pucReceivedParams+i);
00361                             
00362                             }
00363                         snake[19] = '\0';
00364                         printf("%s\n", snake);
00365                         
00366                         printf("handling get scan results\n");
00367                         */
00368                         uint8_t received_params_copy[53];
00369                         memcpy(received_params_copy, pucReceivedParams, 53);
00370                         //printf("copied memory\n");
00371                         
00372                         
00373                         STREAM_TO_UINT32((uint8_t *)received_params_copy,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(uint32_t *)ret_param);
00374                         ret_param = ((uint8_t *)ret_param) + 4;
00375                         STREAM_TO_UINT32((uint8_t *)received_params_copy,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(uint32_t *)ret_param);
00376                         ret_param = ((uint8_t *)ret_param) + 4;
00377                         STREAM_TO_UINT16((uint8_t *)received_params_copy,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(uint16_t *)ret_param);
00378                         ret_param = ((uint8_t *)ret_param) + 2;
00379                         STREAM_TO_UINT16((uint8_t *)received_params_copy,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(uint16_t *)ret_param);
00380                         ret_param = ((uint8_t *)ret_param) + 2;
00381                         
00382                         /*
00383                         
00384                         STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(uint32_t *)ret_param);
00385                         ret_param = ((uint8_t *)ret_param) + 4;
00386                         printf("handling get scan results 2");
00387                         STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(uint32_t *)ret_param);
00388                         ret_param = ((uint8_t *)ret_param) + 4;
00389                         STREAM_TO_UINT16((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(uint32_t *)ret_param);
00390                         ret_param = ((uint8_t *)ret_param) + 2;
00391                         STREAM_TO_UINT16((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(uint32_t *)ret_param);
00392                         ret_param = ((uint8_t *)ret_param) + 2;
00393                         */
00394                         memcpy((uint8_t *)ret_param, (uint8_t *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH);
00395                         
00396                         break;
00397                         }
00398                         
00399                         
00400 
00401                     case HCI_CMND_SIMPLE_LINK_START:
00402                         break;
00403 
00404                     case HCI_NETAPP_IPCONFIG:
00405 
00406                         //Read IP address
00407                         STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
00408                         RecvParams += 4;
00409 
00410                         //Read subnet
00411                         STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
00412                         RecvParams += 4;
00413 
00414                         //Read default GW
00415                         STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
00416                         RecvParams += 4;
00417 
00418                         //Read DHCP server
00419                         STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
00420                         RecvParams += 4;
00421 
00422                         //Read DNS server
00423                         STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
00424                         RecvParams += 4;
00425 
00426                         //Read Mac address
00427                         STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH);
00428                         RecvParams += 6;
00429 
00430                         //Read SSID
00431                         STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH);
00432                         break;
00433 
00434                     default :
00435                         DBG_HCI("UNKNOWN Event Received : 0x%04X ", received_op_code);
00436                         break;
00437                     }
00438 
00439                 }
00440                 if (received_op_code == _simple_link.get_op_code())
00441                 {
00442                     _simple_link.set_op_code(0);
00443                 }
00444             }
00445             else
00446             {
00447                 pucReceivedParams = received_data;
00448                 STREAM_TO_UINT8((uint8_t *)received_data, HCI_PACKET_ARGSIZE_OFFSET, argument_size);
00449 
00450                 STREAM_TO_UINT16((uint8_t *)received_data, HCI_PACKET_LENGTH_OFFSET, length);
00451 
00452                 // Data received: note that the only case where from and from length
00453                 // are not null is in recv from, so fill the args accordingly
00454                 if (from)
00455                 {
00456                     STREAM_TO_UINT32((uint8_t *)(received_data + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(uint32_t *)fromlen);
00457                     memcpy(from, (received_data + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen);
00458                 }
00459 
00460                 memcpy(ret_param, pucReceivedParams + HCI_DATA_HEADER_SIZE + argument_size, length - argument_size);
00461 
00462                 _simple_link.set_pending_data(0);
00463             }
00464 
00465             _simple_link.set_data_received_flag(0);
00466             _spi.wlan_irq_enable();
00467 
00468             // Since we are going to TX - we need to handle this event after the ResumeSPi since we need interrupts
00469             if ((*received_data == HCI_TYPE_EVNT) && (received_op_code == HCI_EVNT_PATCHES_REQ))
00470             {
00471                 hci_unsol_handle_patch_request((uint8_t *)received_data);
00472             }
00473             if ((_simple_link.get_op_code() == 0) && (_simple_link.get_pending_data() == 0))
00474             {
00475                 return NULL;
00476             }
00477         }
00478     }
00479 }
00480 
00481 int32_t cc3000_event::hci_unsol_event_handler(uint8_t *event_hdr) {
00482     uint8_t *data = NULL;
00483     int32_t event_type;
00484     uint32_t number_of_released_packets;
00485     uint32_t number_of_sent_packets;
00486 
00487     STREAM_TO_UINT16(event_hdr, HCI_EVENT_OPCODE_OFFSET,event_type);
00488 
00489     if (event_type & HCI_EVNT_UNSOL_BASE) {
00490         switch(event_type) {
00491             case HCI_EVNT_DATA_UNSOL_FREE_BUFF:
00492             {
00493                 hci_event_unsol_flowcontrol_handler(event_hdr);
00494 
00495                 number_of_released_packets = _simple_link.get_released_packets();
00496                 number_of_sent_packets = _simple_link.get_sent_packets();
00497 
00498                 if (number_of_released_packets == number_of_sent_packets)
00499                 {
00500                     if (_simple_link.get_tx_complete_signal())
00501                     {
00502                         //tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB);
00503                         _cc3000.usync_callback(HCI_EVENT_CC3000_CAN_SHUT_DOWN, NULL, 0);
00504                     }
00505                 }
00506                 return 1;
00507             }
00508         }
00509     }
00510 
00511     if (event_type & HCI_EVNT_WLAN_UNSOL_BASE) {
00512         switch(event_type) {
00513             case HCI_EVNT_WLAN_KEEPALIVE:
00514             case HCI_EVNT_WLAN_UNSOL_CONNECT:
00515             case HCI_EVNT_WLAN_UNSOL_DISCONNECT:
00516             case HCI_EVNT_WLAN_UNSOL_INIT:
00517             case HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE:
00518                  _cc3000.usync_callback(event_type, 0, 0);
00519                 break;
00520             case HCI_EVNT_WLAN_UNSOL_DHCP:
00521             {
00522                 uint8_t params[NETAPP_IPCONFIG_MAC_OFFSET + 1]; // extra byte is for the status
00523                 uint8_t *recParams = params;
00524                 data = (uint8_t *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
00525 
00526                 //Read IP address
00527                 STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
00528                 data += 4;
00529                 //Read subnet
00530                 STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
00531                 data += 4;
00532                 //Read default GW
00533                 STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
00534                 data += 4;
00535                 //Read DHCP server
00536                 STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
00537                 data += 4;
00538                 //Read DNS server
00539                 STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
00540                 // read the status
00541                 STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, *recParams);
00542 
00543                 _cc3000.usync_callback(event_type, (uint8_t  *)params, sizeof(params));
00544 
00545                 break;
00546             }
00547             case HCI_EVNT_WLAN_ASYNC_PING_REPORT:
00548             {
00549                 netapp_pingreport_args_t params;
00550                 data = (uint8_t *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
00551                 STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_SENT_OFFSET, params.packets_sent);
00552                 STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_RCVD_OFFSET, params.packets_received);
00553                 STREAM_TO_UINT32(data, NETAPP_PING_MIN_RTT_OFFSET, params.min_round_time);
00554                 STREAM_TO_UINT32(data, NETAPP_PING_MAX_RTT_OFFSET, params.max_round_time);
00555                 STREAM_TO_UINT32(data, NETAPP_PING_AVG_RTT_OFFSET, params.avg_round_time);
00556 
00557                 _cc3000.usync_callback(event_type, (uint8_t  *)&params, sizeof(params));
00558                 break;
00559             }
00560             case HCI_EVNT_BSD_TCP_CLOSE_WAIT:
00561             {
00562                 _cc3000.usync_callback(event_type, NULL, 0);
00563                 break;
00564             }
00565 
00566             //'default' case which means "event not supported"
00567             default:
00568                 return (0);
00569         }
00570         return(1);
00571     }
00572 
00573     if ((event_type == HCI_EVNT_SEND) || (event_type == HCI_EVNT_SENDTO) || (event_type == HCI_EVNT_WRITE)) {
00574         uint8_t *pArg;
00575         int32_t status;
00576         pArg = M_BSD_RESP_PARAMS_OFFSET(event_hdr);
00577         STREAM_TO_UINT32(pArg, BSD_RSP_PARAMS_STATUS_OFFSET,status);
00578         if (ERROR_SOCKET_INACTIVE == status) {
00579             // The only synchronous event that can come from SL device in form of
00580             // command complete is "Command Complete" on data sent, in case SL device
00581             // was unable to transmit
00582             int32_t transmit_error  = _simple_link.get_transmit_error();
00583             STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, transmit_error);
00584             _simple_link.set_transmit_error(transmit_error);
00585             update_socket_active_status(M_BSD_RESP_PARAMS_OFFSET(event_hdr));
00586             return (1);
00587         }
00588         else {
00589             return (0);
00590         }
00591     }
00592     return(0);
00593 }
00594 
00595 int32_t cc3000_event::hci_unsolicited_event_handler(void) {
00596     uint32_t res = 0;
00597     uint8_t *received_data;
00598 
00599     if (_simple_link.get_data_received_flag() != 0) {
00600         received_data = (_simple_link.get_received_data());
00601 
00602         if (*received_data == HCI_TYPE_EVNT) {
00603             // unsolicited event received - finish handling
00604             if (hci_unsol_event_handler((uint8_t *)received_data) == 1) {
00605                 // An unsolicited event was received:
00606                 // release the buffer and clean the event received
00607                 _simple_link.set_data_received_flag(0);
00608 
00609                 res = 1;
00610                 _spi.wlan_irq_enable();
00611             }
00612         }
00613     }
00614     return res;
00615 }
00616 
00617 void cc3000_event::set_socket_active_status(int32_t sd, int32_t status) {
00618     if (M_IS_VALID_SD(sd) && M_IS_VALID_STATUS(status)) {
00619         socket_active_status &= ~(1 << sd);      /* clean socket's mask */
00620         socket_active_status |= (status << sd); /* set new socket's mask */
00621     }
00622 }
00623 
00624 int32_t cc3000_event::hci_event_unsol_flowcontrol_handler(uint8_t *event) {
00625     int32_t temp, value;
00626     uint16_t i;
00627     uint16_t pusNumberOfHandles=0;
00628     uint8_t *pReadPayload;
00629 
00630     STREAM_TO_UINT16((uint8_t *)event,HCI_EVENT_HEADER_SIZE,pusNumberOfHandles);
00631     pReadPayload = ((uint8_t *)event + HCI_EVENT_HEADER_SIZE + sizeof(pusNumberOfHandles));
00632     temp = 0;
00633 
00634     for(i = 0; i < pusNumberOfHandles; i++) {
00635         STREAM_TO_UINT16(pReadPayload, FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET, value);
00636         temp += value;
00637         pReadPayload += FLOW_CONTROL_EVENT_SIZE;
00638     }
00639 
00640     _simple_link.set_number_free_buffers(_simple_link.get_number_free_buffers() + temp);
00641     _simple_link.set_number_of_released_packets(_simple_link.get_released_packets() + temp);
00642 
00643     return(ESUCCESS);
00644 }
00645 
00646 int32_t cc3000_event::get_socket_active_status(int32_t sd) {
00647     if (M_IS_VALID_SD(sd)) {
00648         return (socket_active_status & (1 << sd)) ? SOCKET_STATUS_INACTIVE : SOCKET_STATUS_ACTIVE;
00649     } else {
00650         return SOCKET_STATUS_INACTIVE;
00651     }
00652 }
00653 
00654 void cc3000_event::update_socket_active_status(uint8_t *resp_params) {
00655     int32_t status, sd;
00656 
00657     STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_SOCKET_OFFSET,sd);
00658     STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_STATUS_OFFSET,status);
00659 
00660     if (ERROR_SOCKET_INACTIVE == status) {
00661         set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
00662     }
00663 }
00664 
00665 void cc3000_event::simplelink_wait_event(uint16_t op_code, void *ret_param) {
00666     // In the blocking implementation the control to caller will be returned only
00667     // after the end of current transaction
00668     _simple_link.set_op_code(op_code);
00669     hci_event_handler(ret_param, 0, 0);
00670 }
00671 
00672 void cc3000_event::simplelink_wait_data(uint8_t *pBuf, uint8_t *from, uint8_t *fromlen) {
00673     // In the blocking implementation the control to caller will be returned only
00674     // after the end of current transaction, i.e. only after data will be received
00675     _simple_link.set_pending_data(1);
00676     hci_event_handler(pBuf, from, fromlen);
00677 }
00678 
00679 
00680 } // end of cc3000