diff options
Diffstat (limited to 'lib/bt/host/bluedroid/hci')
| -rw-r--r-- | lib/bt/host/bluedroid/hci/ble_hci_iso.c | 346 | ||||
| -rw-r--r-- | lib/bt/host/bluedroid/hci/hci_hal_h4.c | 158 | ||||
| -rw-r--r-- | lib/bt/host/bluedroid/hci/hci_layer.c | 2 | ||||
| -rw-r--r-- | lib/bt/host/bluedroid/hci/hci_packet_factory.c | 28 | ||||
| -rw-r--r-- | lib/bt/host/bluedroid/hci/hci_packet_parser.c | 62 | ||||
| -rw-r--r-- | lib/bt/host/bluedroid/hci/include/hci/ble_hci_iso.h | 85 | ||||
| -rw-r--r-- | lib/bt/host/bluedroid/hci/include/hci/hci_hal.h | 3 | ||||
| -rw-r--r-- | lib/bt/host/bluedroid/hci/include/hci/hci_layer.h | 3 | ||||
| -rw-r--r-- | lib/bt/host/bluedroid/hci/include/hci/hci_packet_factory.h | 10 | ||||
| -rw-r--r-- | lib/bt/host/bluedroid/hci/include/hci/hci_packet_parser.h | 20 | ||||
| -rw-r--r-- | lib/bt/host/bluedroid/hci/packet_fragmenter.c | 6 |
11 files changed, 649 insertions, 74 deletions
diff --git a/lib/bt/host/bluedroid/hci/ble_hci_iso.c b/lib/bt/host/bluedroid/hci/ble_hci_iso.c new file mode 100644 index 00000000..9c73fae2 --- /dev/null +++ b/lib/bt/host/bluedroid/hci/ble_hci_iso.c @@ -0,0 +1,346 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <string.h> +#include <assert.h> +#include "hci/ble_hci_iso.h" +#include "common/bt_target.h" +#include "osi/mutex.h" + +#if (BLE_FEAT_ISO_EN == TRUE) + +#define BLE_HCI_ISO_PB_FIRST_FRAG 0 +#define BLE_HCI_ISO_PB_CONT_FRAG 1 +#define BLE_HCI_ISO_PB_COMP_SDU 2 +#define BLE_HCI_ISO_PB_LAST_FRAG 3 + +#define BLE_HCI_ISO_DATA_HDR_SZ 4 +#define BLE_HCI_ISO_DATA_LOAD_TS_SZ 4 +#define BLE_HCI_ISO_DATA_LOAD_HDR_SZ 4 + +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + +static uint16_t ble_hs_iso_buf_sz; +static uint8_t ble_hs_iso_max_pkts; + +#if (BLE_ISO_STD_FLOW_CTRL == TRUE) +/* Number of available ISO transmit buffers on the controller. + * It must only be accessed while the host mutex is locked. + */ +static uint16_t ble_hs_iso_avail_pkts; +#endif // #if (BLE_ISO_STD_FLOW_CTRL == TRUE) + +static struct ble_hci_iso_conn g_iso_conn[BLE_ISO_BIS_MAX_COUNT + BLE_ISO_CIS_MAX_COUNT]; + +int +ble_hci_set_iso_buf_sz(uint16_t pktlen, uint8_t max_pkts) +{ + if (pktlen == 0 || max_pkts == 0) { + return 3; + } + + ble_hs_iso_buf_sz = pktlen; + ble_hs_iso_max_pkts = max_pkts; + +#if (BLE_ISO_STD_FLOW_CTRL == TRUE) + ble_hs_iso_avail_pkts = max_pkts; +#endif /* (BLE_ISO_STD_FLOW_CTRL) */ + + HCI_TRACE_WARNING("ISO Flow Control:\n"); + HCI_TRACE_WARNING(" Length: %u\n", pktlen); + HCI_TRACE_WARNING(" Count: %u\n", max_pkts); + HCI_TRACE_WARNING(" Status: "); +#if (BLE_ISO_STD_FLOW_CTRL == TRUE) + HCI_TRACE_WARNING("%s\n", "Standard"); +#elif (BLE_ISO_NON_STD_FLOW_CTRL == TRUE) + HCI_TRACE_WARNING("%s\n", "Non-standard"); +#else + HCI_TRACE_WARNING("%s\n", "Not support"); +#endif + + return 0; +} + +void +ble_hci_get_iso_buf_size(uint16_t *pktlen, uint8_t *max_pkts) +{ + assert(pktlen && max_pkts); + + *pktlen = ble_hs_iso_buf_sz; + *max_pkts = ble_hs_iso_max_pkts; +} + +#if (BLE_ISO_STD_FLOW_CTRL == TRUE) +void +ble_hci_add_iso_avail_pkts(uint16_t delta) +{ + osi_mutex_global_lock(); + + if (ble_hs_iso_avail_pkts + delta > ble_hs_iso_max_pkts) { + HCI_TRACE_ERROR("ISO_HS_RESET %u %u %u\n", ble_hs_iso_avail_pkts, delta, ble_hs_iso_max_pkts); + // ble_hs_sched_reset(BLE_HS_ECONTROLLER); + assert(0); + } else { + ble_hs_iso_avail_pkts += delta; + } + + osi_mutex_global_unlock(); +} +#endif /* (BLE_ISO_STD_FLOW_CTRL) */ + +#define BLE_ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) + +struct ble_hci_iso_conn * +ble_hci_iso_conn_find(uint16_t conn_handle) +{ + for (size_t i = 0; i < BLE_ARRAY_SIZE(g_iso_conn); i++) { + struct ble_hci_iso_conn *conn = &g_iso_conn[i]; + + if (conn->enabled && + conn->conn_handle == conn_handle) { + return conn; + } + } + + return NULL; +} + +int ble_hci_iso_conn_free(uint16_t conn_handle) +{ + for (size_t i = 0; i < BLE_ARRAY_SIZE(g_iso_conn); i++) { + struct ble_hci_iso_conn *conn = &g_iso_conn[i]; + + if (conn->enabled && + conn->conn_handle == conn_handle) { + conn->enabled = 0; + conn->conn_handle = 0; + return 0; + } + } + + return 1; +} + +static struct ble_hci_iso_conn * +ble_hci_iso_alloc_conn(uint16_t conn_handle) +{ + for (size_t i = 0; i < BLE_ARRAY_SIZE(g_iso_conn); i++) { + struct ble_hci_iso_conn *conn = &g_iso_conn[i]; + + if (!conn->enabled) { + conn->enabled = 1; + conn->conn_handle = conn_handle; + conn->pkt_seq_num = 0; /* Initialize to 0 */ + return conn; + } + } + + return NULL; +} + +#if (BLE_ISO_STD_FLOW_CTRL == TRUE) +static uint8_t +ble_hci_iso_buf_needed(struct ble_hs_iso_conn *conn) +{ + uint16_t sdu_offset; + uint16_t dl_len; + uint8_t dlh_len; + uint8_t count; + + dlh_len = (conn->ts_flag ? BLE_HCI_ISO_DATA_LOAD_TS_SZ : 0) + BLE_HCI_ISO_DATA_LOAD_HDR_SZ; + sdu_offset = 0; + count = 1; /* 1 extra since framed pdu may be used */ + + while (1) { + dl_len = min(dlh_len + conn->sdu_len - sdu_offset, ble_hs_iso_buf_sz); + + count += 1; + + sdu_offset += dl_len - dlh_len; + assert(sdu_offset <= conn->sdu_len); + + if (sdu_offset == conn->sdu_len) { + break; + } + + /* No data load header for continuation/last segment */ + dlh_len = 0; + } + + return count; +} +#endif /* (BLE_ISO_STD_FLOW_CTRL) */ + +static void +ble_hci_iso_hdr_append(struct ble_hci_iso_conn *conn, + uint8_t *frag, + uint8_t pb_flag, uint16_t dl_len) +{ + uint32_t pkt_hdr; + uint32_t dl_hdr; + + pkt_hdr = conn->conn_handle; + pkt_hdr |= (pb_flag << 12); + if (pb_flag == BLE_HCI_ISO_PB_FIRST_FRAG || + pb_flag == BLE_HCI_ISO_PB_COMP_SDU) { + pkt_hdr |= (conn->ts_flag << 14); + } + pkt_hdr |= (dl_len << 16); + + memcpy(frag, &pkt_hdr, BLE_HCI_ISO_DATA_HDR_SZ); + + /* No data load header for continuation/last segment */ + if (pb_flag == BLE_HCI_ISO_PB_CONT_FRAG || + pb_flag == BLE_HCI_ISO_PB_LAST_FRAG) { + return; + } + + if (conn->ts_flag) { + memcpy(frag + BLE_HCI_ISO_DATA_HDR_SZ, &conn->time_stamp, BLE_HCI_ISO_DATA_LOAD_TS_SZ); + } + + dl_hdr = (conn->sdu_len << 16) | conn->pkt_seq_num; + + memcpy(frag + BLE_HCI_ISO_DATA_HDR_SZ + (conn->ts_flag ? BLE_HCI_ISO_DATA_LOAD_TS_SZ : 0), + &dl_hdr, BLE_HCI_ISO_DATA_LOAD_HDR_SZ); +} + +int +ble_hci_tx_iso_data(const uint8_t *data, uint16_t len, void *arg) +{ + int rc = 1; +#if CONFIG_BT_LE_ISO_SUPPORT + // return ble_transport_to_ll_iso(data, len, arg); + extern int ble_hci_trans_hs_iso_tx(const uint8_t *data, uint16_t length, void *arg); + rc = ble_hci_trans_hs_iso_tx(data, len, arg); +#endif // #if CONFIG_BT_LE_ISO_SUPPORT + return rc; +} + +static int +ble_hci_iso_tx_now(struct ble_hci_iso_conn *conn, const uint8_t *sdu, + uint32_t time_stamp, uint16_t pkt_seq_num) +{ + uint8_t dlh_len; + uint8_t *frag; + int rc; + +#if (BLE_ISO_STD_FLOW_CTRL == TRUE) + /* Get the Controller ISO buffer needed for the SDU */ + uint8_t count = ble_hs_hci_iso_buf_needed(conn); + + /* Make sure the Controller ISO buffer can accommodate the SDU completely */ + if (count > ble_hs_iso_avail_pkts) { + HCI_TRACE_ERROR("ISO flow control(%u/%u)!\n", count, ble_hs_iso_avail_pkts); + return 1; + } +#elif (BLE_ISO_NON_STD_FLOW_CTRL == TRUE) + extern uint16_t ble_ll_iso_free_buf_num_get(uint16_t conn_handle); + if (ble_ll_iso_free_buf_num_get(conn->conn_handle) == 0) { + HCI_TRACE_ERROR("ISO flow control!\n"); + return 1; + } +#endif + + dlh_len = (conn->ts_flag ? BLE_HCI_ISO_DATA_LOAD_TS_SZ : 0) + BLE_HCI_ISO_DATA_LOAD_HDR_SZ; + + frag = malloc(BLE_HCI_ISO_DATA_HDR_SZ + dlh_len + conn->sdu_len); + if (frag == NULL) { + HCI_TRACE_ERROR("frag is null\n"); + return 6; + } + + ble_hci_iso_hdr_append(conn, + frag, + BLE_HCI_ISO_PB_COMP_SDU, + dlh_len + conn->sdu_len); + + memcpy(frag + BLE_HCI_ISO_DATA_HDR_SZ + dlh_len, + sdu, + conn->sdu_len); + + rc = ble_hci_tx_iso_data(frag, BLE_HCI_ISO_DATA_HDR_SZ + dlh_len + conn->sdu_len, NULL); + if (rc) { + HCI_TRACE_ERROR("iso tx failed\n"); + return 14; + } + +#if (BLE_ISO_STD_FLOW_CTRL == TRUE) + /* If an ISO SDU is fragmented into fragments, flow control is not supported. + * + * Currently even if an SDU is larger than the ISO buffer size, fragmentation + * will not happen here, the SDU will be posted to Controller completely. + */ + ble_hs_iso_avail_pkts -= 1; +#endif /* (BLE_ISO_STD_FLOW_CTRL) */ + + return 0; +} + +int +esp_ble_hci_iso_tx(uint16_t conn_handle, const uint8_t *sdu, uint16_t sdu_len, + bool ts_flag, uint32_t time_stamp, uint16_t pkt_seq_num) +{ + struct ble_hci_iso_conn *conn; + uint16_t max_sdu; + int rc; + + osi_mutex_global_lock(); + + /* For sending empty SDU, we could use an SDU with zero length. */ + if (sdu == NULL && sdu_len != 0) { + HCI_TRACE_ERROR("Invalid iso sdu\n"); + rc = 3; + goto end; + } + + /* TODO: + * Use Host functions to replace the above LL implementation. + */ + max_sdu = 0x0FFF; + + if (sdu_len > max_sdu) { + HCI_TRACE_ERROR("Too large iso sdu %d, max_sdu %d\n", sdu_len, max_sdu); + rc = 8; + goto end; + } + + conn = ble_hci_iso_conn_find(conn_handle); + if (!conn) { + conn = ble_hci_iso_alloc_conn(conn_handle); + } + if (!conn) { + rc = 7; + goto end; + } + + conn->ts_flag = ts_flag; + conn->time_stamp = time_stamp; + conn->pkt_seq_num = pkt_seq_num; + conn->sdu_len = sdu_len; + + rc = ble_hci_iso_tx_now(conn, sdu, time_stamp, pkt_seq_num); +end: + osi_mutex_global_unlock(); + return rc; +} + +#endif // #if (BLE_FEAT_ISO_EN == TRUE) diff --git a/lib/bt/host/bluedroid/hci/hci_hal_h4.c b/lib/bt/host/bluedroid/hci/hci_hal_h4.c index 9663126a..1dcdf67d 100644 --- a/lib/bt/host/bluedroid/hci/hci_hal_h4.c +++ b/lib/bt/host/bluedroid/hci/hci_hal_h4.c @@ -35,16 +35,16 @@ #include "esp_bluedroid_hci.h" #include "stack/hcimsgs.h" -#if ((BT_CONTROLLER_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER) -#include "ble_hci_trans.h" -#endif - #if (C2H_FLOW_CONTROL_INCLUDED == TRUE) #include "l2c_int.h" #endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE #include "stack/hcimsgs.h" #include "hci_log/bt_hci_log.h" +#if CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED +#include "ble_log/ble_log_spi_out.h" +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED + #define HCI_BLE_EVENT 0x3e #define PACKET_TYPE_TO_INBOUND_INDEX(type) ((type) - 2) #define PACKET_TYPE_TO_INDEX(type) ((type) - 1) @@ -56,9 +56,6 @@ #define HCI_HAL_BLE_ADV_RPT_QUEUE_LEN_MAX (200) #endif -extern bool BTU_check_queue_is_congest(void); - - static const uint8_t preamble_sizes[] = { HCI_COMMAND_PREAMBLE_SIZE, HCI_ACL_PREAMBLE_SIZE, @@ -75,6 +72,7 @@ static const uint16_t outbound_event_types[] = { typedef struct { fixed_queue_t *rx_q; +#if (BLE_42_SCAN_EN == TRUE) struct pkt_queue *adv_rpt_q; #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) osi_mutex_t adv_flow_lock; @@ -84,6 +82,7 @@ typedef struct { pkt_linked_item_t *adv_fc_cmd_buf; bool cmd_buf_in_use; #endif +#endif // #if (BLE_42_SCAN_EN == TRUE) hci_hal_callbacks_t *callbacks; osi_thread_t *hci_h4_thread; struct osi_event *upstream_data_ready; @@ -97,15 +96,18 @@ static const esp_bluedroid_hci_driver_callbacks_t hci_host_cb; static void host_send_pkt_available_cb(void); static int host_recv_pkt_cb(uint8_t *data, uint16_t len); static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet); +#if (BLE_42_SCAN_EN == TRUE) static void hci_hal_h4_hdl_rx_adv_rpt(pkt_linked_item_t *linked_pkt); +#endif // #if (BLE_42_SCAN_EN == TRUE) static void hci_upstream_data_handler(void *arg); static bool hci_upstream_data_post(uint32_t timeout); +#if (BLE_42_SCAN_EN == TRUE) #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) static void hci_adv_flow_monitor(void *context); static void hci_adv_flow_cmd_free_cb(pkt_linked_item_t *linked_pkt); #endif - +#endif // #if (BLE_42_SCAN_EN == TRUE) static bool hci_hal_env_init(const hci_hal_callbacks_t *upper_callbacks, osi_thread_t *task_thread) { assert(upper_callbacks != NULL); @@ -113,7 +115,7 @@ static bool hci_hal_env_init(const hci_hal_callbacks_t *upper_callbacks, osi_thr hci_hal_env.hci_h4_thread = task_thread; hci_hal_env.callbacks = (hci_hal_callbacks_t *)upper_callbacks; - +#if (BLE_42_SCAN_EN == TRUE) #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) hci_hal_env.adv_fc_cmd_buf = osi_calloc(HCI_CMD_LINKED_BUF_SIZE(HCIC_PARAM_SIZE_BLE_UPDATE_ADV_FLOW_CONTROL)); assert(hci_hal_env.adv_fc_cmd_buf != NULL); @@ -126,12 +128,13 @@ static bool hci_hal_env_init(const hci_hal_callbacks_t *upper_callbacks, osi_thr hci_hal_env.adv_flow_monitor = osi_alarm_new("adv_fc_mon", hci_adv_flow_monitor, NULL, HCI_ADV_FLOW_MONITOR_PERIOD_MS); assert (hci_hal_env.adv_flow_monitor != NULL); #endif - +#endif // #if (BLE_42_SCAN_EN == TRUE) hci_hal_env.rx_q = fixed_queue_new(QUEUE_SIZE_MAX); assert(hci_hal_env.rx_q != NULL); - +#if (BLE_42_SCAN_EN == TRUE) hci_hal_env.adv_rpt_q = pkt_queue_create(); assert(hci_hal_env.adv_rpt_q != NULL); +#endif // #if (BLE_42_SCAN_EN == TRUE) struct osi_event *event = osi_event_create(hci_upstream_data_handler, NULL); assert(event != NULL); @@ -144,19 +147,22 @@ static bool hci_hal_env_init(const hci_hal_callbacks_t *upper_callbacks, osi_thr static void hci_hal_env_deinit(void) { fixed_queue_t *rx_q = hci_hal_env.rx_q; +#if (BLE_42_SCAN_EN == TRUE) struct pkt_queue *adv_rpt_q = hci_hal_env.adv_rpt_q; +#endif // #if (BLE_42_SCAN_EN == TRUE) struct osi_event *upstream_data_ready = hci_hal_env.upstream_data_ready; hci_hal_env.rx_q = NULL; +#if (BLE_42_SCAN_EN == TRUE) hci_hal_env.adv_rpt_q = NULL; +#endif // #if (BLE_42_SCAN_EN == TRUE) hci_hal_env.upstream_data_ready = NULL; - fixed_queue_free(rx_q, osi_free_func); - +#if (BLE_42_SCAN_EN == TRUE) pkt_queue_destroy(adv_rpt_q, NULL); - +#endif // #if (BLE_42_SCAN_EN == TRUE) osi_event_delete(upstream_data_ready); - +#if (BLE_42_SCAN_EN == TRUE) #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) hci_hal_env.cmd_buf_in_use = true; osi_alarm_cancel(hci_hal_env.adv_flow_monitor); @@ -166,7 +172,7 @@ static void hci_hal_env_deinit(void) osi_free(hci_hal_env.adv_fc_cmd_buf); hci_hal_env.adv_fc_cmd_buf = NULL; #endif - +#endif // #if (BLE_42_SCAN_EN == TRUE) hci_hal_env.hci_h4_thread = NULL; memset(&hci_hal_env, 0, sizeof(hci_hal_env_t)); @@ -225,11 +231,37 @@ static uint16_t transmit_data(serial_data_type_t type, return length - 1; } +#if (BLE_FEAT_ISO_EN == TRUE) +typedef void ble_host_rx_iso_data_fn(uint8_t *data, uint16_t len); + +static ble_host_rx_iso_data_fn *ble_host_iso_rx_cb = NULL; + +void ble_host_register_rx_iso_data_cb(void *cb) +{ + /* If the iso rx cb is already registered, we will give + * a warning log here, and the cb will still be updated. + */ + if (ble_host_iso_rx_cb) { + HCI_TRACE_WARNING("iso rx cb %p already registered\n", ble_host_iso_rx_cb); + } + + ble_host_iso_rx_cb = cb; +} + +void ble_hci_register_rx_iso_data_cb(void *cb) +{ + ble_host_register_rx_iso_data_cb(cb); +} + +#endif // #if (BLE_FEAT_ISO_EN == TRUE) + // Internal functions static void hci_upstream_data_handler(void *arg) { fixed_queue_t *rx_q = hci_hal_env.rx_q; +#if (BLE_42_SCAN_EN == TRUE) struct pkt_queue *adv_rpt_q = hci_hal_env.adv_rpt_q; +#endif // #if (BLE_42_SCAN_EN == TRUE) size_t pkts_to_process; do { @@ -241,7 +273,7 @@ static void hci_upstream_data_handler(void *arg) } } } while (0); - +#if (BLE_42_SCAN_EN == TRUE) do { pkts_to_process = pkt_queue_length(adv_rpt_q); for (size_t i = 0; i < pkts_to_process; i++) { @@ -251,8 +283,12 @@ static void hci_upstream_data_handler(void *arg) } } } while (0); - - if (!fixed_queue_is_empty(rx_q) || pkt_queue_length(adv_rpt_q) > 0) { +#endif // #if (BLE_42_SCAN_EN == TRUE) + if (!fixed_queue_is_empty(rx_q) +#if (BLE_42_SCAN_EN == TRUE) + || pkt_queue_length(adv_rpt_q) > 0 +#endif // #if (BLE_42_SCAN_EN == TRUE) + ) { hci_upstream_data_post(OSI_THREAD_MAX_TIMEOUT); } } @@ -293,6 +329,7 @@ bool host_recv_adv_packet(uint8_t *packet) return false; } +#if (BLE_42_SCAN_EN == TRUE) #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) static void hci_adv_flow_monitor(void *context) { @@ -418,6 +455,7 @@ int hci_adv_credits_force_release(uint16_t num) return credits_released; } #endif +#endif // #if (BLE_42_SCAN_EN == TRUE) static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet) { @@ -479,7 +517,7 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet) packet->event = outbound_event_types[PACKET_TYPE_TO_INDEX(type)]; hci_hal_env.callbacks->packet_ready(packet); } - +#if (BLE_42_SCAN_EN == TRUE) static void hci_hal_h4_hdl_rx_adv_rpt(pkt_linked_item_t *linked_pkt) { uint8_t type; @@ -515,13 +553,6 @@ static void hci_hal_h4_hdl_rx_adv_rpt(pkt_linked_item_t *linked_pkt) goto _discard_packet; } -#if SCAN_QUEUE_CONGEST_CHECK - if(BTU_check_queue_is_congest()) { - HCI_TRACE_DEBUG("BtuQueue is congested"); - goto _discard_packet; - } -#endif - packet->event = outbound_event_types[PACKET_TYPE_TO_INDEX(type)]; hci_hal_env.callbacks->adv_rpt_ready(linked_pkt); @@ -533,6 +564,7 @@ _discard_packet: hci_adv_credits_prep_to_release(1); #endif } +#endif // #if (BLE_42_SCAN_EN == TRUE) static void host_send_pkt_available_cb(void) { @@ -555,7 +587,12 @@ void bt_record_hci_data(uint8_t *data, uint16_t len) )) { bt_hci_log_record_hci_adv(HCI_LOG_DATA_TYPE_ADV, &data[2], len - 2); } else { - uint8_t data_type = ((data[0] == 2) ? HCI_LOG_DATA_TYPE_C2H_ACL : data[0]); + uint8_t data_type; + if (data[0] == HCI_LOG_DATA_TYPE_ISO_DATA) { + data_type = HCI_LOG_DATA_TYPE_ISO_DATA; + } else { + data_type = ((data[0] == 2) ? HCI_LOG_DATA_TYPE_C2H_ACL : data[0]); + } bt_hci_log_record_hci_data(data_type, &data[1], len - 1); } #endif // (BT_HCI_LOG_INCLUDED == TRUE) @@ -563,17 +600,33 @@ void bt_record_hci_data(uint8_t *data, uint16_t len) static int host_recv_pkt_cb(uint8_t *data, uint16_t len) { +#if (BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER) + ble_log_spi_out_write_with_ts(BLE_LOG_SPI_OUT_SOURCE_HCI_UPSTREAM, data, len); +#endif // (BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER) //Target has packet to host, malloc new buffer for packet BT_HDR *pkt = NULL; +#if (BLE_42_SCAN_EN == TRUE) pkt_linked_item_t *linked_pkt = NULL; +#endif // #if (BLE_42_SCAN_EN == TRUE) size_t pkt_size; - if (hci_hal_env.rx_q == NULL) { + if ((hci_hal_env.rx_q == NULL) || (data == NULL)) { return 0; } bt_record_hci_data(data, len); +#if (BLE_FEAT_ISO_EN == TRUE) + if (data[0] == DATA_TYPE_ISO) { + if (ble_host_iso_rx_cb) { + ble_host_iso_rx_cb(&data[1], len -1); + } + + free(data); + return 0; + } +#endif // #if (BLE_FEAT_ISO_EN == TRUE) + bool is_adv_rpt = host_recv_adv_packet(data); if (!is_adv_rpt) { @@ -588,8 +641,11 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len) pkt->len = len; pkt->layer_specific = 0; memcpy(pkt->data, data, len); - fixed_queue_enqueue(hci_hal_env.rx_q, pkt, FIXED_QUEUE_MAX_TIMEOUT); + { + fixed_queue_enqueue(hci_hal_env.rx_q, pkt, FIXED_QUEUE_MAX_TIMEOUT); + } } else { +#if (BLE_42_SCAN_EN == TRUE) #if !BLE_ADV_REPORT_FLOW_CONTROL // drop the packets if pkt_queue length goes beyond upper limit if (pkt_queue_length(hci_hal_env.adv_rpt_q) > HCI_HAL_BLE_ADV_RPT_QUEUE_LEN_MAX) { @@ -597,7 +653,11 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len) } #endif pkt_size = BT_PKT_LINKED_HDR_SIZE + BT_HDR_SIZE + len; + #if HEAP_MEMORY_DEBUG linked_pkt = (pkt_linked_item_t *) osi_calloc(pkt_size); + #else + linked_pkt = (pkt_linked_item_t *) osi_calloc_base(pkt_size); + #endif if (!linked_pkt) { #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) hci_adv_credits_consumed(1); @@ -614,6 +674,9 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len) #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) hci_adv_credits_consumed(1); #endif +#else + assert(0); +#endif // #if (BLE_42_SCAN_EN == TRUE) } hci_upstream_data_post(OSI_THREAD_MAX_TIMEOUT); @@ -622,42 +685,7 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len) return 0; } -#if ((BT_CONTROLLER_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER) -int -ble_hs_hci_rx_evt(uint8_t *hci_ev, void *arg) -{ - if(esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) { - ble_hci_trans_buf_free(hci_ev); - return 0; - } - uint16_t len = hci_ev[1] + 3; - uint8_t *data = (uint8_t *)malloc(len); - assert(data != NULL); - data[0] = 0x04; - memcpy(&data[1], hci_ev, len - 1); - ble_hci_trans_buf_free(hci_ev); - host_recv_pkt_cb(data, len); - free(data); - return 0; -} - - -int -ble_hs_rx_data(struct os_mbuf *om, void *arg) -{ - uint16_t len = OS_MBUF_PKTHDR(om)->omp_len + 1; - uint8_t *data = (uint8_t *)malloc(len); - assert(data != NULL); - data[0] = 0x02; - os_mbuf_copydata(om, 0, len - 1, &data[1]); - host_recv_pkt_cb(data, len); - free(data); - os_mbuf_free_chain(om); - return 0; -} - -#endif static const esp_bluedroid_hci_driver_callbacks_t hci_host_cb = { .notify_host_send_available = host_send_pkt_available_cb, .notify_host_recv = host_recv_pkt_cb, diff --git a/lib/bt/host/bluedroid/hci/hci_layer.c b/lib/bt/host/bluedroid/hci/hci_layer.c index c9f1f5e3..e5cd263f 100644 --- a/lib/bt/host/bluedroid/hci/hci_layer.c +++ b/lib/bt/host/bluedroid/hci/hci_layer.c @@ -537,9 +537,11 @@ static void dispatch_adv_report(pkt_linked_item_t *linked_pkt) //Tell Up-layer received packet. if (btu_task_post(SIG_BTU_HCI_ADV_RPT_MSG, linked_pkt, OSI_THREAD_MAX_TIMEOUT) == false) { osi_free(linked_pkt); +#if (BLE_42_SCAN_EN == TRUE) #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) hci_adv_credits_try_release(1); #endif +#endif // #if (BLE_42_SCAN_EN == TRUE) } } // Misc internal functions diff --git a/lib/bt/host/bluedroid/hci/hci_packet_factory.c b/lib/bt/host/bluedroid/hci/hci_packet_factory.c index 5010e99d..6a84f9ca 100644 --- a/lib/bt/host/bluedroid/hci/hci_packet_factory.c +++ b/lib/bt/host/bluedroid/hci/hci_packet_factory.c @@ -52,6 +52,7 @@ static BT_HDR *make_set_c2h_flow_control(uint8_t enable) return packet; } +#if (BLE_42_SCAN_EN == TRUE) static BT_HDR *make_set_adv_report_flow_control(uint8_t enable, uint16_t num, uint16_t lost_threshold) { uint8_t *stream; @@ -63,7 +64,7 @@ static BT_HDR *make_set_adv_report_flow_control(uint8_t enable, uint16_t num, ui UINT16_TO_STREAM(stream, lost_threshold); return packet; } - +#endif // #if (BLE_42_SCAN_EN == TRUE) static BT_HDR *make_host_buffer_size(uint16_t acl_size, uint8_t sco_size, uint16_t acl_count, uint16_t sco_count) { uint8_t *stream; @@ -158,6 +159,13 @@ static BT_HDR *make_ble_read_buffer_size(void) return make_command_no_params(HCI_BLE_READ_BUFFER_SIZE); } +#if (BLE_FEAT_ISO_EN == TRUE) +static BT_HDR *make_ble_read_buffer_size_v2(void) +{ + return make_command_no_params(HCI_BLE_READ_BUFFER_SZIE_V2); +} +#endif // #if (BLE_FEAT_ISO_EN == TRUE) + static BT_HDR *make_ble_read_supported_states(void) { return make_command_no_params(HCI_BLE_READ_SUPPORTED_STATES); @@ -219,10 +227,18 @@ static BT_HDR *make_write_default_erroneous_data_report(uint8_t enable) return packet; } #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_50_EXTEND_ADV_EN == TRUE) static BT_HDR *make_read_max_adv_data_len(void) { return make_command_no_params(HCI_BLE_RD_MAX_ADV_DATA_LEN); } +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) +#if (BLE_50_EXTEND_SYNC_EN == TRUE) +static BT_HDR *read_periodic_adv_list_size(void) +{ + return make_command_no_params(HCI_BLE_RD_PERIOD_ADV_LIST_SIZE); +} +#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) // Internal functions @@ -252,7 +268,9 @@ static const hci_packet_factory_t interface = { make_reset, make_read_buffer_size, make_set_c2h_flow_control, +#if (BLE_42_SCAN_EN == TRUE) make_set_adv_report_flow_control, +#endif // #if (BLE_42_SCAN_EN == TRUE) make_host_buffer_size, make_read_local_version_info, make_read_bd_addr, @@ -265,11 +283,19 @@ static const hci_packet_factory_t interface = { make_ble_write_host_support, make_ble_read_white_list_size, make_ble_read_buffer_size, +#if (BLE_FEAT_ISO_EN == TRUE) + make_ble_read_buffer_size_v2, +#endif // #if (BLE_FEAT_ISO_EN == TRUE) make_ble_read_supported_states, make_ble_read_local_supported_features, make_ble_read_resolving_list_size, #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_50_EXTEND_ADV_EN == TRUE) make_read_max_adv_data_len, +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) +#if (BLE_50_EXTEND_SYNC_EN == TRUE) + read_periodic_adv_list_size, +#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) make_ble_read_suggested_default_data_length, make_ble_write_suggested_default_data_length, diff --git a/lib/bt/host/bluedroid/hci/hci_packet_parser.c b/lib/bt/host/bluedroid/hci/hci_packet_parser.c index 88515376..b254c9be 100644 --- a/lib/bt/host/bluedroid/hci/hci_packet_parser.c +++ b/lib/bt/host/bluedroid/hci/hci_packet_parser.c @@ -155,6 +155,26 @@ static void parse_ble_read_buffer_size_response( osi_free(response); } +#if (BLE_FEAT_ISO_EN == TRUE) +static void parse_ble_read_buffer_size_response_v2 ( + BT_HDR *response, + uint16_t *data_size_ptr, + uint8_t *acl_buffer_count_ptr, + uint16_t *iso_pkt_len_ptr, + uint8_t *iso_pkt_num_ptr) +{ + + uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_BUFFER_SZIE_V2, 3 /* bytes after */); + assert(stream != NULL); + STREAM_TO_UINT16(*data_size_ptr, stream); + STREAM_TO_UINT8(*acl_buffer_count_ptr, stream); + STREAM_TO_UINT16(*iso_pkt_len_ptr, stream); + STREAM_TO_UINT8(*iso_pkt_num_ptr, stream); + + osi_free(response); +} +#endif // #if (BLE_FEAT_ISO_EN == TRUE) + static void parse_ble_read_supported_states_response( BT_HDR *response, uint8_t *supported_states, @@ -186,7 +206,9 @@ static void parse_ble_read_resolving_list_size_response( { uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_RESOLVING_LIST_SIZE, 1 /* bytes after */); - STREAM_TO_UINT8(*resolving_list_size_ptr, stream); + if (stream) { + STREAM_TO_UINT8(*resolving_list_size_ptr, stream); + } osi_free(response); } @@ -198,22 +220,43 @@ static void parse_ble_read_suggested_default_data_length_response( { uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_DEFAULT_DATA_LENGTH, 2 /* bytes after */); - STREAM_TO_UINT16(*ble_default_packet_length_ptr, stream); - STREAM_TO_UINT16(*ble_default_packet_txtime_ptr, stream); + if (stream) { + STREAM_TO_UINT16(*ble_default_packet_length_ptr, stream); + STREAM_TO_UINT16(*ble_default_packet_txtime_ptr, stream); + } + osi_free(response); } + #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_50_EXTEND_ADV_EN == TRUE) static void parse_ble_read_adv_max_len_response( BT_HDR *response, uint16_t *adv_max_len_ptr) { uint8_t *stream = read_command_complete_header(response, HCI_BLE_RD_MAX_ADV_DATA_LEN, 1 /* bytes after */); - // Size: 2 Octets ; Value: 0x001F – 0x0672 ; Maximum supported advertising data length - STREAM_TO_UINT16(*adv_max_len_ptr, stream); + if (stream) { + // Size: 2 Octets ; Value: 0x001F – 0x0672 ; Maximum supported advertising data length + STREAM_TO_UINT16(*adv_max_len_ptr, stream); + } + osi_free(response); +} +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE +#if (BLE_50_EXTEND_SYNC_EN == TRUE) +static void parse_ble_read_periodic_adv_list_size_response( + BT_HDR *response, + uint16_t *periodic_adv_list_size_ptr) +{ + uint8_t *stream = read_command_complete_header(response, HCI_BLE_RD_PERIOD_ADV_LIST_SIZE, 1 /* bytes after */); + if (stream) { + // Size: 1 Octets ; Value: 0x01 to 0xFF ; Total number of Periodic Advertiser list entries that can be stored in the Controller + STREAM_TO_UINT8(*periodic_adv_list_size_ptr, stream); + } osi_free(response); } +#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) @@ -254,6 +297,7 @@ static uint8_t *read_command_complete_header( STREAM_TO_UINT8(status, stream); if (status != HCI_SUCCESS) { + HCI_TRACE_ERROR("%s failed: opcode 0x%04x, status 0x%02x", __func__, opcode, status); return NULL; } @@ -270,11 +314,19 @@ static const hci_packet_parser_t interface = { parse_read_local_extended_features_response, parse_ble_read_white_list_size_response, parse_ble_read_buffer_size_response, +#if (BLE_FEAT_ISO_EN == TRUE) + parse_ble_read_buffer_size_response_v2, +#endif // #if (BLE_FEAT_ISO_EN == TRUE) parse_ble_read_supported_states_response, parse_ble_read_local_supported_features_response, parse_ble_read_resolving_list_size_response, #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_50_EXTEND_ADV_EN == TRUE) parse_ble_read_adv_max_len_response, +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) +#if (BLE_50_EXTEND_SYNC_EN == TRUE) + parse_ble_read_periodic_adv_list_size_response, +#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) parse_ble_read_suggested_default_data_length_response }; diff --git a/lib/bt/host/bluedroid/hci/include/hci/ble_hci_iso.h b/lib/bt/host/bluedroid/hci/include/hci/ble_hci_iso.h new file mode 100644 index 00000000..9b289677 --- /dev/null +++ b/lib/bt/host/bluedroid/hci/include/hci/ble_hci_iso.h @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_HCI_ISO_ +#define H_BLE_HCI_ISO_ + +#include <stdint.h> +#include <stdbool.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct ble_hci_iso_pkt_hdr { + uint16_t conn_handle : 12, + pb_flag : 2, + ts_flag : 1; + uint16_t data_load_len; +} __attribute__((packed)); + +struct ble_hci_iso_pkt { + /* ISO header */ + uint16_t conn_handle; /* CIS or BIS handle. */ + uint8_t pb_flag : 2, /* Packet boundary flag. */ + ts_flag : 1; /* Timestamp flag. */ + uint16_t iso_data_load_len; /* ISO Data Load length. */ + + /* ISO Data Load */ + uint32_t time_stamp; /* Timestamp. */ + uint16_t packet_seq; /* Packet sequence number. */ + uint16_t iso_sdu_len; /* SDU length. */ + uint8_t ps_flag; /* Packet status. */ + const uint8_t *sdu; /* First byte of ISO SDU. */ +}; + +struct ble_hci_iso_tx { + struct ble_hci_iso_pkt pkt; +}; + +struct ble_hci_iso_rx { + struct ble_hci_iso_pkt pkt; +}; + +struct ble_hci_iso_conn { + uint16_t conn_handle; + uint8_t enabled : 1, + pb_flag : 2, + ts_flag : 1; + uint32_t time_stamp; + uint16_t pkt_seq_num; + uint16_t sdu_len; +}; + +int ble_hci_set_iso_buf_sz(uint16_t pktlen, uint8_t max_pkts); + +void ble_hci_get_iso_buf_size(uint16_t *pktlen, uint8_t *max_pkts); + +void ble_hci_add_iso_avail_pkts(uint16_t delta); + +struct ble_hci_iso_conn *ble_hci_iso_conn_find(uint16_t conn_handle); + +int esp_ble_hci_iso_tx(uint16_t conn_handle, const uint8_t *sdu, uint16_t sdu_len, + bool ts_flag, uint32_t time_stamp, uint16_t pkt_seq_num); + +#ifdef __cplusplus +} +#endif + +#endif /* H_BLE_HCI_ISO_ */ diff --git a/lib/bt/host/bluedroid/hci/include/hci/hci_hal.h b/lib/bt/host/bluedroid/hci/include/hci/hci_hal.h index fe5796db..aec926b6 100644 --- a/lib/bt/host/bluedroid/hci/include/hci/hci_hal.h +++ b/lib/bt/host/bluedroid/hci/include/hci/hci_hal.h @@ -31,7 +31,8 @@ typedef enum { DATA_TYPE_COMMAND = 1, DATA_TYPE_ACL = 2, DATA_TYPE_SCO = 3, - DATA_TYPE_EVENT = 4 + DATA_TYPE_EVENT = 4, + DATA_TYPE_ISO = 5, } serial_data_type_t; typedef void (*packet_ready_cb)(BT_HDR *packet); diff --git a/lib/bt/host/bluedroid/hci/include/hci/hci_layer.h b/lib/bt/host/bluedroid/hci/include/hci/hci_layer.h index 8e822f0f..c48d0565 100644 --- a/lib/bt/host/bluedroid/hci/include/hci/hci_layer.h +++ b/lib/bt/host/bluedroid/hci/include/hci/hci_layer.h @@ -104,10 +104,11 @@ void hci_shut_down(void); bool hci_downstream_data_post(uint32_t timeout); +#if (BLE_42_SCAN_EN == TRUE) #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) int hci_adv_credits_prep_to_release(uint16_t num); int hci_adv_credits_try_release(uint16_t num); int hci_adv_credits_force_release(uint16_t num); #endif - +#endif // #if (BLE_42_SCAN_EN == TRUE) #endif /* _HCI_LAYER_H_ */ diff --git a/lib/bt/host/bluedroid/hci/include/hci/hci_packet_factory.h b/lib/bt/host/bluedroid/hci/include/hci/hci_packet_factory.h index c1580fd8..2d36051a 100644 --- a/lib/bt/host/bluedroid/hci/include/hci/hci_packet_factory.h +++ b/lib/bt/host/bluedroid/hci/include/hci/hci_packet_factory.h @@ -26,7 +26,9 @@ typedef struct { BT_HDR *(*make_reset)(void); BT_HDR *(*make_read_buffer_size)(void); BT_HDR *(*make_set_c2h_flow_control)(uint8_t enable); +#if (BLE_42_SCAN_EN == TRUE) BT_HDR *(*make_set_adv_report_flow_control)(uint8_t enable, uint16_t num, uint16_t lost_threshold); +#endif // #if (BLE_42_SCAN_EN == TRUE) BT_HDR *(*make_host_buffer_size)(uint16_t acl_size, uint8_t sco_size, uint16_t acl_count, uint16_t sco_count); BT_HDR *(*make_read_local_version_info)(void); BT_HDR *(*make_read_bd_addr)(void); @@ -39,11 +41,19 @@ typedef struct { BT_HDR *(*make_ble_write_host_support)(uint8_t supported_host, uint8_t simultaneous_host); BT_HDR *(*make_ble_read_white_list_size)(void); BT_HDR *(*make_ble_read_buffer_size)(void); +#if (BLE_FEAT_ISO_EN == TRUE) + BT_HDR *(*make_ble_read_buffer_size_v2)(void); +#endif // #if (BLE_FEAT_ISO_EN == TRUE) BT_HDR *(*make_ble_read_supported_states)(void); BT_HDR *(*make_ble_read_local_supported_features)(void); BT_HDR *(*make_ble_read_resolving_list_size)(void); #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_50_EXTEND_ADV_EN == TRUE) BT_HDR *(*make_read_max_adv_data_len)(void); +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) +#if (BLE_50_EXTEND_SYNC_EN == TRUE) + BT_HDR *(*read_periodic_adv_list_size)(void); +#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) BT_HDR *(*make_ble_read_suggested_default_data_length)(void); BT_HDR *(*make_ble_write_suggested_default_data_length)(uint16_t SuggestedMaxTxOctets, uint16_t SuggestedMaxTxTime); diff --git a/lib/bt/host/bluedroid/hci/include/hci/hci_packet_parser.h b/lib/bt/host/bluedroid/hci/include/hci/hci_packet_parser.h index e46acc17..c40ffef9 100644 --- a/lib/bt/host/bluedroid/hci/include/hci/hci_packet_parser.h +++ b/lib/bt/host/bluedroid/hci/include/hci/hci_packet_parser.h @@ -79,6 +79,16 @@ typedef struct { uint8_t *acl_buffer_count_ptr ); +#if (BLE_FEAT_ISO_EN == TRUE) + void (*parse_ble_read_buffer_size_response_v2) ( + BT_HDR *response, + uint16_t *data_size_ptr, + uint8_t *acl_buffer_count_ptr, + uint16_t *iso_pkt_len_ptr, + uint8_t *iso_pkt_num_ptr + ); +#endif // #if (BLE_FEAT_ISO_EN == TRUE) + void (*parse_ble_read_supported_states_response)( BT_HDR *response, uint8_t *supported_states, @@ -95,10 +105,18 @@ typedef struct { uint8_t *resolving_list_size_ptr ); #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_50_EXTEND_ADV_EN == TRUE) void (*parse_ble_read_adv_max_len_response) ( - BT_HDR *respone, + BT_HDR *response, uint16_t *ble_ext_adv_data_max_len_ptr ); +#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) +#if (BLE_50_EXTEND_SYNC_EN == TRUE) + void (*parse_ble_read_periodic_adv_list_size_response) ( + BT_HDR *response, + uint16_t *periodic_advertiser_list_size + ); +#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) void (*parse_ble_read_suggested_default_data_length_response)( BT_HDR *response, diff --git a/lib/bt/host/bluedroid/hci/packet_fragmenter.c b/lib/bt/host/bluedroid/hci/packet_fragmenter.c index 78b6151e..d8f2ff91 100644 --- a/lib/bt/host/bluedroid/hci/packet_fragmenter.c +++ b/lib/bt/host/bluedroid/hci/packet_fragmenter.c @@ -171,6 +171,12 @@ static void reassemble_and_dispatch(BT_HDR *packet) return; } partial_packet = (BT_HDR *)osi_calloc(full_length + sizeof(BT_HDR)); + + if (partial_packet == NULL) { + HCI_TRACE_WARNING("%s full_length %d no memory.\n", __func__, full_length); + assert(0); + } + partial_packet->event = packet->event; partial_packet->len = full_length; partial_packet->offset = packet->len; |
