Loading system/stack/gap/gap_conn.cc +5 −1 Original line number Diff line number Diff line Loading @@ -210,7 +210,7 @@ uint16_t GAP_ConnOpen(const char* p_serv_name, uint8_t service_id, /* Configure L2CAP COC, if transport is LE */ if (transport == BT_TRANSPORT_LE) { p_ccb->local_coc_cfg.credits = L2CAP_LE_DEFAULT_CREDIT; p_ccb->local_coc_cfg.credits = L2CAP_LE_CREDIT_DEFAULT; p_ccb->local_coc_cfg.mtu = p_cfg->mtu; uint16_t max_mps = controller_get_interface()->get_acl_data_size_ble(); Loading @@ -219,6 +219,10 @@ uint16_t GAP_ConnOpen(const char* p_serv_name, uint8_t service_id, le_mps = max_mps; } p_ccb->local_coc_cfg.mps = le_mps; VLOG(2) << __func__ << ": credits=" << p_ccb->local_coc_cfg.credits << ", mps=" << p_ccb->local_coc_cfg.mps << ", mtu=" << p_ccb->local_coc_cfg.mtu; } p_ccb->p_callback = p_cb; Loading system/stack/l2cap/l2c_api.cc +8 −2 Original line number Diff line number Diff line Loading @@ -555,7 +555,10 @@ uint16_t L2CA_ConnectLECocReq(uint16_t psm, const RawAddress& p_bd_addr, p_ccb->p_rcb = p_rcb; /* Save the configuration */ if (p_cfg) memcpy(&p_ccb->local_conn_cfg, p_cfg, sizeof(tL2CAP_LE_CFG_INFO)); if (p_cfg) { memcpy(&p_ccb->local_conn_cfg, p_cfg, sizeof(tL2CAP_LE_CFG_INFO)); p_ccb->remote_credit_count = p_cfg->credits; } /* If link is up, start the L2CAP connection */ if (p_lcb->link_state == LST_CONNECTED) { Loading Loading @@ -625,7 +628,10 @@ bool L2CA_ConnectLECocRsp(const RawAddress& p_bd_addr, uint8_t id, return false; } if (p_cfg) memcpy(&p_ccb->local_conn_cfg, p_cfg, sizeof(tL2CAP_LE_CFG_INFO)); if (p_cfg) { memcpy(&p_ccb->local_conn_cfg, p_cfg, sizeof(tL2CAP_LE_CFG_INFO)); p_ccb->remote_credit_count = p_cfg->credits; } if (result == L2CAP_CONN_OK) l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONNECT_RSP, NULL); Loading system/stack/l2cap/l2c_csm.cc +1 −1 Original line number Diff line number Diff line Loading @@ -1105,7 +1105,7 @@ static void l2c_csm_open(tL2C_CCB* p_ccb, uint16_t event, void* p_data) { case L2CEVT_L2CAP_RECV_FLOW_CONTROL_CREDIT: credit = (uint16_t*)p_data; L2CAP_TRACE_DEBUG("%s Credits received %d", __func__, *credit); if ((p_ccb->peer_conn_cfg.credits + *credit) > L2CAP_LE_MAX_CREDIT) { if ((p_ccb->peer_conn_cfg.credits + *credit) > L2CAP_LE_CREDIT_MAX) { /* we have received credits more than max coc credits, * so disconnecting the Le Coc Channel */ Loading system/stack/l2cap/l2c_int.h +19 −6 Original line number Diff line number Diff line Loading @@ -37,12 +37,21 @@ #define L2CAP_MIN_MTU 48 /* Minimum acceptable MTU is 48 bytes */ /* LE credit based L2CAP connection parameters */ #define L2CAP_LE_MIN_MTU 23 #define L2CAP_LE_MIN_MPS 23 #define L2CAP_LE_MAX_MPS 65533 #define L2CAP_LE_MIN_CREDIT 0 #define L2CAP_LE_MAX_CREDIT 65535 #define L2CAP_LE_DEFAULT_CREDIT 1 constexpr uint16_t L2CAP_LE_MIN_MTU = 23; // Minimum SDU size constexpr uint16_t L2CAP_LE_MIN_MPS = 23; constexpr uint16_t L2CAP_LE_MAX_MPS = 65533; constexpr uint16_t L2CAP_LE_CREDIT_MAX = 65535; // This is initial amout of credits we send, and amount to which we increase // credits once they fall below threshold constexpr uint16_t L2CAP_LE_CREDIT_DEFAULT = 0xffff; // If credit count on remote fall below this value, we send back credits to // reach default value. constexpr uint16_t L2CAP_LE_CREDIT_THRESHOLD = 0x0040; static_assert(L2CAP_LE_CREDIT_THRESHOLD < L2CAP_LE_CREDIT_DEFAULT, "Threshold must be smaller then default credits"); /* * Timeout values (in milliseconds). Loading Loading @@ -327,6 +336,10 @@ typedef struct t_l2c_ccb { uint16_t fixed_chnl_idle_tout; /* Idle timeout to use for the fixed channel */ #endif uint16_t tx_data_len; /* Number of LE frames that the remote can send to us (credit count in * remote). Valid only for LE CoC */ uint16_t remote_credit_count; } tL2C_CCB; /*********************************************************************** Loading system/stack/l2cap/l2c_main.cc +12 −3 Original line number Diff line number Diff line Loading @@ -215,9 +215,18 @@ void l2c_rcv_acl_data(BT_HDR* p_msg) { if (p_lcb->transport == BT_TRANSPORT_LE) { l2c_lcc_proc_pdu(p_ccb, p_msg); // Got a pkt, valid send out credits to the peer device uint16_t credit = L2CAP_LE_DEFAULT_CREDIT; l2c_csm_execute(p_ccb, L2CEVT_L2CA_SEND_FLOW_CONTROL_CREDIT, &credit); /* The remote device has one less credit left */ --p_ccb->remote_credit_count; /* If the credits left on the remote device are getting low, send some */ if (p_ccb->remote_credit_count <= L2CAP_LE_CREDIT_THRESHOLD) { uint16_t credits = L2CAP_LE_CREDIT_DEFAULT - p_ccb->remote_credit_count; p_ccb->remote_credit_count = L2CAP_LE_CREDIT_DEFAULT; /* Return back credits */ l2c_csm_execute(p_ccb, L2CEVT_L2CA_SEND_FLOW_CONTROL_CREDIT, &credits); } } else { /* Basic mode packets go straight to the state machine */ if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE) Loading Loading
system/stack/gap/gap_conn.cc +5 −1 Original line number Diff line number Diff line Loading @@ -210,7 +210,7 @@ uint16_t GAP_ConnOpen(const char* p_serv_name, uint8_t service_id, /* Configure L2CAP COC, if transport is LE */ if (transport == BT_TRANSPORT_LE) { p_ccb->local_coc_cfg.credits = L2CAP_LE_DEFAULT_CREDIT; p_ccb->local_coc_cfg.credits = L2CAP_LE_CREDIT_DEFAULT; p_ccb->local_coc_cfg.mtu = p_cfg->mtu; uint16_t max_mps = controller_get_interface()->get_acl_data_size_ble(); Loading @@ -219,6 +219,10 @@ uint16_t GAP_ConnOpen(const char* p_serv_name, uint8_t service_id, le_mps = max_mps; } p_ccb->local_coc_cfg.mps = le_mps; VLOG(2) << __func__ << ": credits=" << p_ccb->local_coc_cfg.credits << ", mps=" << p_ccb->local_coc_cfg.mps << ", mtu=" << p_ccb->local_coc_cfg.mtu; } p_ccb->p_callback = p_cb; Loading
system/stack/l2cap/l2c_api.cc +8 −2 Original line number Diff line number Diff line Loading @@ -555,7 +555,10 @@ uint16_t L2CA_ConnectLECocReq(uint16_t psm, const RawAddress& p_bd_addr, p_ccb->p_rcb = p_rcb; /* Save the configuration */ if (p_cfg) memcpy(&p_ccb->local_conn_cfg, p_cfg, sizeof(tL2CAP_LE_CFG_INFO)); if (p_cfg) { memcpy(&p_ccb->local_conn_cfg, p_cfg, sizeof(tL2CAP_LE_CFG_INFO)); p_ccb->remote_credit_count = p_cfg->credits; } /* If link is up, start the L2CAP connection */ if (p_lcb->link_state == LST_CONNECTED) { Loading Loading @@ -625,7 +628,10 @@ bool L2CA_ConnectLECocRsp(const RawAddress& p_bd_addr, uint8_t id, return false; } if (p_cfg) memcpy(&p_ccb->local_conn_cfg, p_cfg, sizeof(tL2CAP_LE_CFG_INFO)); if (p_cfg) { memcpy(&p_ccb->local_conn_cfg, p_cfg, sizeof(tL2CAP_LE_CFG_INFO)); p_ccb->remote_credit_count = p_cfg->credits; } if (result == L2CAP_CONN_OK) l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONNECT_RSP, NULL); Loading
system/stack/l2cap/l2c_csm.cc +1 −1 Original line number Diff line number Diff line Loading @@ -1105,7 +1105,7 @@ static void l2c_csm_open(tL2C_CCB* p_ccb, uint16_t event, void* p_data) { case L2CEVT_L2CAP_RECV_FLOW_CONTROL_CREDIT: credit = (uint16_t*)p_data; L2CAP_TRACE_DEBUG("%s Credits received %d", __func__, *credit); if ((p_ccb->peer_conn_cfg.credits + *credit) > L2CAP_LE_MAX_CREDIT) { if ((p_ccb->peer_conn_cfg.credits + *credit) > L2CAP_LE_CREDIT_MAX) { /* we have received credits more than max coc credits, * so disconnecting the Le Coc Channel */ Loading
system/stack/l2cap/l2c_int.h +19 −6 Original line number Diff line number Diff line Loading @@ -37,12 +37,21 @@ #define L2CAP_MIN_MTU 48 /* Minimum acceptable MTU is 48 bytes */ /* LE credit based L2CAP connection parameters */ #define L2CAP_LE_MIN_MTU 23 #define L2CAP_LE_MIN_MPS 23 #define L2CAP_LE_MAX_MPS 65533 #define L2CAP_LE_MIN_CREDIT 0 #define L2CAP_LE_MAX_CREDIT 65535 #define L2CAP_LE_DEFAULT_CREDIT 1 constexpr uint16_t L2CAP_LE_MIN_MTU = 23; // Minimum SDU size constexpr uint16_t L2CAP_LE_MIN_MPS = 23; constexpr uint16_t L2CAP_LE_MAX_MPS = 65533; constexpr uint16_t L2CAP_LE_CREDIT_MAX = 65535; // This is initial amout of credits we send, and amount to which we increase // credits once they fall below threshold constexpr uint16_t L2CAP_LE_CREDIT_DEFAULT = 0xffff; // If credit count on remote fall below this value, we send back credits to // reach default value. constexpr uint16_t L2CAP_LE_CREDIT_THRESHOLD = 0x0040; static_assert(L2CAP_LE_CREDIT_THRESHOLD < L2CAP_LE_CREDIT_DEFAULT, "Threshold must be smaller then default credits"); /* * Timeout values (in milliseconds). Loading Loading @@ -327,6 +336,10 @@ typedef struct t_l2c_ccb { uint16_t fixed_chnl_idle_tout; /* Idle timeout to use for the fixed channel */ #endif uint16_t tx_data_len; /* Number of LE frames that the remote can send to us (credit count in * remote). Valid only for LE CoC */ uint16_t remote_credit_count; } tL2C_CCB; /*********************************************************************** Loading
system/stack/l2cap/l2c_main.cc +12 −3 Original line number Diff line number Diff line Loading @@ -215,9 +215,18 @@ void l2c_rcv_acl_data(BT_HDR* p_msg) { if (p_lcb->transport == BT_TRANSPORT_LE) { l2c_lcc_proc_pdu(p_ccb, p_msg); // Got a pkt, valid send out credits to the peer device uint16_t credit = L2CAP_LE_DEFAULT_CREDIT; l2c_csm_execute(p_ccb, L2CEVT_L2CA_SEND_FLOW_CONTROL_CREDIT, &credit); /* The remote device has one less credit left */ --p_ccb->remote_credit_count; /* If the credits left on the remote device are getting low, send some */ if (p_ccb->remote_credit_count <= L2CAP_LE_CREDIT_THRESHOLD) { uint16_t credits = L2CAP_LE_CREDIT_DEFAULT - p_ccb->remote_credit_count; p_ccb->remote_credit_count = L2CAP_LE_CREDIT_DEFAULT; /* Return back credits */ l2c_csm_execute(p_ccb, L2CEVT_L2CA_SEND_FLOW_CONTROL_CREDIT, &credits); } } else { /* Basic mode packets go straight to the state machine */ if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE) Loading