diff --git a/components/bt/host/bluedroid/hci/hci_hal_h4.c b/components/bt/host/bluedroid/hci/hci_hal_h4.c index ae51b55dcd..a1f12bb9bf 100644 --- a/components/bt/host/bluedroid/hci/hci_hal_h4.c +++ b/components/bt/host/bluedroid/hci/hci_hal_h4.c @@ -34,7 +34,6 @@ #include "esp_bt.h" #endif #include "esp_bluedroid_hci.h" -#include "stack/hcimsgs.h" #if (C2H_FLOW_CONTROL_INCLUDED == TRUE) #include "l2c_int.h" @@ -319,9 +318,12 @@ static void hci_packet_complete(BT_HDR *packet){ } #endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE -bool host_recv_adv_packet(uint8_t *packet) +bool host_recv_adv_packet(uint8_t *packet, uint16_t len) { assert(packet); + if (len < 4) { + return false; + } if(packet[0] == DATA_TYPE_EVENT && packet[1] == HCI_BLE_EVENT) { if(packet[3] == HCI_BLE_ADV_PKT_RPT_EVT || packet[3] == HCI_BLE_DIRECT_ADV_EVT #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) @@ -543,7 +545,7 @@ static void hci_hal_h4_hdl_rx_adv_rpt(pkt_linked_item_t *linked_pkt) BT_HDR* packet = (BT_HDR *)linked_pkt->data; stream = packet->data + packet->offset; - assert(host_recv_adv_packet(stream) == true); + assert(host_recv_adv_packet(stream, packet->len) == true); STREAM_TO_UINT8(type, stream); packet->offset++; @@ -588,7 +590,10 @@ static void host_send_pkt_available_cb(void) void bt_record_hci_data(uint8_t *data, uint16_t len) { #if (BT_HCI_LOG_INCLUDED == TRUE) - if ((data[0] == DATA_TYPE_EVENT) && (data[1] == HCI_BLE_EVENT) && ((data[3] == HCI_BLE_ADV_PKT_RPT_EVT) || (data[3] == HCI_BLE_DIRECT_ADV_EVT) + if (len < 2) { + return; + } + if ((len >= 4) && (data[0] == DATA_TYPE_EVENT) && (data[1] == HCI_BLE_EVENT) && ((data[3] == HCI_BLE_ADV_PKT_RPT_EVT) || (data[3] == HCI_BLE_DIRECT_ADV_EVT) #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) || (data[3] == HCI_BLE_ADV_DISCARD_REPORT_EVT) #endif // (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) @@ -641,7 +646,7 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len) } #endif // #if (BLE_FEAT_ISO_EN == TRUE) - bool is_adv_rpt = host_recv_adv_packet(data); + bool is_adv_rpt = host_recv_adv_packet(data, len); if (!is_adv_rpt) { pkt_size = BT_HDR_SIZE + len; @@ -700,7 +705,7 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len) hci_upstream_data_post(OSI_THREAD_MAX_TIMEOUT); - BTTRC_DUMP_BUFFER("Recv Pkt", pkt->data, len); + BTTRC_DUMP_BUFFER("Recv Pkt", data, len); return 0; } diff --git a/components/bt/host/bluedroid/hci/hci_layer.c b/components/bt/host/bluedroid/hci/hci_layer.c index fbc0dab461..ac56596667 100644 --- a/components/bt/host/bluedroid/hci/hci_layer.c +++ b/components/bt/host/bluedroid/hci/hci_layer.c @@ -117,7 +117,7 @@ int hci_start_up(void) hci_host_thread = osi_thread_create(HCI_HOST_TASK_NAME, HCI_HOST_TASK_STACK_SIZE, HCI_HOST_TASK_PRIO, HCI_HOST_TASK_PINNED_TO_CORE, HCI_HOST_TASK_WORKQUEUE_NUM, workqueue_len); if (hci_host_thread == NULL) { - return -2; + goto error; } osi_event_bind(hci_host_env.downstream_data_ready, hci_host_thread, HCI_DOWNSTREAM_DATA_QUEUE_IDX); @@ -137,13 +137,15 @@ error: void hci_shut_down(void) { hci_host_startup_flag = false; + + /* Close HAL and cleanup before freeing thread: hal->open() and osi_event_bind() + * stored references to hci_host_thread; they must not use it after osi_thread_free(). */ + if (hci_host_thread != NULL) { + hal->close(); + packet_fragmenter->cleanup(); + } hci_layer_deinit_env(); - packet_fragmenter->cleanup(); - - //low_power_manager->cleanup(); - hal->close(); - osi_thread_free(hci_host_thread); hci_host_thread = NULL; } @@ -445,7 +447,7 @@ static bool filter_incoming_event(BT_HDR *packet) { pkt_linked_item_t *wait_entry = NULL; hci_cmd_metadata_t *metadata = NULL; - uint8_t *stream = packet->data + packet->offset; + uint8_t *stream; uint8_t event_code; command_opcode_t opcode; @@ -453,6 +455,8 @@ static bool filter_incoming_event(BT_HDR *packet) return true; } + stream = packet->data + packet->offset; + if (packet->len < HCI_EVENT_PREAMBLE_SIZE) { HCI_TRACE_WARNING("dropping too short HCI event (len=%u)", packet->len); osi_free(packet); diff --git a/components/bt/host/bluedroid/hci/hci_packet_factory.c b/components/bt/host/bluedroid/hci/hci_packet_factory.c index 6a84f9ca29..f710046d0e 100644 --- a/components/bt/host/bluedroid/hci/hci_packet_factory.c +++ b/components/bt/host/bluedroid/hci/hci_packet_factory.c @@ -250,6 +250,8 @@ static BT_HDR *make_command_no_params(uint16_t opcode) static BT_HDR *make_command(uint16_t opcode, size_t parameter_size, uint8_t **stream_out) { BT_HDR *packet = HCI_GET_CMD_BUF(parameter_size); + assert(packet != NULL); + hci_cmd_metadata_t *metadata = HCI_GET_CMD_METAMSG(packet); metadata->opcode = opcode; diff --git a/components/bt/host/bluedroid/hci/packet_fragmenter.c b/components/bt/host/bluedroid/hci/packet_fragmenter.c index 0827ecb4fe..e280a98183 100644 --- a/components/bt/host/bluedroid/hci/packet_fragmenter.c +++ b/components/bt/host/bluedroid/hci/packet_fragmenter.c @@ -73,9 +73,10 @@ static void fragment_and_dispatch(BT_HDR *packet) uint16_t continuation_handle; uint16_t max_data_size, max_packet_size, remaining_length; uint16_t event = packet->event & MSG_EVT_MASK; - uint8_t *stream = packet->data + packet->offset; + uint8_t *stream; assert(packet != NULL); + stream = packet->data + packet->offset; // We only fragment ACL packets if (event != MSG_STACK_TO_HC_HCI_ACL) {