diff options
-rw-r--r-- | TEST_MAPPING | 3 | ||||
-rw-r--r-- | system/btif/Android.bp | 2 | ||||
-rw-r--r-- | system/stack/Android.bp | 70 | ||||
-rw-r--r-- | system/stack/avct/avct_api.cc | 10 | ||||
-rw-r--r-- | system/stack/test/stack_avctp_test.cc | 128 |
5 files changed, 210 insertions, 3 deletions
diff --git a/TEST_MAPPING b/TEST_MAPPING index 5f21a9b800..425f18826a 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -320,6 +320,9 @@ "name": "net_test_bta_jv" }, { + "name": "net_test_stack_avctp" + }, + { "name": "asrc_resampler_test" } ] diff --git a/system/btif/Android.bp b/system/btif/Android.bp index 9b22ee4784..2d3d40e3fd 100644 --- a/system/btif/Android.bp +++ b/system/btif/Android.bp @@ -597,8 +597,6 @@ cc_test { "libbt-platform-protos-lite", "libbt-sbc-decoder", "libbt-sbc-encoder", - "libbt-stack", - "libbt-stack-core", "libbtdevice", "libbtif", "libbtif-core", diff --git a/system/stack/Android.bp b/system/stack/Android.bp index 5fec9d2cee..b739ce2732 100644 --- a/system/stack/Android.bp +++ b/system/stack/Android.bp @@ -1180,6 +1180,76 @@ cc_test { } cc_test { + name: "net_test_stack_avctp", + defaults: [ + "fluoride_defaults", + "mts_defaults", + ], + test_suites: ["general-tests"], + host_supported: true, + test_options: { + unit_test: true, + }, + include_dirs: [ + "external/libldac/inc", + "packages/modules/Bluetooth/system", + "packages/modules/Bluetooth/system/gd", + "packages/modules/Bluetooth/system/stack/include", + ], + srcs: [ + ":TestCommonMockFunctions", + ":TestFakeOsi", + ":TestMockBta", + ":TestMockBtif", + ":TestMockDevice", + ":TestMockStackA2dp", + ":TestMockStackAcl", + ":TestMockStackL2cap", + "avct/avct_api.cc", + "avct/avct_bcb_act.cc", + "avct/avct_ccb.cc", + "avct/avct_l2c.cc", + "avct/avct_l2c_br.cc", + "avct/avct_lcb.cc", + "avct/avct_lcb_act.cc", + "test/stack_avctp_test.cc", + ], + shared_libs: [ + "libcrypto", + "libcutils", + "server_configurable_flags", + ], + static_libs: [ + "bluetooth_flags_c_lib_for_test", + "libaconfig_storage_read_api_cc", + "libbase", + "libbluetooth-types", + "libbluetooth_crypto_toolbox", + "libbluetooth_gd", + "libbluetooth_log", + "libbt-common", + "libchrome", + "libevent", + "libgmock", + "liblog", + "libosi", + "libprotobuf-cpp-lite", + "libstatslog_bt", + ], + target: { + android: { + shared_libs: ["libstatssocket"], + }, + }, + sanitize: { + address: true, + cfi: true, + misc_undefined: ["bounds"], + }, + header_libs: ["libbluetooth_headers"], +} + +cc_test { name: "net_test_stack_avdtp", defaults: [ "fluoride_defaults", diff --git a/system/stack/avct/avct_api.cc b/system/stack/avct/avct_api.cc index 70efdee0c2..d4a6aab45e 100644 --- a/system/stack/avct/avct_api.cc +++ b/system/stack/avct/avct_api.cc @@ -28,11 +28,12 @@ #include <com_android_bluetooth_flags.h> #include <string.h> -#include "avct_int.h" #include "bta/include/bta_sec_api.h" #include "internal_include/bt_target.h" #include "main/shim/dumpsys.h" #include "osi/include/allocator.h" +#include "stack/avct/avct_int.h" +#include "stack/include/avct_api.h" #include "stack/include/bt_hdr.h" #include "stack/include/bt_psm_types.h" #include "stack/include/l2cap_interface.h" @@ -109,6 +110,13 @@ void AVCT_Deregister(void) { /* deregister AVCT_BR_PSM with L2CAP */ stack::l2cap::get_interface().L2CA_Deregister(BT_PSM_AVCTP_BROWSE); + + // Clean up AVCTP data structures + for (int i = 0; i < AVCT_NUM_LINKS; i++) { + osi_free(avct_cb.lcb[i].p_rx_msg); + fixed_queue_free(avct_cb.lcb[i].tx_q, nullptr); + osi_free_and_reset((void**)&(avct_cb.bcb[i].p_tx_msg)); + } } /******************************************************************************* diff --git a/system/stack/test/stack_avctp_test.cc b/system/stack/test/stack_avctp_test.cc new file mode 100644 index 0000000000..17abac13c6 --- /dev/null +++ b/system/stack/test/stack_avctp_test.cc @@ -0,0 +1,128 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed 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 <bluetooth/log.h> +#include <gtest/gtest.h> +#include <unistd.h> + +#include "stack/include/avct_api.h" +#include "stack/include/bt_psm_types.h" +#include "test/fake/fake_osi.h" +#include "test/mock/mock_stack_l2cap_interface.h" + +using ::testing::_; +using ::testing::Args; +using ::testing::DoAll; +using ::testing::SaveArg; + +namespace { +constexpr uint16_t kRemoteCid = 0x0123; +const RawAddress kRawAddress = RawAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66}); +} // namespace + +class StackAvctpTest : public ::testing::Test { +protected: + void SetUp() override { + fake_osi_ = std::make_unique<::test::fake::FakeOsi>(); + bluetooth::testing::stack::l2cap::set_interface(&mock_stack_l2cap_interface_); + EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_RegisterWithSecurity(_, _, _, _, _, _, _)) + .WillRepeatedly([this](unsigned short psm, const tL2CAP_APPL_INFO& cb, bool /* c */, + tL2CAP_ERTM_INFO* /*d*/, unsigned short /* e */, + unsigned short /* f */, unsigned short /* g */) { + this->callback_map_.insert(std::make_tuple(psm, cb)); + return psm; + }); + EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_DisconnectReq(_)).WillRepeatedly([]() { + return true; + }); + AVCT_Register(); + // Make sure we have a callback for both PSMs + ASSERT_EQ(2U, callback_map_.size()); + } + + void TearDown() override { + EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_Deregister(BT_PSM_AVCTP)); + EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_Deregister(BT_PSM_AVCTP_BROWSE)); + AVCT_Deregister(); + } + + std::map<uint16_t, tL2CAP_APPL_INFO> callback_map_; + bluetooth::testing::stack::l2cap::Mock mock_stack_l2cap_interface_; + std::unique_ptr<test::fake::FakeOsi> fake_osi_; + int fd_{STDOUT_FILENO}; +}; + +TEST_F(StackAvctpTest, AVCT_Dumpsys) { AVCT_Dumpsys(fd_); } + +TEST_F(StackAvctpTest, AVCT_CreateConn) { + EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_ConnectReqWithSecurity(_, _, _)) + .WillRepeatedly([](unsigned short /* psm */, const RawAddress /* bd_addr */, + uint16_t /* sec_level */) { return 0x1234; }); + + uint8_t handle; + tAVCT_CC cc = { + .p_ctrl_cback = [](uint8_t /* handle */, uint8_t /* event */, uint16_t /* result */, + const RawAddress* /* peer_addr */) {}, + .p_msg_cback = [](uint8_t /* handle */, uint8_t /* label */, uint8_t /* cr */, + BT_HDR* /* p_pkt */) {}, + .pid = 0x1234, + .role = AVCT_ROLE_INITIATOR, + .control = 1, + }; + ASSERT_EQ(AVCT_SUCCESS, AVCT_CreateConn(&handle, &cc, kRawAddress)); + ASSERT_EQ(AVCT_SUCCESS, AVCT_RemoveConn(handle)); +} + +TEST_F(StackAvctpTest, AVCT_CreateBrowse) { + EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_ConnectReqWithSecurity(_, _, _)) + .WillRepeatedly([](unsigned short /* psm */, const RawAddress /* bd_addr */, + uint16_t /* sec_level */) { return 0x1234; }); + + uint8_t handle; + tAVCT_CC cc = { + .p_ctrl_cback = [](uint8_t /* handle */, uint8_t /* event */, uint16_t /* result */, + const RawAddress* /* peer_addr */) {}, + .p_msg_cback = [](uint8_t /* handle */, uint8_t /* label */, uint8_t /* cr */, + BT_HDR* /* p_pkt */) {}, + .pid = 0x1234, + .role = AVCT_ROLE_INITIATOR, + .control = 1, + }; + ASSERT_EQ(AVCT_SUCCESS, AVCT_CreateConn(&handle, &cc, kRawAddress)); + ASSERT_EQ(AVCT_SUCCESS, AVCT_CreateBrowse(handle, AVCT_ROLE_INITIATOR)); + + ASSERT_EQ(AVCT_SUCCESS, AVCT_RemoveBrowse(handle)); + ASSERT_EQ(AVCT_SUCCESS, AVCT_RemoveConn(handle)); +} + +TEST_F(StackAvctpTest, AVCT_RemoteInitiatesControl) { + // AVCT Control + callback_map_[BT_PSM_AVCTP].pL2CA_ConnectInd_Cb(kRawAddress, kRemoteCid, BT_PSM_AVCTP, 0); + callback_map_[BT_PSM_AVCTP].pL2CA_ConnectCfm_Cb(kRemoteCid, tL2CAP_CONN::L2CAP_CONN_OK); +} + +TEST_F(StackAvctpTest, AVCT_RemoteInitiatesBrowse) { + // AVCT Control + callback_map_[BT_PSM_AVCTP].pL2CA_ConnectInd_Cb(kRawAddress, kRemoteCid, BT_PSM_AVCTP, 0); + callback_map_[BT_PSM_AVCTP].pL2CA_ConnectCfm_Cb(kRemoteCid, tL2CAP_CONN::L2CAP_CONN_OK); + + // AVCT Browse + callback_map_[BT_PSM_AVCTP_BROWSE].pL2CA_ConnectInd_Cb(kRawAddress, kRemoteCid, + BT_PSM_AVCTP_BROWSE, 0); + callback_map_[BT_PSM_AVCTP_BROWSE].pL2CA_ConnectCfm_Cb(kRemoteCid, tL2CAP_CONN::L2CAP_CONN_OK); + + AVCT_Dumpsys(fd_); +} |