summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TEST_MAPPING3
-rw-r--r--system/btif/Android.bp2
-rw-r--r--system/stack/Android.bp70
-rw-r--r--system/stack/avct/avct_api.cc10
-rw-r--r--system/stack/test/stack_avctp_test.cc128
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_);
+}