summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jayden Kim <jaydenk@google.com> 2024-11-14 19:38:32 +0000
committer Jayden Kim <jaydenk@google.com> 2024-12-03 17:34:12 +0000
commit5c298722d78529e9f97842468a70f876cc35a764 (patch)
tree0701d5a4f4b60856a82541500808a4ccd4024f06
parent88ba5e075efbc539445b21a77c743fe1d027a039 (diff)
Set the initial local credits to 0 for offload LE socket
Bug: 342012881 Bug: 367419086 Test: m -j Change-Id: Ie2967885b07a2da27ee16027b894db65cfbf2f58
-rw-r--r--system/btif/src/btif_sock_l2cap.cc14
-rw-r--r--system/stack/gap/gap_conn.cc3
-rw-r--r--system/stack/include/l2cap_types.h2
-rw-r--r--system/stack/l2cap/l2c_ble.cc5
-rw-r--r--system/stack/l2cap/l2c_utils.cc3
5 files changed, 24 insertions, 3 deletions
diff --git a/system/btif/src/btif_sock_l2cap.cc b/system/btif/src/btif_sock_l2cap.cc
index a6d724fc53..a9cd4fbcc3 100644
--- a/system/btif/src/btif_sock_l2cap.cc
+++ b/system/btif/src/btif_sock_l2cap.cc
@@ -851,6 +851,13 @@ static void btsock_l2cap_server_listen(l2cap_socket* sock) {
/* Setup ETM settings: mtu will be set below */
std::unique_ptr<tL2CAP_CFG_INFO> cfg = std::make_unique<tL2CAP_CFG_INFO>(
tL2CAP_CFG_INFO{.fcr_present = true, .fcr = kDefaultErtmOptions});
+ /* For hardware offload data path, host stack sets the initial credits to 0. The offload stack
+ * should send initial credits to peer device through L2CAP signaling command when the data path
+ * is switched successfully. */
+ if (sock->data_path == BTSOCK_DATA_PATH_HARDWARE_OFFLOAD) {
+ cfg->init_credit_present = true;
+ cfg->init_credit = 0;
+ }
std::unique_ptr<tL2CAP_ERTM_INFO> ertm_info;
if (!sock->is_le_coc) {
@@ -925,6 +932,13 @@ static bt_status_t btsock_l2cap_listen_or_connect(const char* name, const RawAdd
/* Setup ETM settings: mtu will be set below */
std::unique_ptr<tL2CAP_CFG_INFO> cfg = std::make_unique<tL2CAP_CFG_INFO>(
tL2CAP_CFG_INFO{.fcr_present = true, .fcr = kDefaultErtmOptions});
+ /* For hardware offload data path, host stack sets the initial credits to 0. The offload stack
+ * should send initial credits to peer device through L2CAP signaling command when the data path
+ * is switched successfully. */
+ if (sock->data_path == BTSOCK_DATA_PATH_HARDWARE_OFFLOAD) {
+ cfg->init_credit_present = true;
+ cfg->init_credit = 0;
+ }
std::unique_ptr<tL2CAP_ERTM_INFO> ertm_info;
if (!sock->is_le_coc) {
diff --git a/system/stack/gap/gap_conn.cc b/system/stack/gap/gap_conn.cc
index 127ded1cff..aad35dedfd 100644
--- a/system/stack/gap/gap_conn.cc
+++ b/system/stack/gap/gap_conn.cc
@@ -213,7 +213,8 @@ uint16_t GAP_ConnOpen(const char* /* p_serv_name */, uint8_t service_id, bool is
/* Configure L2CAP COC, if transport is LE */
if (transport == BT_TRANSPORT_LE) {
- p_ccb->local_coc_cfg.credits = L2CA_LeCreditDefault();
+ p_ccb->local_coc_cfg.credits =
+ (p_ccb->cfg.init_credit_present) ? p_ccb->cfg.init_credit : L2CA_LeCreditDefault();
p_ccb->local_coc_cfg.mtu = p_cfg->mtu;
uint16_t max_mps = bluetooth::shim::GetController()->GetLeBufferSize().le_data_packet_length_;
diff --git a/system/stack/include/l2cap_types.h b/system/stack/include/l2cap_types.h
index 311dab7528..d2dd74bad7 100644
--- a/system/stack/include/l2cap_types.h
+++ b/system/stack/include/l2cap_types.h
@@ -129,6 +129,8 @@ typedef struct {
uint8_t fcs; /* '0' if desire is to bypass FCS, otherwise '1' */
bool ext_flow_spec_present;
tHCI_EXT_FLOW_SPEC ext_flow_spec;
+ bool init_credit_present;
+ uint16_t init_credit;
uint16_t flags; /* bit 0: 0-no continuation, 1-continuation */
} tL2CAP_CFG_INFO;
diff --git a/system/stack/l2cap/l2c_ble.cc b/system/stack/l2cap/l2c_ble.cc
index 9d69e5ab36..e33a024386 100644
--- a/system/stack/l2cap/l2c_ble.cc
+++ b/system/stack/l2cap/l2c_ble.cc
@@ -780,8 +780,9 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
p_ccb->local_conn_cfg.mtu = L2CAP_SDU_LENGTH_LE_MAX;
p_ccb->local_conn_cfg.mps =
bluetooth::shim::GetController()->GetLeBufferSize().le_data_packet_length_;
- p_ccb->local_conn_cfg.credits = L2CA_LeCreditDefault();
- p_ccb->remote_credit_count = L2CA_LeCreditDefault();
+ p_ccb->local_conn_cfg.credits = p_rcb->coc_cfg.credits;
+
+ p_ccb->remote_credit_count = p_rcb->coc_cfg.credits;
p_ccb->peer_conn_cfg.mtu = mtu;
p_ccb->peer_conn_cfg.mps = mps;
diff --git a/system/stack/l2cap/l2c_utils.cc b/system/stack/l2cap/l2c_utils.cc
index c04379bf89..c18ba8c5a9 100644
--- a/system/stack/l2cap/l2c_utils.cc
+++ b/system/stack/l2cap/l2c_utils.cc
@@ -3331,6 +3331,9 @@ void l2cu_send_peer_ble_credit_based_conn_res(tL2C_CCB* p_ccb, tL2CAP_LE_RESULT_
p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
L2CAP_CMD_OVERHEAD;
+ log::verbose("local cid: {}, mtu: {}, mps: {}, initial credits: {}", p_ccb->local_cid,
+ p_ccb->local_conn_cfg.mtu, p_ccb->local_conn_cfg.mps, p_ccb->local_conn_cfg.credits);
+
UINT16_TO_STREAM(p, p_ccb->local_cid); /* Local CID */
UINT16_TO_STREAM(p, p_ccb->local_conn_cfg.mtu); /* MTU */
UINT16_TO_STREAM(p, p_ccb->local_conn_cfg.mps); /* MPS */