]> granicus.if.org Git - esp-idf/blobdiff - components/bt/bluedroid/hci/hci_hal_h4.c
Merge branch 'bugfix/spiram_malloc_reserve_internal_fragments' into 'master'
[esp-idf] / components / bt / bluedroid / hci / hci_hal_h4.c
index b9231b1b6f3d88c0a4845dbda95d9f79a4f68341..e910aa7b73102f96150e0ad703a69099c024b3c7 100644 (file)
  *
  ******************************************************************************/
 #include <string.h>
-#include "bt_defs.h"
-#include "bt_trace.h"
-#include "bt_types.h"
-#include "buffer_allocator.h"
-#include "fixed_queue.h"
-#include "hci_hal.h"
-#include "hci_internals.h"
-#include "hci_layer.h"
-#include "thread.h"
+#include "common/bt_defs.h"
+#include "common/bt_trace.h"
+#include "stack/bt_types.h"
+#include "hci/buffer_allocator.h"
+#include "osi/fixed_queue.h"
+#include "hci/hci_hal.h"
+#include "hci/hci_internals.h"
+#include "hci/hci_layer.h"
+#include "osi/thread.h"
 #include "esp_bt.h"
 
+#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
+#include "l2c_int.h"
+#include "stack/hcimsgs.h"
+#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
+
 #define HCI_HAL_SERIAL_BUFFER_SIZE 1026
 #define HCI_BLE_EVENT 0x3e
 #define PACKET_TYPE_TO_INBOUND_INDEX(type) ((type) - 2)
 #define PACKET_TYPE_TO_INDEX(type) ((type) - 1)
+extern bool BTU_check_queue_is_congest(void);
 
 
 static const uint8_t preamble_sizes[] = {
@@ -83,7 +89,7 @@ static void hci_hal_env_init(
     if (hci_hal_env.rx_q) {
         fixed_queue_register_dequeue(hci_hal_env.rx_q, event_uart_has_bytes);
     } else {
-        LOG_ERROR("%s unable to create rx queue.\n", __func__);
+        HCI_TRACE_ERROR("%s unable to create rx queue.\n", __func__);
     }
 
     return;
@@ -92,6 +98,7 @@ static void hci_hal_env_init(
 static void hci_hal_env_deinit(void)
 {
     fixed_queue_free(hci_hal_env.rx_q, hci_hal_env.allocator->free);
+    hci_hal_env.rx_q = NULL;
 }
 
 static bool hal_open(const hci_hal_callbacks_t *upper_callbacks)
@@ -99,7 +106,7 @@ static bool hal_open(const hci_hal_callbacks_t *upper_callbacks)
     assert(upper_callbacks != NULL);
     callbacks = upper_callbacks;
 
-    hci_hal_env_init(HCI_HAL_SERIAL_BUFFER_SIZE, SIZE_MAX);
+    hci_hal_env_init(HCI_HAL_SERIAL_BUFFER_SIZE, QUEUE_SIZE_MAX);
 
     xHciH4Queue = xQueueCreate(HCI_H4_QUEUE_LEN, sizeof(BtTaskEvt_t));
     xTaskCreatePinnedToCore(hci_hal_h4_rx_handler, HCI_H4_TASK_NAME, HCI_H4_TASK_STACK_SIZE, NULL, HCI_H4_TASK_PRIO, &xHciH4TaskHandle, HCI_H4_TASK_PINNED_TO_CORE);
@@ -135,7 +142,7 @@ static uint16_t transmit_data(serial_data_type_t type,
     assert(length > 0);
 
     if (type < DATA_TYPE_COMMAND || type > DATA_TYPE_SCO) {
-        LOG_ERROR("%s invalid data type: %d", __func__, type);
+        HCI_TRACE_ERROR("%s invalid data type: %d", __func__, type);
         return 0;
     }
 
@@ -165,6 +172,7 @@ static void hci_hal_h4_rx_handler(void *arg)
         if (pdTRUE == xQueueReceive(xHciH4Queue, &e, (portTickType)portMAX_DELAY)) {
             if (e.sig == SIG_HCI_HAL_RECV_PACKET) {
                 fixed_queue_process(hci_hal_env.rx_q);
+
             }
         }
     }
@@ -178,13 +186,51 @@ task_post_status_t hci_hal_h4_task_post(task_post_t timeout)
     evt.par = 0;
 
     if (xQueueSend(xHciH4Queue, &evt, timeout) != pdTRUE) {
-        LOG_ERROR("xHciH4Queue failed\n");
         return TASK_POST_SUCCESS;
     }
 
     return TASK_POST_FAIL;
 }
 
+#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
+static void hci_packet_complete(BT_HDR *packet){
+    uint8_t type, num_handle;
+    uint16_t handle;
+    uint16_t handles[MAX_L2CAP_LINKS + 4];
+    uint16_t num_packets[MAX_L2CAP_LINKS + 4];
+    uint8_t *stream = packet->data + packet->offset;
+    tL2C_LCB  *p_lcb = NULL;
+
+    STREAM_TO_UINT8(type, stream);
+    if (type == DATA_TYPE_ACL/* || type == DATA_TYPE_SCO*/) {
+        STREAM_TO_UINT16(handle, stream);
+        handle = handle & HCI_DATA_HANDLE_MASK;
+        p_lcb = l2cu_find_lcb_by_handle(handle);
+        if (p_lcb) {
+            p_lcb->completed_packets++;
+        }
+        if (esp_vhci_host_check_send_available()){
+            num_handle = l2cu_find_completed_packets(handles, num_packets);
+            if (num_handle > 0){
+                btsnd_hcic_host_num_xmitted_pkts (num_handle, handles, num_packets);
+            }
+        } else {
+            //Send HCI_Host_Number_of_Completed_Packets next time.
+        }
+
+    }
+}
+#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
+
+bool host_recv_adv_packet(BT_HDR *packet)
+{
+    assert(packet);
+    if(packet->data[0] == DATA_TYPE_EVENT && packet->data[1] == HCI_BLE_EVENT && packet->data[3] ==  HCI_BLE_ADV_PKT_RPT_EVT) {
+        return true;
+    }
+    return false;
+}
+
 static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
 {
     uint8_t type, hdr_size;
@@ -194,19 +240,24 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
     if (!packet) {
         return;
     }
+
+#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
+    hci_packet_complete(packet);
+#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
+
     STREAM_TO_UINT8(type, stream);
     packet->offset++;
     packet->len--;
     if (type == HCI_BLE_EVENT) {
         uint8_t len = 0;
         STREAM_TO_UINT8(len, stream);
-        LOG_ERROR("Workround stream corrupted during LE SCAN: pkt_len=%d ble_event_len=%d\n",
+        HCI_TRACE_ERROR("Workround stream corrupted during LE SCAN: pkt_len=%d ble_event_len=%d\n",
                   packet->len, len);
         hci_hal_env.allocator->free(packet);
         return;
     }
     if (type < DATA_TYPE_ACL || type > DATA_TYPE_EVENT) {
-        LOG_ERROR("%s Unknown HCI message type. Dropping this byte 0x%x,"
+        HCI_TRACE_ERROR("%s Unknown HCI message type. Dropping this byte 0x%x,"
                   " min %x, max %x\n", __func__, type,
                   DATA_TYPE_ACL, DATA_TYPE_EVENT);
         hci_hal_env.allocator->free(packet);
@@ -214,7 +265,7 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
     }
     hdr_size = preamble_sizes[type - 1];
     if (packet->len < hdr_size) {
-        LOG_ERROR("Wrong packet length type=%d pkt_len=%d hdr_len=%d",
+        HCI_TRACE_ERROR("Wrong packet length type=%d pkt_len=%d hdr_len=%d",
                   type, packet->len, hdr_size);
         hci_hal_env.allocator->free(packet);
         return;
@@ -228,11 +279,18 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
     }
 
     if ((length + hdr_size) != packet->len) {
-        LOG_ERROR("Wrong packet length type=%d hdr_len=%d pd_len=%d "
+        HCI_TRACE_ERROR("Wrong packet length type=%d hdr_len=%d pd_len=%d "
                   "pkt_len=%d", type, hdr_size, length, packet->len);
         hci_hal_env.allocator->free(packet);
         return;
     }
+#if SCAN_QUEUE_CONGEST_CHECK
+    if(BTU_check_queue_is_congest() && host_recv_adv_packet(packet)) {
+        HCI_TRACE_ERROR("BtuQueue is congested");
+        hci_hal_env.allocator->free(packet);
+        return;
+    }
+#endif
 
     packet->event = outbound_event_types[PACKET_TYPE_TO_INDEX(type)];
     callbacks->packet_ready(packet);
@@ -260,10 +318,14 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
     BT_HDR *pkt;
     size_t pkt_size;
 
+    if (hci_hal_env.rx_q == NULL) {
+        return 0;
+    }
+
     pkt_size = BT_HDR_SIZE + len;
     pkt = (BT_HDR *)hci_hal_env.allocator->alloc(pkt_size);
     if (!pkt) {
-        LOG_ERROR("%s couldn't aquire memory for inbound data buffer.\n", __func__);
+        HCI_TRACE_ERROR("%s couldn't aquire memory for inbound data buffer.\n", __func__);
         return -1;
     }
     pkt->offset = 0;
@@ -271,7 +333,7 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
     pkt->layer_specific = 0;
     memcpy(pkt->data, data, len);
     fixed_queue_enqueue(hci_hal_env.rx_q, pkt);
-    hci_hal_h4_task_post(TASK_POST_BLOCKING);
+    hci_hal_h4_task_post(100 / portTICK_PERIOD_MS);
 
     BTTRC_DUMP_BUFFER("Recv Pkt", pkt->data, len);