diff options
author | 2024-12-09 01:11:34 -0800 | |
---|---|---|
committer | 2024-12-12 19:12:32 -0800 | |
commit | c9f93cdf363fa32d0536b0119d60525211314444 (patch) | |
tree | 9cf1eb57565cb0ecf4d3127094a782a0120f3877 | |
parent | cfae36f86663b10eca17b72deb7896cf860656ee (diff) |
Add helper functions to get RFCOMM channel and L2CAP local mtu information
Flag: com.android.bluetooth.flags.socket_settings_api
Bug: 342012881
Bug: 374358112
Test: m -j
Change-Id: Id94712de7fb1ebdd88dd850db16e176092c10185
-rw-r--r-- | system/stack/include/l2cap_interface.h | 17 | ||||
-rw-r--r-- | system/stack/include/port_api.h | 26 | ||||
-rw-r--r-- | system/stack/l2cap/internal/l2c_api.h | 17 | ||||
-rw-r--r-- | system/stack/l2cap/l2c_api.cc | 27 | ||||
-rw-r--r-- | system/stack/l2cap/l2c_api.h | 2 | ||||
-rw-r--r-- | system/stack/l2cap/l2cap_api.cc | 5 | ||||
-rw-r--r-- | system/stack/rfcomm/port_api.cc | 48 | ||||
-rw-r--r-- | system/test/mock/mock_stack_l2cap_api.cc | 5 | ||||
-rw-r--r-- | system/test/mock/mock_stack_l2cap_api.h | 10 | ||||
-rw-r--r-- | system/test/mock/mock_stack_l2cap_interface.h | 1 | ||||
-rw-r--r-- | system/test/mock/mock_stack_rfcomm_port_api.cc | 9 |
11 files changed, 167 insertions, 0 deletions
diff --git a/system/stack/include/l2cap_interface.h b/system/stack/include/l2cap_interface.h index c3e32dcf36..af8d08d7d5 100644 --- a/system/stack/include/l2cap_interface.h +++ b/system/stack/include/l2cap_interface.h @@ -933,6 +933,23 @@ public: ** ******************************************************************************/ virtual bool L2CA_GetAclHandle(uint16_t lcid, uint16_t* acl_handle) = 0; + + /******************************************************************************* + ** + ** Function L2CA_GetLocalMtu + ** + ** Description Given a local channel identifier, |lcid|, this function + ** returns the L2CAP local mtu, |local_mtu|. If + ** |lcid| is not known or is invalid, this function returns false and does not + ** modify the value pointed at by |local_mtu|. + ** + ** Parameters: lcid: Local CID + ** local_mtu: Pointer to L2CAP local mtu must NOT be nullptr + ** + ** Returns true if local_mtu lookup was successful + ** + ******************************************************************************/ + virtual bool L2CA_GetLocalMtu(uint16_t lcid, uint16_t* local_mtu) = 0; }; Interface& get_interface(); diff --git a/system/stack/include/port_api.h b/system/stack/include/port_api.h index e2986740f1..260a30e1b0 100644 --- a/system/stack/include/port_api.h +++ b/system/stack/include/port_api.h @@ -483,4 +483,30 @@ void RFCOMM_Init(void); ******************************************************************************/ [[nodiscard]] int PORT_GetSecurityMask(uint16_t handle, uint16_t* sec_mask); +/******************************************************************************* + * + * Function PORT_GetChannelInfo + * + * Description This function is called to get RFCOMM channel information + * by the handle of the port. All OUT parameters must NOT be nullptr. + * + * Parameters: handle - Handle of the port returned in the Open + * local_mtu - OUT local L2CAP MTU + * remote_mtu - OUT remote L2CAP MTU + * local_credit - OUT local RFCOMM credit + * remote_credit - OUT remote RFCOMM credit + * local_cid - OUT local L2CAP CID + * remote_cid - OUT remote L2CAP CID + * dlci - OUT dlci + * max_frame_size- OUT max frame size for RFCOMM + * acl_handle - OUT ACL handle + * mux_initiator - OUT is initiator of the RFCOMM multiplexer control channel + * + ******************************************************************************/ +[[nodiscard]] int PORT_GetChannelInfo(uint16_t handle, uint16_t* local_mtu, uint16_t* remote_mtu, + uint16_t* local_credit, uint16_t* remote_credit, + uint16_t* local_cid, uint16_t* remote_cid, uint16_t* dlci, + uint16_t* max_frame_size, uint16_t* acl_handle, + bool* mux_initiator); + #endif /* PORT_API_H */ diff --git a/system/stack/l2cap/internal/l2c_api.h b/system/stack/l2cap/internal/l2c_api.h index 99c1f57781..e6a949a888 100644 --- a/system/stack/l2cap/internal/l2c_api.h +++ b/system/stack/l2cap/internal/l2c_api.h @@ -794,3 +794,20 @@ void L2CA_SetMediaStreamChannel(uint16_t local_media_cid, bool status); ** ******************************************************************************/ [[nodiscard]] bool L2CA_GetAclHandle(uint16_t lcid, uint16_t* acl_handle); + +/******************************************************************************* + ** + ** Function L2CA_GetLocalMtu + ** + ** Description Given a local channel identifier, |lcid|, this function + ** returns the L2CAP local mtu, |local_mtu|. If + ** |lcid| is not known or is invalid, this function returns false and does not + ** modify the value pointed at by |local_mtu|. + ** + ** Parameters: lcid: Local CID + ** local_mtu: Pointer to L2CAP local mtu must NOT be nullptr + ** + ** Returns true if local_mtu lookup was successful + ** + ******************************************************************************/ +[[nodiscard]] bool L2CA_GetLocalMtu(uint16_t lcid, uint16_t* local_mtu); diff --git a/system/stack/l2cap/l2c_api.cc b/system/stack/l2cap/l2c_api.cc index 68aacece21..7ae58fe77f 100644 --- a/system/stack/l2cap/l2c_api.cc +++ b/system/stack/l2cap/l2c_api.cc @@ -1763,6 +1763,33 @@ bool L2CA_GetAclHandle(uint16_t lcid, uint16_t* acl_handle) { return true; } +/******************************************************************************* + ** + ** Function L2CA_GetLocalMtu + ** + ** Description Given a local channel identifier, |lcid|, this function + ** returns the L2CAP local mtu, |local_mtu|. If + ** |lcid| is not known or is invalid, this function returns false and does not + ** modify the value pointed at by |local_mtu|. + ** + ** Parameters: lcid: Local CID + ** local_mtu: Pointer to L2CAP local mtu must NOT be nullptr + ** + ** Returns true if local_mtu lookup was successful + ** + ******************************************************************************/ +bool L2CA_GetLocalMtu(uint16_t lcid, uint16_t* local_mtu) { + log::assert_that(local_mtu != nullptr, "assert failed: local_mtu != nullptr"); + + tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(nullptr, lcid); + if (p_ccb == nullptr) { + log::error("No CCB for CID:0x{:04x}", lcid); + return false; + } + *local_mtu = p_ccb->p_rcb->my_mtu; + return true; +} + using namespace bluetooth; #define DUMPSYS_TAG "shim::legacy::l2cap" diff --git a/system/stack/l2cap/l2c_api.h b/system/stack/l2cap/l2c_api.h index f89a5cc6ca..fc7faccc18 100644 --- a/system/stack/l2cap/l2c_api.h +++ b/system/stack/l2cap/l2c_api.h @@ -135,6 +135,8 @@ public: bool is_local_cid) override; [[nodiscard]] bool L2CA_GetAclHandle(uint16_t lcid, uint16_t* acl_handle) override; + + [[nodiscard]] bool L2CA_GetLocalMtu(uint16_t lcid, uint16_t* local_mtu) override; }; } // namespace l2cap diff --git a/system/stack/l2cap/l2cap_api.cc b/system/stack/l2cap/l2cap_api.cc index 2e1b12c7de..37caa2bc2a 100644 --- a/system/stack/l2cap/l2cap_api.cc +++ b/system/stack/l2cap/l2cap_api.cc @@ -262,3 +262,8 @@ void bluetooth::stack::l2cap::Impl::L2CA_SetMediaStreamChannel(uint16_t local_me uint16_t* acl_handle) { return ::L2CA_GetAclHandle(lcid, acl_handle); } + +[[nodiscard]] bool bluetooth::stack::l2cap::Impl::L2CA_GetLocalMtu(uint16_t lcid, + uint16_t* local_mtu) { + return ::L2CA_GetLocalMtu(lcid, local_mtu); +} diff --git a/system/stack/rfcomm/port_api.cc b/system/stack/rfcomm/port_api.cc index 6786e88d02..0495026945 100644 --- a/system/stack/rfcomm/port_api.cc +++ b/system/stack/rfcomm/port_api.cc @@ -1194,3 +1194,51 @@ int PORT_GetSecurityMask(uint16_t handle, uint16_t* sec_mask) { *sec_mask = p_port->sec_mask; return PORT_SUCCESS; } + +int PORT_GetChannelInfo(uint16_t handle, uint16_t* local_mtu, uint16_t* remote_mtu, + uint16_t* local_credit, uint16_t* remote_credit, uint16_t* local_cid, + uint16_t* remote_cid, uint16_t* dlci, uint16_t* max_frame_size, + uint16_t* acl_handle, bool* mux_initiator) { + log::verbose("PORT_GetChannelInfo() handle:{}", handle); + + tPORT* p_port = get_port_from_handle(handle); + if (p_port == nullptr) { + log::error("Unable to get RFCOMM port control block bad handle:{}", handle); + return PORT_BAD_HANDLE; + } + + if (!p_port->in_use || (p_port->state == PORT_CONNECTION_STATE_CLOSED)) { + return PORT_NOT_OPENED; + } + + if (p_port->line_status) { + return PORT_LINE_ERR; + } + + uint16_t rcid, ahandle, lmtu; + if (!stack::l2cap::get_interface().L2CA_GetRemoteChannelId(p_port->rfc.p_mcb->lcid, &rcid)) { + log::error("L2CA_GetRemoteChannelId failed, local cid: {}", p_port->rfc.p_mcb->lcid); + return PORT_PEER_FAILED; + } + + if (!stack::l2cap::get_interface().L2CA_GetAclHandle(p_port->rfc.p_mcb->lcid, &ahandle)) { + log::error("L2CA_GetAclHandle failed, local cid: {}", p_port->rfc.p_mcb->lcid); + return PORT_PEER_FAILED; + } + + if (!stack::l2cap::get_interface().L2CA_GetLocalMtu(p_port->rfc.p_mcb->lcid, &lmtu)) { + log::error("L2CA_GetLocalMtu failed, local cid: {}", p_port->rfc.p_mcb->lcid); + return PORT_PEER_FAILED; + } + *local_mtu = lmtu; + *remote_mtu = p_port->rfc.p_mcb->peer_l2cap_mtu + RFCOMM_MIN_OFFSET + 1; + *local_credit = p_port->credit_rx; + *remote_credit = p_port->credit_tx; + *local_cid = p_port->rfc.p_mcb->lcid; + *remote_cid = rcid; + *dlci = p_port->dlci; + *max_frame_size = p_port->mtu; + *acl_handle = ahandle; + *mux_initiator = p_port->rfc.p_mcb->is_initiator; + return PORT_SUCCESS; +} diff --git a/system/test/mock/mock_stack_l2cap_api.cc b/system/test/mock/mock_stack_l2cap_api.cc index 3dd0ef991c..de117f06a9 100644 --- a/system/test/mock/mock_stack_l2cap_api.cc +++ b/system/test/mock/mock_stack_l2cap_api.cc @@ -76,6 +76,7 @@ struct L2CA_isMediaChannel L2CA_isMediaChannel; struct L2CA_LeCreditDefault L2CA_LeCreditDefault; struct L2CA_LeCreditThreshold L2CA_LeCreditThreshold; struct L2CA_GetAclHandle L2CA_GetAclHandle; +struct L2CA_GetLocalMtu L2CA_GetLocalMtu; } // namespace stack_l2cap_api } // namespace mock @@ -255,6 +256,10 @@ bool L2CA_GetAclHandle(uint16_t lcid, uint16_t* acl_handle) { inc_func_call_count(__func__); return test::mock::stack_l2cap_api::L2CA_GetAclHandle(lcid, acl_handle); } +bool L2CA_GetLocalMtu(uint16_t lcid, uint16_t* local_mtu) { + inc_func_call_count(__func__); + return test::mock::stack_l2cap_api::L2CA_GetLocalMtu(lcid, local_mtu); +} // END mockcify generation diff --git a/system/test/mock/mock_stack_l2cap_api.h b/system/test/mock/mock_stack_l2cap_api.h index ed20c3438d..3f2e6dc72f 100644 --- a/system/test/mock/mock_stack_l2cap_api.h +++ b/system/test/mock/mock_stack_l2cap_api.h @@ -467,6 +467,16 @@ struct L2CA_GetAclHandle { }; extern struct L2CA_GetAclHandle L2CA_GetAclHandle; +// Name: L2CA_GetLocalMtu +// Params: uint16_t lcid, uint16_t* local_mtu +// Returns: bool +struct L2CA_GetLocalMtu { + std::function<bool(uint16_t lcid, uint16_t* local_mtu)> body{ + [](uint16_t /* lcid */, uint16_t* /* local_mtu */) { return false; }}; + bool operator()(uint16_t lcid, uint16_t* local_mtu) { return body(lcid, local_mtu); } +}; +extern struct L2CA_GetLocalMtu L2CA_GetLocalMtu; + } // namespace stack_l2cap_api } // namespace mock } // namespace test diff --git a/system/test/mock/mock_stack_l2cap_interface.h b/system/test/mock/mock_stack_l2cap_interface.h index 7756f4a4ed..f274f18643 100644 --- a/system/test/mock/mock_stack_l2cap_interface.h +++ b/system/test/mock/mock_stack_l2cap_interface.h @@ -107,6 +107,7 @@ public: MOCK_METHOD(void, L2CA_Consolidate, (const RawAddress& identity_addr, const RawAddress& rpa)); MOCK_METHOD(bool, L2CA_GetAclHandle, (uint16_t lcid, uint16_t* acl_handle)); + MOCK_METHOD(bool, L2CA_GetLocalMtu, (uint16_t lcid, uint16_t* local_mtu)); // Disconnect methods an active connection for both BR/EDR and BLE MOCK_METHOD(bool, L2CA_DisconnectReq, (uint16_t cid)); diff --git a/system/test/mock/mock_stack_rfcomm_port_api.cc b/system/test/mock/mock_stack_rfcomm_port_api.cc index e3dffbbf48..da6eefd3b9 100644 --- a/system/test/mock/mock_stack_rfcomm_port_api.cc +++ b/system/test/mock/mock_stack_rfcomm_port_api.cc @@ -101,6 +101,15 @@ int PORT_GetSecurityMask(uint16_t /* handle */, uint16_t* /* sec_mask */) { inc_func_call_count(__func__); return 0; } +int PORT_GetChannelInfo(uint16_t /* handle */, uint16_t* /* local_mtu */, + uint16_t* /* remote_mtu */, uint16_t* /* local_credit */, + uint16_t* /* remote_credit */, uint16_t* /* local_cid */, + uint16_t* /* remote_cid */, uint16_t* /* dlci */, + uint16_t* /* max_frame_size */, uint16_t* /* acl_handle */, + bool* /* mux_initiator */) { + inc_func_call_count(__func__); + return 0; +} void RFCOMM_Init(void) { inc_func_call_count(__func__); } bool PORT_IsCollisionDetected(RawAddress /* bd_addr */) { inc_func_call_count(__func__); |