diff --git a/components/bt/host/bluedroid/api/esp_gatt_common_api.c b/components/bt/host/bluedroid/api/esp_gatt_common_api.c index 7a26013b8..983092516 100644 --- a/components/bt/host/bluedroid/api/esp_gatt_common_api.c +++ b/components/bt/host/bluedroid/api/esp_gatt_common_api.c @@ -49,10 +49,35 @@ esp_err_t esp_ble_gatt_set_local_mtu (uint16_t mtu) } #if (BLE_INCLUDED == TRUE) -extern uint16_t L2CA_GetFreePktBufferNum_LE(void); +extern UINT16 L2CA_GetFreePktBufferNum_LE(void); -uint16_t esp_ble_get_sendable_packets_num () +/** + * @brief This function is called to get currently sendable packets number on controller, + * the function is called only in BLE running core and single connection now. + * + * @return + * sendable packets number on controller + * + */ + +uint16_t esp_ble_get_sendable_packets_num (void) { return L2CA_GetFreePktBufferNum_LE(); } + +/** + * @brief This function is used to query the number of available buffers for the current connection. + * When you need to query the current available buffer number, it is recommended to use this API. + * @param[in] conn_id: current connection id. + * + * @return + * Number of available buffers for the current connection + * + */ + +extern UINT16 L2CA_GetCurFreePktBufferNum_LE(UINT16 conn_id); +uint16_t esp_ble_get_cur_sendable_packets_num (uint16_t connid) +{ + return L2CA_GetCurFreePktBufferNum_LE(connid); +} #endif \ No newline at end of file diff --git a/components/bt/host/bluedroid/api/esp_gattc_api.c b/components/bt/host/bluedroid/api/esp_gattc_api.c index c8da7bcec..a3a086a85 100644 --- a/components/bt/host/bluedroid/api/esp_gattc_api.c +++ b/components/bt/host/bluedroid/api/esp_gattc_api.c @@ -431,7 +431,9 @@ esp_err_t esp_ble_gattc_write_char(esp_gatt_if_t gattc_if, arg.write_char.value = value; arg.write_char.write_type = write_type; arg.write_char.auth_req = auth_req; - + if(write_type == ESP_GATT_WRITE_TYPE_NO_RSP){ + l2ble_update_att_acl_pkt_num(L2CA_ADD_BTC_NUM, NULL); + } return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), btc_gattc_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } @@ -461,7 +463,9 @@ esp_err_t esp_ble_gattc_write_char_descr (esp_gatt_if_t gattc_if, arg.write_descr.value = value; arg.write_descr.write_type = write_type; arg.write_descr.auth_req = auth_req; - + if(write_type == ESP_GATT_WRITE_TYPE_NO_RSP){ + l2ble_update_att_acl_pkt_num(L2CA_ADD_BTC_NUM, NULL); + } return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), btc_gattc_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } diff --git a/components/bt/host/bluedroid/api/esp_gatts_api.c b/components/bt/host/bluedroid/api/esp_gatts_api.c index 80d89b30b..91edc26b5 100644 --- a/components/bt/host/bluedroid/api/esp_gatts_api.c +++ b/components/bt/host/bluedroid/api/esp_gatts_api.c @@ -273,7 +273,9 @@ esp_err_t esp_ble_gatts_send_indicate(esp_gatt_if_t gatts_if, uint16_t conn_id, arg.send_ind.need_confirm = need_confirm; arg.send_ind.value_len = value_len; arg.send_ind.value = value; - + if(need_confirm == false){ + l2ble_update_att_acl_pkt_num(L2CA_ADD_BTC_NUM, NULL); + } return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } diff --git a/components/bt/host/bluedroid/api/include/api/esp_gatt_common_api.h b/components/bt/host/bluedroid/api/include/api/esp_gatt_common_api.h index bee2c28f0..447a26bd9 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gatt_common_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gatt_common_api.h @@ -46,6 +46,7 @@ extern esp_err_t esp_ble_gatt_set_local_mtu (uint16_t mtu); #if (BLE_INCLUDED == TRUE) extern uint16_t esp_ble_get_sendable_packets_num (void); +extern uint16_t esp_ble_get_cur_sendable_packets_num (uint16_t connid); #endif #ifdef __cplusplus diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c index 6e4da29a2..55c17621c 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c @@ -31,7 +31,7 @@ #include "bta/bta_sys.h" #include "bta/bta_gatt_api.h" #include "bta_gattc_int.h" - +#include "stack/l2c_api.h" /***************************************************************************** ** Constants *****************************************************************************/ @@ -602,7 +602,10 @@ void BTA_GATTC_WriteCharValue ( UINT16 conn_id, p_buf->p_value = (UINT8 *)(p_buf + 1); memcpy(p_buf->p_value, p_value, len); } - + if(write_type == BTA_GATTC_TYPE_WRITE_NO_RSP){ + l2ble_update_att_acl_pkt_num(L2CA_DECREASE_BTC_NUM, NULL); + l2ble_update_att_acl_pkt_num(L2CA_ADD_BTU_NUM, NULL); + } bta_sys_sendmsg(p_buf); } return; @@ -649,7 +652,10 @@ void BTA_GATTC_WriteCharDescr (UINT16 conn_id, /* pack the descr data */ memcpy(p_buf->p_value, p_data->p_value, p_data->len); } - + if(write_type == BTA_GATTC_TYPE_WRITE_NO_RSP){ + l2ble_update_att_acl_pkt_num(L2CA_DECREASE_BTC_NUM, NULL); + l2ble_update_att_acl_pkt_num(L2CA_ADD_BTU_NUM, NULL); + } bta_sys_sendmsg(p_buf); } return; diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c b/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c index 87962b1d4..7658c7b1a 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c @@ -674,6 +674,7 @@ void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg) p_msg->api_indicate.len, p_msg->api_indicate.value); } else { + l2ble_update_att_acl_pkt_num(L2CA_DECREASE_BTU_NUM, NULL); status = GATTS_HandleValueNotification (p_msg->api_indicate.hdr.layer_specific, p_msg->api_indicate.attr_id, p_msg->api_indicate.len, diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gatts_api.c b/components/bt/host/bluedroid/bta/gatt/bta_gatts_api.c index 5397c6487..f06a2976e 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gatts_api.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gatts_api.c @@ -31,6 +31,7 @@ #include "bta/bta_gatt_api.h" #include "bta_gatts_int.h" #include "osi/allocator.h" +#include "stack/l2c_api.h" /***************************************************************************** ** Constants @@ -426,6 +427,10 @@ void BTA_GATTS_HandleValueIndication (UINT16 conn_id, UINT16 attr_id, UINT16 dat memcpy(p_buf->value, p_data, data_len); } + if(need_confirm == false){ + l2ble_update_att_acl_pkt_num(L2CA_DECREASE_BTC_NUM, NULL); + l2ble_update_att_acl_pkt_num(L2CA_ADD_BTU_NUM, NULL); + } bta_sys_sendmsg(p_buf); } return; diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_cl.c b/components/bt/host/bluedroid/stack/gatt/gatt_cl.c index 4ffd7ca5a..56a11dd8e 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_cl.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_cl.c @@ -219,6 +219,7 @@ void gatt_act_write (tGATT_CLCB *p_clcb, UINT8 sec_act) if (p_attr) { switch (p_clcb->op_subtype) { case GATT_WRITE_NO_RSP: + l2ble_update_att_acl_pkt_num(L2CA_DECREASE_BTU_NUM, NULL); p_clcb->s_handle = p_attr->handle; op_code = (sec_act == GATT_SEC_SIGN_DATA) ? GATT_SIGN_CMD_WRITE : GATT_CMD_WRITE; rt = gatt_send_write_msg(p_tcb, diff --git a/components/bt/host/bluedroid/stack/include/stack/l2c_api.h b/components/bt/host/bluedroid/stack/include/stack/l2c_api.h index 33abaec7b..421b93d48 100644 --- a/components/bt/host/bluedroid/stack/include/stack/l2c_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/l2c_api.h @@ -29,6 +29,7 @@ #include "common/bt_target.h" #include "stack/l2cdefs.h" #include "stack/hcidefs.h" +#include "osi/fixed_queue.h" /***************************************************************************** ** Constants @@ -1228,7 +1229,21 @@ extern UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda, tBT_TRANSPORT transp extern BOOLEAN L2CA_CheckIsCongest(UINT16 fixed_cid, UINT16 handle); +#define L2CA_GET_ATT_NUM 0 +#define L2CA_ADD_BTC_NUM 1 +#define L2CA_DECREASE_BTC_NUM 2 +#define L2CA_ADD_BTU_NUM 3 +#define L2CA_DECREASE_BTU_NUM 4 +#define L2CA_BUFF_INI 5 +#define L2CA_BUFF_DEINIT 6 +typedef struct { + UINT16 conn_id; + UINT16 * get_num; +} tl2c_buff_param_t; + + +extern void l2ble_update_att_acl_pkt_num(UINT8 type, tl2c_buff_param_t *param); #ifdef __cplusplus } diff --git a/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h b/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h index d24562e51..26075679b 100644 --- a/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h +++ b/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h @@ -74,6 +74,8 @@ #define L2CAP_DEFAULT_MONITOR_TOUT 12000 /* 12000 milliseconds */ #define L2CAP_FCR_ACK_TOUT 200 /* 200 milliseconds */ +#define L2CAP_CACHE_ATT_ACL_NUM 10 + /* Define the possible L2CAP channel states. The names of ** the states may seem a bit strange, but they are taken from ** the Bluetooth specification. @@ -165,6 +167,9 @@ typedef enum { #define L2CAP_MAX_FCR_CFG_TRIES 2 /* Config attempts before disconnecting */ +#ifndef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif typedef uint8_t tL2C_BLE_FIXED_CHNLS_MASK; typedef struct { diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_api.c b/components/bt/host/bluedroid/stack/l2cap/l2c_api.c index 6bd1fadc8..859389c07 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_api.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_api.c @@ -36,7 +36,7 @@ #include "stack/btu.h" #include "stack/btm_api.h" #include "osi/allocator.h" - +#include "gatt_int.h" #if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** @@ -1877,6 +1877,15 @@ UINT16 L2CA_GetFreePktBufferNum_LE(void) { return l2cb.controller_le_xmit_window; } +UINT16 L2CA_GetCurFreePktBufferNum_LE(UINT16 conn_id) +{ + uint16_t num = 0; + tl2c_buff_param_t param; + param.conn_id = conn_id; + param.get_num = # + l2ble_update_att_acl_pkt_num(L2CA_GET_ATT_NUM, ¶m); + return num; +} #endif /******************************************************************************* @@ -2265,3 +2274,89 @@ UINT16 L2CA_FlushChannel (UINT16 lcid, UINT16 num_to_flush) return (num_left); } + +/****************************************************************************** +** +** Function update_acl_pkt_num +** +** Description Update the number of att acl packets to be sent in xmit_hold_q. +** +** Returns None +** +*******************************************************************************/ + +#if BLE_INCLUDED == TRUE +void l2ble_update_att_acl_pkt_num(UINT8 type, tl2c_buff_param_t *param) +{ + static SemaphoreHandle_t buff_semaphore = NULL ; + static INT16 btc_buf; + static INT16 btu_buf; + + if(buff_semaphore != NULL){ + xSemaphoreTake(buff_semaphore, 10 / portTICK_PERIOD_MS); + } + switch (type) + { + case L2CA_ADD_BTC_NUM:{ + btc_buf ++; + break; + } + case L2CA_DECREASE_BTC_NUM:{ + btc_buf --; + break; + } + case L2CA_ADD_BTU_NUM:{ + btu_buf ++; + break; + } + case L2CA_DECREASE_BTU_NUM:{ + btu_buf --; + break; + } + case L2CA_GET_ATT_NUM:{ + INT16 att_acl_pkt_num = 0; + INT16 att_max_num = 0; + *(param->get_num) = 0; + UINT8 tcb_idx = param->conn_id; + tGATT_TCB * p_tcb = gatt_get_tcb_by_idx(tcb_idx); + if (p_tcb == NULL){ + L2CAP_TRACE_ERROR("%s not found p_tcb", __func__); + break; + } + tL2C_LCB * p_lcb = l2cu_find_lcb_by_bd_addr (p_tcb->peer_bda, BT_TRANSPORT_LE); + if (p_lcb == NULL){ + L2CAP_TRACE_ERROR("%s not found p_lcb", __func__); + break; + } + fixed_queue_t * queue = p_lcb->p_fixed_ccbs[L2CAP_ATT_CID - L2CAP_FIRST_FIXED_CHNL]->xmit_hold_q; + att_max_num = MIN(p_lcb->link_xmit_quota, L2CAP_CACHE_ATT_ACL_NUM); + if (queue == NULL){ + L2CAP_TRACE_ERROR("%s not found queue", __func__); + break; + } + att_acl_pkt_num = fixed_queue_length(queue); + if(att_acl_pkt_num < att_max_num){ + if(btc_buf + btu_buf < att_max_num - att_acl_pkt_num){ + *(param->get_num) = att_max_num - att_acl_pkt_num - (btc_buf + btu_buf); + } + } + break; + } + case L2CA_BUFF_INI:{ + btc_buf = 0; + btu_buf = 0; + buff_semaphore = xSemaphoreCreateBinary(); + xSemaphoreGive(buff_semaphore); + break; + } + case L2CA_BUFF_DEINIT:{ + btc_buf = 0; + btu_buf = 0; + break; + } + default: + break; + } + xSemaphoreGive(buff_semaphore); +} +#endif \ No newline at end of file diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_link.c b/components/bt/host/bluedroid/stack/l2cap/l2c_link.c index 22360ac84..960c455d8 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_link.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_link.c @@ -1131,6 +1131,12 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf) while ((l2cb.controller_xmit_window != 0) && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) #endif { + //need check flag: partial_segment_being_sent + if ( (p_lcb->partial_segment_being_sent) + || (p_lcb->link_state != LST_CONNECTED) + || (L2C_LINK_CHECK_POWER_MODE (p_lcb)) ) { + break; + } //L2CAP_TRACE_DEBUG("l2cu_get_next_buffer_to_send = %p",l2cu_get_next_buffer_to_send(p_lcb)); if ((p_buf = l2cu_get_next_buffer_to_send (p_lcb)) == NULL) { break; diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_main.c b/components/bt/host/bluedroid/stack/l2cap/l2c_main.c index e50e59dce..c6baaca3c 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_main.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_main.c @@ -883,6 +883,9 @@ void l2c_init (void) if (l2cb.rcv_pending_q == NULL) { L2CAP_TRACE_ERROR("%s unable to allocate memory for link layer control block", __func__); } +#if BLE_INCLUDED == TRUE + l2ble_update_att_acl_pkt_num(L2CA_BUFF_INI, NULL); +#endif } void l2c_free(void) @@ -892,6 +895,9 @@ void l2c_free(void) #if L2C_DYNAMIC_MEMORY FREE_AND_RESET(l2c_cb_ptr); #endif +#if BLE_INCLUDED == TRUE + l2ble_update_att_acl_pkt_num(L2CA_BUFF_DEINIT, NULL); +#endif } /******************************************************************************* diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c index cd886bbfe..01761346a 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c @@ -3662,7 +3662,7 @@ void l2cu_check_channel_congestion (tL2C_CCB *p_ccb) } else { tL2C_LCB *p_lcb = p_ccb->p_lcb; /* If this channel was not congested but it is congested now, tell the app */ - if ((q_count > p_ccb->buff_quota) || (p_lcb && (p_ccb->local_cid == L2CAP_ATT_CID) && (p_lcb->link_xmit_quota > 0) && (p_lcb->link_xmit_quota <= p_lcb->sent_not_acked))) { + if (q_count > p_ccb->buff_quota || (p_lcb && (p_lcb->link_xmit_data_q) && (list_length(p_lcb->link_xmit_data_q) + q_count) > p_ccb->buff_quota)) { p_ccb->cong_sent = TRUE; if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb) { L2CAP_TRACE_DEBUG ("L2CAP - Calling CongestionStatus_Cb (TRUE),CID:0x%04x,XmitQ:%u,Quota:%u", diff --git a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/main/example_ble_client_throughput.c b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/main/example_ble_client_throughput.c index 92387b62b..60a3774cc 100644 --- a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/main/example_ble_client_throughput.c +++ b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/main/example_ble_client_throughput.c @@ -504,7 +504,7 @@ static void throughput_client_task(void *param) assert(res == pdTRUE); } else { if (is_connect) { - int free_buff_num = esp_ble_get_sendable_packets_num(); + int free_buff_num = esp_ble_get_cur_sendable_packets_num(gl_profile_tab[PROFILE_A_APP_ID].conn_id); if(free_buff_num > 0) { for( ; free_buff_num > 0; free_buff_num--) { // the app data set to 490 just for divided into two packages to send in the low layer diff --git a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/main/example_ble_server_throughput.c b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/main/example_ble_server_throughput.c index 5d2ebeb83..5b75ca0fe 100644 --- a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/main/example_ble_server_throughput.c +++ b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/main/example_ble_server_throughput.c @@ -624,7 +624,7 @@ void throughput_server_task(void *param) assert(res == pdTRUE); } else { if (is_connect) { - int free_buff_num = esp_ble_get_sendable_packets_num(); + int free_buff_num = esp_ble_get_cur_sendable_packets_num(gl_profile_tab[PROFILE_A_APP_ID].conn_id); if(free_buff_num > 0) { for( ; free_buff_num > 0; free_buff_num--) { esp_ble_gatts_send_indicate(gl_profile_tab[PROFILE_A_APP_ID].gatts_if, gl_profile_tab[PROFILE_A_APP_ID].conn_id,