Loading flags/gap.aconfig +0 −10 Original line number Diff line number Diff line Loading @@ -123,16 +123,6 @@ flag { } } flag { name: "update_inquiry_result_on_flag_change" namespace: "bluetooth" description: "Update ADV flag in inquiry result as soon as updated flag received" bug: "329872838" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "ble_gatt_server_use_address_type_in_connection" namespace: "bluetooth" Loading system/stack/BUILD.gn +43 −0 Original line number Diff line number Diff line Loading @@ -229,6 +229,11 @@ source_set("stack") { "//bt/system/stack/mmc", "//bt/system/types", ] if (use.test) { deps += [ ":sco_hci_linux_test", ] } configs += [ "//bt/system:target_defaults", Loading @@ -237,6 +242,44 @@ source_set("stack") { } if (use.test) { executable("sco_hci_linux_test") { sources = [ "btm/btm_sco_hci.cc", "test/btm/sco_hci_linux_test.cc", "//bt/system/test/common/core_interface.cc", "//bt/system/test/common/mock_functions.cc", "//bt/system/test/fake/fake_osi.cc", "//bt/system/test/mock/mock_bluetooth_interface.cc", "//bt/system/test/mock/mock_btif_stack_manager.cc", "//bt/system/test/mock/mock_osi_alarm.cc", "//bt/system/test/mock/mock_osi_allocator.cc", "//bt/system/test/mock/mock_osi_fixed_queue.cc", "//bt/system/test/mock/mock_osi_list.cc", "//bt/system/test/mock/mock_stack_rnr_interface.cc", "//bt/system/test/mock/mock_udrv_ulinux_uipc.cc", ] include_dirs = [ "btm", "include", "test/common", ] libs = [ "fmt", ] deps = [ "//bt/system/log:libbluetooth_log", "//bt/system/common", "//bt/system/osi", "//bt/system/types", ] configs += [ "//bt/system:external_gmock_main", "//bt/system:target_defaults", "//bt/system/log:log_defaults", ] } executable("net_test_btm_iso") { sources = [ "btm/btm_iso.cc", Loading system/stack/btm/btm_ble_gap.cc +1 −2 Original line number Diff line number Diff line Loading @@ -2312,8 +2312,7 @@ void btm_ble_process_adv_pkt_cont_for_inquiry(uint16_t evt_type, tBLE_ADDR_TYPE if (p_i && (!(p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BLE) || /* scan response to be updated */ (!p_i->scan_rsp) || (!p_i->inq_info.results.include_rsi && include_rsi) || (com::android::bluetooth::flags::update_inquiry_result_on_flag_change() && !p_i->inq_info.results.flag && p_flag && *p_flag))) { (!p_i->inq_info.results.flag && p_flag && *p_flag))) { update = true; } else if (btm_cb.ble_ctr_cb.is_ble_observe_active()) { btm_cb.neighbor.le_observe.results++; Loading system/stack/btm/btm_sco_hci.cc +25 −5 Original line number Diff line number Diff line Loading @@ -32,11 +32,6 @@ #include "stack/btm/btm_sco.h" #include "udrv/include/uipc.h" #define SCO_DATA_READ_POLL_MS 10 #define SCO_HOST_DATA_PATH "/var/run/bluetooth/audio/.sco_data" // TODO(b/198260375): Make SCO data owner group configurable. #define SCO_HOST_DATA_GROUP "bluetooth-audio" /* Per Bluetooth Core v5.0 and HFP 1.9 specification. */ #define BTM_MSBC_H2_HEADER_0 0x01 #define BTM_MSBC_H2_HEADER_LEN 2 Loading Loading @@ -65,6 +60,13 @@ #define BTM_LC3_PKT_LEN 60 #define BTM_LC3_FS 240 /* Frame Size */ #if TARGET_FLOSS #define SCO_DATA_READ_POLL_MS 10 #define SCO_HOST_DATA_PATH "/var/run/bluetooth/audio/.sco_data" // TODO(b/198260375): Make SCO data owner group configurable. #define SCO_HOST_DATA_GROUP "bluetooth-audio" namespace { std::unique_ptr<tUIPC_STATE> sco_uipc = nullptr; Loading @@ -86,11 +88,13 @@ void sco_data_cb(tUIPC_CH_ID, tUIPC_EVENT event) { } } // namespace #endif namespace bluetooth { namespace audio { namespace sco { #if TARGET_FLOSS void open() { if (sco_uipc != nullptr) { log::warn("Re-opening UIPC that is already running"); Loading Loading @@ -136,6 +140,22 @@ size_t write(const uint8_t* p_buf, uint32_t len) { } return UIPC_Send(*sco_uipc, UIPC_CH_ID_AV_AUDIO, 0, p_buf, len) ? len : 0; } #else void open() {} void cleanup() {} size_t read(uint8_t* p_buf, uint32_t len) { (void)p_buf; (void)len; return 0; } size_t write(const uint8_t* p_buf, uint32_t len) { (void)p_buf; (void)len; return 0; } #endif enum decode_buf_state { DECODE_BUF_EMPTY, Loading system/stack/test/btm/sco_hci_linux_test.cc 0 → 100644 +125 −0 Original line number Diff line number Diff line /* * * 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 <gmock/gmock.h> #include <gtest/gtest.h> #include "stack/btm/btm_sco.h" #include "stack/test/btm/btm_test_fixtures.h" #include "test/common/mock_functions.h" #include "udrv/include/uipc.h" extern std::unique_ptr<tUIPC_STATE> mock_uipc_init_ret; extern uint32_t mock_uipc_read_ret; extern bool mock_uipc_send_ret; namespace { class ScoHciTest : public BtmWithMocksTest { public: protected: void SetUp() override { BtmWithMocksTest::SetUp(); mock_uipc_init_ret = nullptr; mock_uipc_read_ret = 0; mock_uipc_send_ret = true; } void TearDown() override { BtmWithMocksTest::TearDown(); } }; class ScoHciWithOpenCleanTest : public ScoHciTest { public: protected: void SetUp() override { ScoHciTest::SetUp(); mock_uipc_init_ret = std::make_unique<tUIPC_STATE>(); bluetooth::audio::sco::open(); } void TearDown() override { bluetooth::audio::sco::cleanup(); } }; TEST_F(ScoHciTest, ScoOverHciOpenFail) { bluetooth::audio::sco::open(); ASSERT_EQ(get_func_call_count("UIPC_Init"), 1); ASSERT_EQ(get_func_call_count("UIPC_Open"), 0); bluetooth::audio::sco::cleanup(); // UIPC is nullptr and shouldn't require an actual call of UIPC_Close; ASSERT_EQ(get_func_call_count("UIPC_Close"), 0); } TEST_F(ScoHciWithOpenCleanTest, ScoOverHciOpenClean) { ASSERT_EQ(get_func_call_count("UIPC_Init"), 1); ASSERT_EQ(get_func_call_count("UIPC_Open"), 1); ASSERT_EQ(mock_uipc_init_ret, nullptr); mock_uipc_init_ret = std::make_unique<tUIPC_STATE>(); // Double open will override uipc bluetooth::audio::sco::open(); ASSERT_EQ(get_func_call_count("UIPC_Init"), 2); ASSERT_EQ(get_func_call_count("UIPC_Open"), 2); ASSERT_EQ(mock_uipc_init_ret, nullptr); bluetooth::audio::sco::cleanup(); ASSERT_EQ(get_func_call_count("UIPC_Close"), 1); // Double clean shouldn't fail bluetooth::audio::sco::cleanup(); ASSERT_EQ(get_func_call_count("UIPC_Close"), 1); } TEST_F(ScoHciTest, ScoOverHciReadNoOpen) { uint8_t buf[100]; ASSERT_EQ(bluetooth::audio::sco::read(buf, sizeof(buf)), size_t(0)); ASSERT_EQ(get_func_call_count("UIPC_Read"), 0); } TEST_F(ScoHciWithOpenCleanTest, ScoOverHciRead) { uint8_t buf[100]; // The UPIC should be ready ASSERT_EQ(get_func_call_count("UIPC_Init"), 1); ASSERT_EQ(get_func_call_count("UIPC_Open"), 1); ASSERT_EQ(mock_uipc_init_ret, nullptr); mock_uipc_read_ret = sizeof(buf); ASSERT_EQ(bluetooth::audio::sco::read(buf, sizeof(buf)), mock_uipc_read_ret); ASSERT_EQ(get_func_call_count("UIPC_Read"), 1); } TEST_F(ScoHciTest, ScoOverHciWriteNoOpen) { uint8_t buf[100]; bluetooth::audio::sco::write(buf, sizeof(buf)); ASSERT_EQ(get_func_call_count("UIPC_Send"), 0); } TEST_F(ScoHciWithOpenCleanTest, ScoOverHciWrite) { uint8_t buf[100]; // The UPIC should be ready ASSERT_EQ(get_func_call_count("UIPC_Init"), 1); ASSERT_EQ(get_func_call_count("UIPC_Open"), 1); ASSERT_EQ(mock_uipc_init_ret, nullptr); ASSERT_EQ(bluetooth::audio::sco::write(buf, sizeof(buf)), sizeof(buf)); ASSERT_EQ(get_func_call_count("UIPC_Send"), 1); // Send fails mock_uipc_send_ret = false; ASSERT_EQ(bluetooth::audio::sco::write(buf, sizeof(buf)), size_t(0)); ASSERT_EQ(get_func_call_count("UIPC_Send"), 2); } } // namespace Loading
flags/gap.aconfig +0 −10 Original line number Diff line number Diff line Loading @@ -123,16 +123,6 @@ flag { } } flag { name: "update_inquiry_result_on_flag_change" namespace: "bluetooth" description: "Update ADV flag in inquiry result as soon as updated flag received" bug: "329872838" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "ble_gatt_server_use_address_type_in_connection" namespace: "bluetooth" Loading
system/stack/BUILD.gn +43 −0 Original line number Diff line number Diff line Loading @@ -229,6 +229,11 @@ source_set("stack") { "//bt/system/stack/mmc", "//bt/system/types", ] if (use.test) { deps += [ ":sco_hci_linux_test", ] } configs += [ "//bt/system:target_defaults", Loading @@ -237,6 +242,44 @@ source_set("stack") { } if (use.test) { executable("sco_hci_linux_test") { sources = [ "btm/btm_sco_hci.cc", "test/btm/sco_hci_linux_test.cc", "//bt/system/test/common/core_interface.cc", "//bt/system/test/common/mock_functions.cc", "//bt/system/test/fake/fake_osi.cc", "//bt/system/test/mock/mock_bluetooth_interface.cc", "//bt/system/test/mock/mock_btif_stack_manager.cc", "//bt/system/test/mock/mock_osi_alarm.cc", "//bt/system/test/mock/mock_osi_allocator.cc", "//bt/system/test/mock/mock_osi_fixed_queue.cc", "//bt/system/test/mock/mock_osi_list.cc", "//bt/system/test/mock/mock_stack_rnr_interface.cc", "//bt/system/test/mock/mock_udrv_ulinux_uipc.cc", ] include_dirs = [ "btm", "include", "test/common", ] libs = [ "fmt", ] deps = [ "//bt/system/log:libbluetooth_log", "//bt/system/common", "//bt/system/osi", "//bt/system/types", ] configs += [ "//bt/system:external_gmock_main", "//bt/system:target_defaults", "//bt/system/log:log_defaults", ] } executable("net_test_btm_iso") { sources = [ "btm/btm_iso.cc", Loading
system/stack/btm/btm_ble_gap.cc +1 −2 Original line number Diff line number Diff line Loading @@ -2312,8 +2312,7 @@ void btm_ble_process_adv_pkt_cont_for_inquiry(uint16_t evt_type, tBLE_ADDR_TYPE if (p_i && (!(p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BLE) || /* scan response to be updated */ (!p_i->scan_rsp) || (!p_i->inq_info.results.include_rsi && include_rsi) || (com::android::bluetooth::flags::update_inquiry_result_on_flag_change() && !p_i->inq_info.results.flag && p_flag && *p_flag))) { (!p_i->inq_info.results.flag && p_flag && *p_flag))) { update = true; } else if (btm_cb.ble_ctr_cb.is_ble_observe_active()) { btm_cb.neighbor.le_observe.results++; Loading
system/stack/btm/btm_sco_hci.cc +25 −5 Original line number Diff line number Diff line Loading @@ -32,11 +32,6 @@ #include "stack/btm/btm_sco.h" #include "udrv/include/uipc.h" #define SCO_DATA_READ_POLL_MS 10 #define SCO_HOST_DATA_PATH "/var/run/bluetooth/audio/.sco_data" // TODO(b/198260375): Make SCO data owner group configurable. #define SCO_HOST_DATA_GROUP "bluetooth-audio" /* Per Bluetooth Core v5.0 and HFP 1.9 specification. */ #define BTM_MSBC_H2_HEADER_0 0x01 #define BTM_MSBC_H2_HEADER_LEN 2 Loading Loading @@ -65,6 +60,13 @@ #define BTM_LC3_PKT_LEN 60 #define BTM_LC3_FS 240 /* Frame Size */ #if TARGET_FLOSS #define SCO_DATA_READ_POLL_MS 10 #define SCO_HOST_DATA_PATH "/var/run/bluetooth/audio/.sco_data" // TODO(b/198260375): Make SCO data owner group configurable. #define SCO_HOST_DATA_GROUP "bluetooth-audio" namespace { std::unique_ptr<tUIPC_STATE> sco_uipc = nullptr; Loading @@ -86,11 +88,13 @@ void sco_data_cb(tUIPC_CH_ID, tUIPC_EVENT event) { } } // namespace #endif namespace bluetooth { namespace audio { namespace sco { #if TARGET_FLOSS void open() { if (sco_uipc != nullptr) { log::warn("Re-opening UIPC that is already running"); Loading Loading @@ -136,6 +140,22 @@ size_t write(const uint8_t* p_buf, uint32_t len) { } return UIPC_Send(*sco_uipc, UIPC_CH_ID_AV_AUDIO, 0, p_buf, len) ? len : 0; } #else void open() {} void cleanup() {} size_t read(uint8_t* p_buf, uint32_t len) { (void)p_buf; (void)len; return 0; } size_t write(const uint8_t* p_buf, uint32_t len) { (void)p_buf; (void)len; return 0; } #endif enum decode_buf_state { DECODE_BUF_EMPTY, Loading
system/stack/test/btm/sco_hci_linux_test.cc 0 → 100644 +125 −0 Original line number Diff line number Diff line /* * * 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 <gmock/gmock.h> #include <gtest/gtest.h> #include "stack/btm/btm_sco.h" #include "stack/test/btm/btm_test_fixtures.h" #include "test/common/mock_functions.h" #include "udrv/include/uipc.h" extern std::unique_ptr<tUIPC_STATE> mock_uipc_init_ret; extern uint32_t mock_uipc_read_ret; extern bool mock_uipc_send_ret; namespace { class ScoHciTest : public BtmWithMocksTest { public: protected: void SetUp() override { BtmWithMocksTest::SetUp(); mock_uipc_init_ret = nullptr; mock_uipc_read_ret = 0; mock_uipc_send_ret = true; } void TearDown() override { BtmWithMocksTest::TearDown(); } }; class ScoHciWithOpenCleanTest : public ScoHciTest { public: protected: void SetUp() override { ScoHciTest::SetUp(); mock_uipc_init_ret = std::make_unique<tUIPC_STATE>(); bluetooth::audio::sco::open(); } void TearDown() override { bluetooth::audio::sco::cleanup(); } }; TEST_F(ScoHciTest, ScoOverHciOpenFail) { bluetooth::audio::sco::open(); ASSERT_EQ(get_func_call_count("UIPC_Init"), 1); ASSERT_EQ(get_func_call_count("UIPC_Open"), 0); bluetooth::audio::sco::cleanup(); // UIPC is nullptr and shouldn't require an actual call of UIPC_Close; ASSERT_EQ(get_func_call_count("UIPC_Close"), 0); } TEST_F(ScoHciWithOpenCleanTest, ScoOverHciOpenClean) { ASSERT_EQ(get_func_call_count("UIPC_Init"), 1); ASSERT_EQ(get_func_call_count("UIPC_Open"), 1); ASSERT_EQ(mock_uipc_init_ret, nullptr); mock_uipc_init_ret = std::make_unique<tUIPC_STATE>(); // Double open will override uipc bluetooth::audio::sco::open(); ASSERT_EQ(get_func_call_count("UIPC_Init"), 2); ASSERT_EQ(get_func_call_count("UIPC_Open"), 2); ASSERT_EQ(mock_uipc_init_ret, nullptr); bluetooth::audio::sco::cleanup(); ASSERT_EQ(get_func_call_count("UIPC_Close"), 1); // Double clean shouldn't fail bluetooth::audio::sco::cleanup(); ASSERT_EQ(get_func_call_count("UIPC_Close"), 1); } TEST_F(ScoHciTest, ScoOverHciReadNoOpen) { uint8_t buf[100]; ASSERT_EQ(bluetooth::audio::sco::read(buf, sizeof(buf)), size_t(0)); ASSERT_EQ(get_func_call_count("UIPC_Read"), 0); } TEST_F(ScoHciWithOpenCleanTest, ScoOverHciRead) { uint8_t buf[100]; // The UPIC should be ready ASSERT_EQ(get_func_call_count("UIPC_Init"), 1); ASSERT_EQ(get_func_call_count("UIPC_Open"), 1); ASSERT_EQ(mock_uipc_init_ret, nullptr); mock_uipc_read_ret = sizeof(buf); ASSERT_EQ(bluetooth::audio::sco::read(buf, sizeof(buf)), mock_uipc_read_ret); ASSERT_EQ(get_func_call_count("UIPC_Read"), 1); } TEST_F(ScoHciTest, ScoOverHciWriteNoOpen) { uint8_t buf[100]; bluetooth::audio::sco::write(buf, sizeof(buf)); ASSERT_EQ(get_func_call_count("UIPC_Send"), 0); } TEST_F(ScoHciWithOpenCleanTest, ScoOverHciWrite) { uint8_t buf[100]; // The UPIC should be ready ASSERT_EQ(get_func_call_count("UIPC_Init"), 1); ASSERT_EQ(get_func_call_count("UIPC_Open"), 1); ASSERT_EQ(mock_uipc_init_ret, nullptr); ASSERT_EQ(bluetooth::audio::sco::write(buf, sizeof(buf)), sizeof(buf)); ASSERT_EQ(get_func_call_count("UIPC_Send"), 1); // Send fails mock_uipc_send_ret = false; ASSERT_EQ(bluetooth::audio::sco::write(buf, sizeof(buf)), size_t(0)); ASSERT_EQ(get_func_call_count("UIPC_Send"), 2); } } // namespace