summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Archie Pusaka <apusaka@google.com> 2022-09-12 19:48:50 +0800
committer Archie Pusaka <apusaka@google.com> 2022-10-19 15:39:29 +0800
commit5c8aec51015e00b8b6fe8d430b3a5111439f3e13 (patch)
treeca87489b9f348d3c102bbd9e19b3643fa2e1a41d
parentaa88fe3f88386662b8d676d7b90ebed75c28e2e5 (diff)
floss: plumbing (dis)connection direction to btif
Whether (dis)connection is initiated by the host or by the peer is an information worthy of being logged by metrics. Therefore, surfacing it. Bug: 240782154 Tag: #floss Test: Verify connection direction is properly passed BYPASS_LONG_LINES_REASON: Bluetooth likes 120 lines Change-Id: I41f5b1333eded0c23459a58a5535258ebace7e3c
-rw-r--r--android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp3
-rw-r--r--system/btif/include/btif_common.h3
-rw-r--r--system/btif/src/bluetooth.cc10
-rw-r--r--system/btif/src/btif_dm.cc32
-rw-r--r--system/btif/test/btif_core_test.cc3
-rw-r--r--system/gd/hci/acl_manager/classic_impl.h18
-rw-r--r--system/gd/hci/acl_manager/connection_callbacks.h2
-rw-r--r--system/gd/hci/acl_manager/le_connection_callbacks.h2
-rw-r--r--system/gd/hci/acl_manager/le_impl.h29
-rw-r--r--system/gd/hci/acl_manager/le_impl_test.cc5
-rw-r--r--system/gd/hci/acl_manager_test.cc12
-rw-r--r--system/gd/hci/acl_manager_unittest.cc4
-rw-r--r--system/gd/hci/facade/acl_manager_facade.cc2
-rw-r--r--system/gd/hci/facade/le_acl_manager_facade.cc2
-rw-r--r--system/gd/l2cap/classic/internal/link_manager.cc2
-rw-r--r--system/gd/l2cap/classic/internal/link_manager.h2
-rw-r--r--system/gd/l2cap/classic/internal/link_manager_test.cc9
-rw-r--r--system/gd/l2cap/le/internal/link_manager.cc3
-rw-r--r--system/gd/l2cap/le/internal/link_manager.h2
-rw-r--r--system/gd/l2cap/le/internal/link_manager_test.cc9
-rw-r--r--system/gd/rust/linux/stack/src/bluetooth.rs8
-rw-r--r--system/gd/rust/topshim/src/btif.rs24
-rw-r--r--system/include/hardware/bluetooth.h10
-rw-r--r--system/main/shim/acl.cc20
-rw-r--r--system/main/shim/acl.h6
-rw-r--r--system/main/shim/acl_legacy_interface.h9
-rw-r--r--system/main/test/main_shim_test.cc8
-rw-r--r--system/service/adapter.cc3
-rw-r--r--system/service/hal/bluetooth_interface.cc10
-rw-r--r--system/service/hal/bluetooth_interface.h3
-rw-r--r--system/service/hal/fake_bluetooth_interface.cc6
-rw-r--r--system/service/hal/fake_bluetooth_interface.h3
-rw-r--r--system/service/test/adapter_unittest.cc8
-rw-r--r--system/stack/acl/acl.h3
-rw-r--r--system/stack/acl/ble_acl.cc15
-rw-r--r--system/stack/acl/btm_acl.cc31
-rw-r--r--system/stack/include/acl_api.h4
-rw-r--r--system/stack/include/acl_hci_link_interface.h5
-rw-r--r--system/stack/include/ble_acl_interface.h4
-rw-r--r--system/stack/include/hci_error_code.h1
-rw-r--r--system/test/headless/headless.cc4
-rw-r--r--system/test/headless/interface.h1
-rw-r--r--system/test/mock/mock_bluetooth_interface.cc3
-rw-r--r--system/test/mock/mock_stack_acl.cc15
-rw-r--r--system/test/mock/mock_stack_acl.h36
-rw-r--r--system/test/mock/mock_stack_acl_ble.cc4
46 files changed, 281 insertions, 117 deletions
diff --git a/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp b/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp
index b6cebbceed..47f5121078 100644
--- a/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp
+++ b/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp
@@ -368,7 +368,8 @@ static void le_address_associate_callback(RawAddress* main_bd_addr,
static void acl_state_changed_callback(bt_status_t status, RawAddress* bd_addr,
bt_acl_state_t state,
int transport_link_type,
- bt_hci_error_code_t hci_reason) {
+ bt_hci_error_code_t hci_reason,
+ bt_conn_direction_t direction) {
if (!bd_addr) {
ALOGE("Address is null in %s", __func__);
return;
diff --git a/system/btif/include/btif_common.h b/system/btif/include/btif_common.h
index cabf709a34..4d69014a9f 100644
--- a/system/btif/include/btif_common.h
+++ b/system/btif/include/btif_common.h
@@ -224,7 +224,8 @@ void invoke_le_address_associate_cb(RawAddress main_bd_addr,
RawAddress secondary_bd_addr);
void invoke_acl_state_changed_cb(bt_status_t status, RawAddress bd_addr,
bt_acl_state_t state, int transport_link_type,
- bt_hci_error_code_t hci_reason);
+ bt_hci_error_code_t hci_reason,
+ bt_conn_direction_t direction);
void invoke_thread_evt_cb(bt_cb_thread_evt event);
void invoke_le_test_mode_cb(bt_status_t status, uint16_t count);
void invoke_energy_info_cb(bt_activity_energy_info energy_info,
diff --git a/system/btif/src/bluetooth.cc b/system/btif/src/bluetooth.cc
index ffe884f289..a2d3a2574d 100644
--- a/system/btif/src/bluetooth.cc
+++ b/system/btif/src/bluetooth.cc
@@ -990,16 +990,18 @@ void invoke_le_address_associate_cb(RawAddress main_bd_addr,
}
void invoke_acl_state_changed_cb(bt_status_t status, RawAddress bd_addr,
bt_acl_state_t state, int transport_link_type,
- bt_hci_error_code_t hci_reason) {
+ bt_hci_error_code_t hci_reason,
+ bt_conn_direction_t direction) {
do_in_jni_thread(
FROM_HERE,
base::BindOnce(
[](bt_status_t status, RawAddress bd_addr, bt_acl_state_t state,
- int transport_link_type, bt_hci_error_code_t hci_reason) {
+ int transport_link_type, bt_hci_error_code_t hci_reason,
+ bt_conn_direction_t direction) {
HAL_CBACK(bt_hal_cbacks, acl_state_changed_cb, status, &bd_addr,
- state, transport_link_type, hci_reason);
+ state, transport_link_type, hci_reason, direction);
},
- status, bd_addr, state, transport_link_type, hci_reason));
+ status, bd_addr, state, transport_link_type, hci_reason, direction));
}
void invoke_thread_evt_cb(bt_cb_thread_evt event) {
diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc
index e6029ba68d..4c26b5281a 100644
--- a/system/btif/src/btif_dm.cc
+++ b/system/btif/src/btif_dm.cc
@@ -1825,26 +1825,48 @@ static void btif_dm_upstreams_evt(uint16_t event, char* p_param) {
invoke_acl_state_changed_cb(
BT_STATUS_SUCCESS, bd_addr, BT_ACL_STATE_CONNECTED,
- (int)p_data->link_up.transport_link_type, HCI_SUCCESS);
+ (int)p_data->link_up.transport_link_type, HCI_SUCCESS,
+ btm_is_acl_locally_initiated()
+ ? bt_conn_direction_t::BT_CONN_DIRECTION_OUTGOING
+ : bt_conn_direction_t::BT_CONN_DIRECTION_INCOMING);
break;
case BTA_DM_LINK_UP_FAILED_EVT:
invoke_acl_state_changed_cb(
BT_STATUS_FAIL, p_data->link_up_failed.bd_addr,
BT_ACL_STATE_DISCONNECTED, p_data->link_up_failed.transport_link_type,
- p_data->link_up_failed.status);
+ p_data->link_up_failed.status,
+ btm_is_acl_locally_initiated()
+ ? bt_conn_direction_t::BT_CONN_DIRECTION_OUTGOING
+ : bt_conn_direction_t::BT_CONN_DIRECTION_INCOMING);
break;
- case BTA_DM_LINK_DOWN_EVT:
+ case BTA_DM_LINK_DOWN_EVT: {
bd_addr = p_data->link_down.bd_addr;
btm_set_bond_type_dev(p_data->link_down.bd_addr,
tBTM_SEC_DEV_REC::BOND_TYPE_UNKNOWN);
btif_av_acl_disconnected(bd_addr);
+ bt_conn_direction_t direction;
+ switch (btm_get_acl_disc_reason_code()) {
+ case HCI_ERR_PEER_USER:
+ case HCI_ERR_REMOTE_LOW_RESOURCE:
+ case HCI_ERR_REMOTE_POWER_OFF:
+ direction = bt_conn_direction_t::BT_CONN_DIRECTION_INCOMING;
+ break;
+ case HCI_ERR_CONN_CAUSE_LOCAL_HOST:
+ case HCI_ERR_HOST_REJECT_SECURITY:
+ direction = bt_conn_direction_t::BT_CONN_DIRECTION_OUTGOING;
+ break;
+ default:
+ direction = bt_conn_direction_t::BT_CONN_DIRECTION_UNKNOWN;
+ }
+
invoke_acl_state_changed_cb(
BT_STATUS_SUCCESS, bd_addr, BT_ACL_STATE_DISCONNECTED,
(int)p_data->link_down.transport_link_type,
- static_cast<bt_hci_error_code_t>(btm_get_acl_disc_reason_code()));
+ static_cast<bt_hci_error_code_t>(btm_get_acl_disc_reason_code()),
+ direction);
LOG_DEBUG(
"Sent BT_ACL_STATE_DISCONNECTED upward as ACL link down event "
"device:%s reason:%s",
@@ -1852,7 +1874,7 @@ static void btif_dm_upstreams_evt(uint16_t event, char* p_param) {
hci_reason_code_text(
static_cast<tHCI_REASON>(btm_get_acl_disc_reason_code()))
.c_str());
- break;
+ } break;
case BTA_DM_BLE_KEY_EVT:
BTIF_TRACE_DEBUG("BTA_DM_BLE_KEY_EVT key_type=0x%02x ",
diff --git a/system/btif/test/btif_core_test.cc b/system/btif/test/btif_core_test.cc
index 82f86dc5fb..17dcebe135 100644
--- a/system/btif/test/btif_core_test.cc
+++ b/system/btif/test/btif_core_test.cc
@@ -69,7 +69,8 @@ void le_address_associate_callback(RawAddress* main_bd_addr,
RawAddress* secondary_bd_addr) {}
void acl_state_changed_callback(bt_status_t status, RawAddress* remote_bd_addr,
bt_acl_state_t state, int transport_link_type,
- bt_hci_error_code_t hci_reason) {}
+ bt_hci_error_code_t hci_reason,
+ bt_conn_direction_t direction) {}
void link_quality_report_callback(uint64_t timestamp, int report_id, int rssi,
int snr, int retransmission_count,
int packets_not_receive_count,
diff --git a/system/gd/hci/acl_manager/classic_impl.h b/system/gd/hci/acl_manager/classic_impl.h
index 9433664202..f68f8e7f0d 100644
--- a/system/gd/hci/acl_manager/classic_impl.h
+++ b/system/gd/hci/acl_manager/classic_impl.h
@@ -310,7 +310,11 @@ struct classic_impl : public security::ISecurityManagerListener {
LOG_ERROR("Failed to create connection, reporting failure and continuing");
ASSERT(client_callbacks_ != nullptr);
client_handler_->Post(common::BindOnce(
- &ConnectionCallbacks::OnConnectFail, common::Unretained(client_callbacks_), address, status.GetStatus()));
+ &ConnectionCallbacks::OnConnectFail,
+ common::Unretained(client_callbacks_),
+ address,
+ status.GetStatus(),
+ true /* locally initiated */));
acl_scheduler_->ReportOutgoingAclConnectionFailure();
} else {
// everything is good, resume when a connection_complete event arrives
@@ -333,7 +337,11 @@ struct classic_impl : public security::ISecurityManagerListener {
}
if (status != ErrorCode::SUCCESS) {
client_handler_->Post(common::BindOnce(
- &ConnectionCallbacks::OnConnectFail, common::Unretained(client_callbacks_), address, status));
+ &ConnectionCallbacks::OnConnectFail,
+ common::Unretained(client_callbacks_),
+ address,
+ status,
+ initiator == Initiator::LOCALLY_INITIATED));
return;
}
uint16_t handle = connection_complete.GetConnectionHandle();
@@ -401,7 +409,11 @@ struct classic_impl : public security::ISecurityManagerListener {
address,
handler_->BindOnceOn(this, &classic_impl::actually_cancel_connect, address),
client_handler_->BindOnceOn(
- client_callbacks_, &ConnectionCallbacks::OnConnectFail, address, ErrorCode::UNKNOWN_CONNECTION));
+ client_callbacks_,
+ &ConnectionCallbacks::OnConnectFail,
+ address,
+ ErrorCode::UNKNOWN_CONNECTION,
+ true /* locally initiated */));
}
void actually_cancel_connect(Address address) {
diff --git a/system/gd/hci/acl_manager/connection_callbacks.h b/system/gd/hci/acl_manager/connection_callbacks.h
index 9a72654e26..6043bf49cc 100644
--- a/system/gd/hci/acl_manager/connection_callbacks.h
+++ b/system/gd/hci/acl_manager/connection_callbacks.h
@@ -33,7 +33,7 @@ class ConnectionCallbacks {
// Invoked when controller sends Connection Complete event with Success error code
virtual void OnConnectSuccess(std::unique_ptr<ClassicAclConnection>) = 0;
// Invoked when controller sends Connection Complete event with non-Success error code
- virtual void OnConnectFail(Address, ErrorCode reason) = 0;
+ virtual void OnConnectFail(Address, ErrorCode reason, bool locally_initiated) = 0;
virtual void HACK_OnEscoConnectRequest(Address, ClassOfDevice) = 0;
virtual void HACK_OnScoConnectRequest(Address, ClassOfDevice) = 0;
diff --git a/system/gd/hci/acl_manager/le_connection_callbacks.h b/system/gd/hci/acl_manager/le_connection_callbacks.h
index 07abc9a21c..594b2ca015 100644
--- a/system/gd/hci/acl_manager/le_connection_callbacks.h
+++ b/system/gd/hci/acl_manager/le_connection_callbacks.h
@@ -33,7 +33,7 @@ class LeConnectionCallbacks {
// AddressWithType is always equal to the object used in AclManager#CreateLeConnection
virtual void OnLeConnectSuccess(AddressWithType, std::unique_ptr<LeAclConnection>) = 0;
// Invoked when create connection timeout or controller sends Connection Complete event with non-Success error code
- virtual void OnLeConnectFail(AddressWithType, ErrorCode reason) = 0;
+ virtual void OnLeConnectFail(AddressWithType, ErrorCode reason, bool locally_initiated) = 0;
};
} // namespace acl_manager
diff --git a/system/gd/hci/acl_manager/le_impl.h b/system/gd/hci/acl_manager/le_impl.h
index 6ad94efb46..a8dfdc2528 100644
--- a/system/gd/hci/acl_manager/le_impl.h
+++ b/system/gd/hci/acl_manager/le_impl.h
@@ -343,7 +343,11 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
if (status != ErrorCode::SUCCESS) {
le_client_handler_->Post(common::BindOnce(
- &LeConnectionCallbacks::OnLeConnectFail, common::Unretained(le_client_callbacks_), remote_address, status));
+ &LeConnectionCallbacks::OnLeConnectFail,
+ common::Unretained(le_client_callbacks_),
+ remote_address,
+ status,
+ true /* locally_initiated */));
return;
}
} else {
@@ -356,6 +360,12 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
if (status != ErrorCode::SUCCESS) {
std::string error_code = ErrorCodeText(status);
LOG_WARN("Received on_le_connection_complete with error code %s", error_code.c_str());
+ le_client_handler_->Post(common::BindOnce(
+ &LeConnectionCallbacks::OnLeConnectFail,
+ common::Unretained(le_client_callbacks_),
+ remote_address,
+ status,
+ false /* locally_initiated */));
return;
}
@@ -390,6 +400,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
connection->latency_ = conn_latency;
connection->supervision_timeout_ = supervision_timeout;
connection->in_filter_accept_list_ = in_filter_accept_list;
+ connection->locally_initiated_ = (role == hci::Role::CENTRAL);
connections.add(
handle, remote_address, queue_down_end, handler_, connection->GetEventCallbacks([this](uint16_t handle) {
this->connections.invalidate(handle);
@@ -456,7 +467,11 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
if (status != ErrorCode::SUCCESS) {
le_client_handler_->Post(common::BindOnce(
- &LeConnectionCallbacks::OnLeConnectFail, common::Unretained(le_client_callbacks_), remote_address, status));
+ &LeConnectionCallbacks::OnLeConnectFail,
+ common::Unretained(le_client_callbacks_),
+ remote_address,
+ status,
+ true /* locally_initiated */));
return;
}
@@ -470,6 +485,12 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
if (status != ErrorCode::SUCCESS) {
std::string error_code = ErrorCodeText(status);
LOG_WARN("Received on_le_enhanced_connection_complete with error code %s", error_code.c_str());
+ le_client_handler_->Post(common::BindOnce(
+ &LeConnectionCallbacks::OnLeConnectFail,
+ common::Unretained(le_client_callbacks_),
+ remote_address,
+ status,
+ false /* locally_initiated */));
return;
}
@@ -514,6 +535,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
connection->local_resolvable_private_address_ = connection_complete.GetLocalResolvablePrivateAddress();
connection->peer_resolvable_private_address_ = connection_complete.GetPeerResolvablePrivateAddress();
connection->in_filter_accept_list_ = in_filter_accept_list;
+ connection->locally_initiated_ = (role == hci::Role::CENTRAL);
connections.add(
handle, remote_address, queue_down_end, handler_, connection->GetEventCallbacks([this](uint16_t handle) {
this->connections.invalidate(handle);
@@ -939,7 +961,8 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
&LeConnectionCallbacks::OnLeConnectFail,
common::Unretained(le_client_callbacks_),
address_with_type,
- ErrorCode::CONNECTION_ACCEPT_TIMEOUT));
+ ErrorCode::CONNECTION_ACCEPT_TIMEOUT,
+ true /* locally_initiated */));
}
}
diff --git a/system/gd/hci/acl_manager/le_impl_test.cc b/system/gd/hci/acl_manager/le_impl_test.cc
index e1238d49d6..dfe3446947 100644
--- a/system/gd/hci/acl_manager/le_impl_test.cc
+++ b/system/gd/hci/acl_manager/le_impl_test.cc
@@ -389,7 +389,8 @@ class MockLeConnectionCallbacks : public LeConnectionCallbacks {
OnLeConnectSuccess,
(AddressWithType address_with_type, std::unique_ptr<LeAclConnection> connection),
(override));
- MOCK_METHOD(void, OnLeConnectFail, (AddressWithType address_with_type, ErrorCode reason), (override));
+ MOCK_METHOD(
+ void, OnLeConnectFail, (AddressWithType address_with_type, ErrorCode reason, bool locally_initiated), (override));
};
class MockLeConnectionManagementCallbacks : public LeConnectionManagementCallbacks {
@@ -1417,7 +1418,7 @@ TEST_F(LeImplTest, on_le_connection_canceled_on_pause) {
}
TEST_F(LeImplTest, on_create_connection_timeout) {
- EXPECT_CALL(mock_le_connection_callbacks_, OnLeConnectFail(_, ErrorCode::CONNECTION_ACCEPT_TIMEOUT)).Times(1);
+ EXPECT_CALL(mock_le_connection_callbacks_, OnLeConnectFail(_, ErrorCode::CONNECTION_ACCEPT_TIMEOUT, _)).Times(1);
le_impl_->create_connection_timeout_alarms_.emplace(
std::piecewise_construct,
std::forward_as_tuple(
diff --git a/system/gd/hci/acl_manager_test.cc b/system/gd/hci/acl_manager_test.cc
index 73e3228310..f22de4e85f 100644
--- a/system/gd/hci/acl_manager_test.cc
+++ b/system/gd/hci/acl_manager_test.cc
@@ -408,7 +408,7 @@ class AclManagerNoCallbacksTest : public ::testing::Test {
connection_promise_.reset();
}
}
- MOCK_METHOD(void, OnConnectFail, (Address, ErrorCode reason), (override));
+ MOCK_METHOD(void, OnConnectFail, (Address, ErrorCode reason, bool locally_initiated), (override));
MOCK_METHOD(void, HACK_OnEscoConnectRequest, (Address, ClassOfDevice), (override));
MOCK_METHOD(void, HACK_OnScoConnectRequest, (Address, ClassOfDevice), (override));
@@ -426,7 +426,7 @@ class AclManagerNoCallbacksTest : public ::testing::Test {
le_connection_promise_.reset();
}
}
- MOCK_METHOD(void, OnLeConnectFail, (AddressWithType, ErrorCode reason), (override));
+ MOCK_METHOD(void, OnLeConnectFail, (AddressWithType, ErrorCode reason, bool locally_initiated), (override));
std::list<std::shared_ptr<LeAclConnection>> le_connections_;
std::unique_ptr<std::promise<void>> le_connection_promise_;
@@ -582,7 +582,7 @@ TEST_F(AclManagerTest, invoke_registered_callback_connection_complete_fail) {
last_command = test_hci_layer_->GetCommand(OpCode::CREATE_CONNECTION);
}
- EXPECT_CALL(mock_connection_callback_, OnConnectFail(remote, ErrorCode::PAGE_TIMEOUT));
+ EXPECT_CALL(mock_connection_callback_, OnConnectFail(remote, ErrorCode::PAGE_TIMEOUT, true));
test_hci_layer_->IncomingEvent(
ConnectionCompleteBuilder::Create(ErrorCode::PAGE_TIMEOUT, handle, remote, LinkType::ACL, Enable::DISABLED));
fake_registry_.SynchronizeModuleHandler(&HciLayer::Factory, std::chrono::milliseconds(20));
@@ -705,8 +705,10 @@ TEST_F(AclManagerTest, invoke_registered_callback_le_connection_complete_fail) {
test_hci_layer_->IncomingEvent(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01));
- EXPECT_CALL(mock_le_connection_callbacks_,
- OnLeConnectFail(remote_with_type, ErrorCode::CONNECTION_REJECTED_LIMITED_RESOURCES));
+ EXPECT_CALL(
+ mock_le_connection_callbacks_,
+ OnLeConnectFail(
+ remote_with_type, ErrorCode::CONNECTION_REJECTED_LIMITED_RESOURCES, /* locally_initiated */ true));
test_hci_layer_->IncomingLeMetaEvent(LeConnectionCompleteBuilder::Create(
ErrorCode::CONNECTION_REJECTED_LIMITED_RESOURCES,
0x123,
diff --git a/system/gd/hci/acl_manager_unittest.cc b/system/gd/hci/acl_manager_unittest.cc
index cc22be79ce..a824bfce29 100644
--- a/system/gd/hci/acl_manager_unittest.cc
+++ b/system/gd/hci/acl_manager_unittest.cc
@@ -349,7 +349,7 @@ class MockConnectionCallback : public ConnectionCallbacks {
connection_promise_.set_value(connections_.back());
}
}
- MOCK_METHOD(void, OnConnectFail, (Address, ErrorCode reason), (override));
+ MOCK_METHOD(void, OnConnectFail, (Address, ErrorCode reason, bool locally_initiated), (override));
MOCK_METHOD(void, HACK_OnEscoConnectRequest, (Address, ClassOfDevice), (override));
MOCK_METHOD(void, HACK_OnScoConnectRequest, (Address, ClassOfDevice), (override));
@@ -376,7 +376,7 @@ class MockLeConnectionCallbacks : public LeConnectionCallbacks {
le_connection_promise_.reset();
}
}
- MOCK_METHOD(void, OnLeConnectFail, (AddressWithType, ErrorCode reason), (override));
+ MOCK_METHOD(void, OnLeConnectFail, (AddressWithType, ErrorCode reason, bool locally_initiated), (override));
std::deque<std::shared_ptr<LeAclConnection>> le_connections_;
std::unique_ptr<std::promise<void>> le_connection_promise_;
diff --git a/system/gd/hci/facade/acl_manager_facade.cc b/system/gd/hci/facade/acl_manager_facade.cc
index 0911577cd8..3df393086a 100644
--- a/system/gd/hci/facade/acl_manager_facade.cc
+++ b/system/gd/hci/facade/acl_manager_facade.cc
@@ -374,7 +374,7 @@ class AclManagerFacadeService : public AclManagerFacade::Service, public Connect
current_connection_request_++;
}
- void OnConnectFail(Address address, ErrorCode reason) override {
+ void OnConnectFail(Address address, ErrorCode reason, bool locally_initiated) override {
LOG_INFO("addr=%s, reason=%s", address.ToString().c_str(), ErrorCodeText(reason).c_str());
std::unique_ptr<BasePacketBuilder> builder =
ConnectionCompleteBuilder::Create(reason, 0, address, LinkType::ACL, Enable::DISABLED);
diff --git a/system/gd/hci/facade/le_acl_manager_facade.cc b/system/gd/hci/facade/le_acl_manager_facade.cc
index b5a2d19071..1cba077484 100644
--- a/system/gd/hci/facade/le_acl_manager_facade.cc
+++ b/system/gd/hci/facade/le_acl_manager_facade.cc
@@ -314,7 +314,7 @@ class LeAclManagerFacadeService : public LeAclManagerFacade::Service, public LeC
}
}
- void OnLeConnectFail(AddressWithType address, ErrorCode reason) override {
+ void OnLeConnectFail(AddressWithType address, ErrorCode reason, bool locally_initiated) override {
LOG_INFO("addr=%s, reason=%s", address.ToString().c_str(), ErrorCodeText(reason).c_str());
std::unique_ptr<BasePacketBuilder> builder = LeConnectionCompleteBuilder::Create(
reason, 0, Role::CENTRAL, address.GetAddressType(), address.GetAddress(), 0, 0, 0, ClockAccuracy::PPM_20);
diff --git a/system/gd/l2cap/classic/internal/link_manager.cc b/system/gd/l2cap/classic/internal/link_manager.cc
index f8ff461d77..a34f4f4070 100644
--- a/system/gd/l2cap/classic/internal/link_manager.cc
+++ b/system/gd/l2cap/classic/internal/link_manager.cc
@@ -284,7 +284,7 @@ void LinkManager::OnConnectSuccess(std::unique_ptr<hci::acl_manager::ClassicAclC
pending_links_.erase(device);
}
-void LinkManager::OnConnectFail(hci::Address device, hci::ErrorCode reason) {
+void LinkManager::OnConnectFail(hci::Address device, hci::ErrorCode reason, bool locally_initiated) {
// Notify all pending links for this device
auto pending_link = pending_links_.find(device);
if (pending_link == pending_links_.end()) {
diff --git a/system/gd/l2cap/classic/internal/link_manager.h b/system/gd/l2cap/classic/internal/link_manager.h
index 4d327ea5bf..5e6d5599b9 100644
--- a/system/gd/l2cap/classic/internal/link_manager.h
+++ b/system/gd/l2cap/classic/internal/link_manager.h
@@ -68,7 +68,7 @@ class LinkManager : public hci::acl_manager::ConnectionCallbacks {
Link* GetLink(hci::Address device);
void OnConnectSuccess(std::unique_ptr<hci::acl_manager::ClassicAclConnection> acl_connection) override;
- void OnConnectFail(hci::Address device, hci::ErrorCode reason) override;
+ void OnConnectFail(hci::Address device, hci::ErrorCode reason, bool locally_initiated) override;
void HACK_OnEscoConnectRequest(hci::Address, hci::ClassOfDevice) override;
void HACK_OnScoConnectRequest(hci::Address, hci::ClassOfDevice) override;
diff --git a/system/gd/l2cap/classic/internal/link_manager_test.cc b/system/gd/l2cap/classic/internal/link_manager_test.cc
index d59e0dd9b9..b48cd8a894 100644
--- a/system/gd/l2cap/classic/internal/link_manager_test.cc
+++ b/system/gd/l2cap/classic/internal/link_manager_test.cc
@@ -253,9 +253,12 @@ TEST_F(L2capClassicLinkManagerTest, connect_fixed_channel_service_without_acl_wi
// Step 3: ACL connection failure event should trigger connection failure callback
EXPECT_CALL(mock_service_1, NotifyChannelCreation(_)).Times(0);
- hci_callback_handler->Post(common::BindOnce(&hci::acl_manager::ConnectionCallbacks::OnConnectFail,
- common::Unretained(hci_connection_callbacks), device,
- hci::ErrorCode::PAGE_TIMEOUT));
+ hci_callback_handler->Post(common::BindOnce(
+ &hci::acl_manager::ConnectionCallbacks::OnConnectFail,
+ common::Unretained(hci_connection_callbacks),
+ device,
+ hci::ErrorCode::PAGE_TIMEOUT,
+ true /* locally_initiated */));
SyncHandler(hci_callback_handler);
SyncHandler(user_handler.get());
EXPECT_EQ(my_result.connection_result_code, FixedChannelManager::ConnectionResultCode::FAIL_HCI_ERROR);
diff --git a/system/gd/l2cap/le/internal/link_manager.cc b/system/gd/l2cap/le/internal/link_manager.cc
index f2677a3bfe..09b6c34107 100644
--- a/system/gd/l2cap/le/internal/link_manager.cc
+++ b/system/gd/l2cap/le/internal/link_manager.cc
@@ -127,7 +127,8 @@ void LinkManager::OnLeConnectSuccess(hci::AddressWithType connecting_address_wit
link->ReadRemoteVersionInformation();
}
-void LinkManager::OnLeConnectFail(hci::AddressWithType address_with_type, hci::ErrorCode reason) {
+void LinkManager::OnLeConnectFail(
+ hci::AddressWithType address_with_type, hci::ErrorCode reason, bool locally_initiated) {
// Notify all pending links for this device
auto pending_link = pending_links_.find(address_with_type);
if (pending_link == pending_links_.end()) {
diff --git a/system/gd/l2cap/le/internal/link_manager.h b/system/gd/l2cap/le/internal/link_manager.h
index 836a3f6e8c..fd00063bb2 100644
--- a/system/gd/l2cap/le/internal/link_manager.h
+++ b/system/gd/l2cap/le/internal/link_manager.h
@@ -73,7 +73,7 @@ class LinkManager : public hci::acl_manager::LeConnectionCallbacks {
Link* GetLink(hci::AddressWithType address_with_type);
void OnLeConnectSuccess(hci::AddressWithType connecting_address_with_type,
std::unique_ptr<hci::acl_manager::LeAclConnection> acl_connection) override;
- void OnLeConnectFail(hci::AddressWithType address_with_type, hci::ErrorCode reason) override;
+ void OnLeConnectFail(hci::AddressWithType address_with_type, hci::ErrorCode reason, bool locally_initiated) override;
// FixedChannelManager methods
diff --git a/system/gd/l2cap/le/internal/link_manager_test.cc b/system/gd/l2cap/le/internal/link_manager_test.cc
index c7585f7f09..6d3932a885 100644
--- a/system/gd/l2cap/le/internal/link_manager_test.cc
+++ b/system/gd/l2cap/le/internal/link_manager_test.cc
@@ -272,9 +272,12 @@ TEST_F(L2capLeLinkManagerTest, connect_fixed_channel_service_without_acl_with_hc
// Step 3: ACL connection failure event should trigger connection failure callback
EXPECT_CALL(mock_service_1, NotifyChannelCreation(_)).Times(0);
- hci_callback_handler->Post(common::BindOnce(&hci::acl_manager::LeConnectionCallbacks::OnLeConnectFail,
- common::Unretained(hci_le_connection_callbacks), address_with_type,
- hci::ErrorCode::PAGE_TIMEOUT));
+ hci_callback_handler->Post(common::BindOnce(
+ &hci::acl_manager::LeConnectionCallbacks::OnLeConnectFail,
+ common::Unretained(hci_le_connection_callbacks),
+ address_with_type,
+ hci::ErrorCode::PAGE_TIMEOUT,
+ true /* locally_initiated */));
SyncHandler(hci_callback_handler);
SyncHandler(user_handler_);
EXPECT_EQ(my_result.connection_result_code, FixedChannelManager::ConnectionResultCode::FAIL_HCI_ERROR);
diff --git a/system/gd/rust/linux/stack/src/bluetooth.rs b/system/gd/rust/linux/stack/src/bluetooth.rs
index c06734a68c..311118094e 100644
--- a/system/gd/rust/linux/stack/src/bluetooth.rs
+++ b/system/gd/rust/linux/stack/src/bluetooth.rs
@@ -2,9 +2,9 @@
use bt_topshim::btif::{
BaseCallbacks, BaseCallbacksDispatcher, BluetoothInterface, BluetoothProperty, BtAclState,
- BtBondState, BtConnectionState, BtDeviceType, BtDiscoveryState, BtHciErrorCode, BtPinCode,
- BtPropertyType, BtScanMode, BtSspVariant, BtState, BtStatus, BtTransport, BtVendorProductInfo,
- RawAddress, ToggleableProfile, Uuid, Uuid128Bit,
+ BtBondState, BtConnectionDirection, BtConnectionState, BtDeviceType, BtDiscoveryState,
+ BtHciErrorCode, BtPinCode, BtPropertyType, BtScanMode, BtSspVariant, BtState, BtStatus,
+ BtTransport, BtVendorProductInfo, RawAddress, ToggleableProfile, Uuid, Uuid128Bit,
};
use bt_topshim::{
metrics,
@@ -724,6 +724,7 @@ pub(crate) trait BtifBluetoothCallbacks {
state: BtAclState,
link_type: BtTransport,
hci_reason: BtHciErrorCode,
+ conn_direction: BtConnectionDirection,
) {
}
@@ -1066,6 +1067,7 @@ impl BtifBluetoothCallbacks for Bluetooth {
state: BtAclState,
_link_type: BtTransport,
_hci_reason: BtHciErrorCode,
+ _conn_direction: BtConnectionDirection,
) {
if status != BtStatus::Success {
warn!("Connection to [{}] failed. Status: {:?}", addr.to_string(), status);
diff --git a/system/gd/rust/topshim/src/btif.rs b/system/gd/rust/topshim/src/btif.rs
index a82e0a4aee..fcf9120a43 100644
--- a/system/gd/rust/topshim/src/btif.rs
+++ b/system/gd/rust/topshim/src/btif.rs
@@ -24,7 +24,7 @@ pub enum BtState {
impl From<bindings::bt_state_t> for BtState {
fn from(item: bindings::bt_state_t) -> Self {
- BtState::from_u32(item).unwrap_or_else(|| BtState::Off)
+ BtState::from_u32(item).unwrap_or(BtState::Off)
}
}
@@ -38,13 +38,13 @@ pub enum BtTransport {
impl From<i32> for BtTransport {
fn from(item: i32) -> Self {
- BtTransport::from_i32(item).unwrap_or_else(|| BtTransport::Auto)
+ BtTransport::from_i32(item).unwrap_or(BtTransport::Auto)
}
}
impl From<BtTransport> for i32 {
fn from(item: BtTransport) -> Self {
- item.to_i32().unwrap_or_else(|| 0)
+ item.to_i32().unwrap_or(0)
}
}
@@ -59,13 +59,13 @@ pub enum BtSspVariant {
impl From<bindings::bt_ssp_variant_t> for BtSspVariant {
fn from(item: bindings::bt_ssp_variant_t) -> Self {
- BtSspVariant::from_u32(item).unwrap_or_else(|| BtSspVariant::PasskeyConfirmation)
+ BtSspVariant::from_u32(item).unwrap_or(BtSspVariant::PasskeyConfirmation)
}
}
impl From<BtSspVariant> for bindings::bt_ssp_variant_t {
fn from(item: BtSspVariant) -> Self {
- item.to_u32().unwrap_or_else(|| 0)
+ item.to_u32().unwrap_or(0)
}
}
@@ -79,7 +79,7 @@ pub enum BtBondState {
impl From<bindings::bt_bond_state_t> for BtBondState {
fn from(item: bindings::bt_bond_state_t) -> Self {
- BtBondState::from_u32(item).unwrap_or_else(|| BtBondState::NotBonded)
+ BtBondState::from_u32(item).unwrap_or(BtBondState::NotBonded)
}
}
@@ -114,7 +114,7 @@ pub enum BtAclState {
impl From<bindings::bt_acl_state_t> for BtAclState {
fn from(item: bindings::bt_acl_state_t) -> Self {
- BtAclState::from_u32(item).unwrap_or_else(|| BtAclState::Disconnected)
+ BtAclState::from_u32(item).unwrap_or(BtAclState::Disconnected)
}
}
@@ -156,13 +156,13 @@ pub enum BtPropertyType {
impl From<u32> for BtPropertyType {
fn from(item: u32) -> Self {
- BtPropertyType::from_u32(item).unwrap_or_else(|| BtPropertyType::Unknown)
+ BtPropertyType::from_u32(item).unwrap_or(BtPropertyType::Unknown)
}
}
impl From<BtPropertyType> for u32 {
fn from(item: BtPropertyType) -> Self {
- item.to_u32().unwrap_or_else(|| 0)
+ item.to_u32().unwrap_or(0)
}
}
@@ -175,7 +175,7 @@ pub enum BtDiscoveryState {
impl From<u32> for BtDiscoveryState {
fn from(item: u32) -> Self {
- BtDiscoveryState::from_u32(item).unwrap_or_else(|| BtDiscoveryState::Stopped)
+ BtDiscoveryState::from_u32(item).unwrap_or(BtDiscoveryState::Stopped)
}
}
@@ -851,7 +851,7 @@ pub enum BaseCallbacks {
BondState(BtStatus, RawAddress, BtBondState, i32),
AddressConsolidate(RawAddress, RawAddress),
LeAddressAssociate(RawAddress, RawAddress),
- AclState(BtStatus, RawAddress, BtAclState, BtTransport, BtHciErrorCode),
+ AclState(BtStatus, RawAddress, BtAclState, BtTransport, BtHciErrorCode, BtConnectionDirection),
// Unimplemented so far:
// thread_evt_cb
// dut_mode_recv_cb
@@ -914,7 +914,7 @@ cb_variant!(BaseCb, le_address_associate_cb -> BaseCallbacks::LeAddressAssociate
});
cb_variant!(BaseCb, acl_state_cb -> BaseCallbacks::AclState,
-u32 -> BtStatus, *mut FfiAddress, bindings::bt_acl_state_t -> BtAclState, i32 -> BtTransport, bindings::bt_hci_error_code_t -> BtHciErrorCode, {
+u32 -> BtStatus, *mut FfiAddress, bindings::bt_acl_state_t -> BtAclState, i32 -> BtTransport, bindings::bt_hci_error_code_t -> BtHciErrorCode, bindings::bt_conn_direction_t -> BtConnectionDirection, {
let _1 = unsafe { *(_1 as *const RawAddress) };
});
diff --git a/system/include/hardware/bluetooth.h b/system/include/hardware/bluetooth.h
index 5d6587a27e..3295cecd41 100644
--- a/system/include/hardware/bluetooth.h
+++ b/system/include/hardware/bluetooth.h
@@ -176,6 +176,13 @@ typedef enum {
BT_ACL_STATE_DISCONNECTED
} bt_acl_state_t;
+/** Bluetooth ACL connection direction */
+typedef enum {
+ BT_CONN_DIRECTION_UNKNOWN,
+ BT_CONN_DIRECTION_OUTGOING,
+ BT_CONN_DIRECTION_INCOMING
+} bt_conn_direction_t;
+
/** Bluetooth SDP service record */
typedef struct {
bluetooth::Uuid uuid;
@@ -492,7 +499,8 @@ typedef void (*acl_state_changed_callback)(bt_status_t status,
RawAddress* remote_bd_addr,
bt_acl_state_t state,
int transport_link_type,
- bt_hci_error_code_t hci_reason);
+ bt_hci_error_code_t hci_reason,
+ bt_conn_direction_t direction);
/** Bluetooth link quality report callback */
typedef void (*link_quality_report_callback)(
diff --git a/system/main/shim/acl.cc b/system/main/shim/acl.cc
index 58f9b3200f..6516db19f5 100644
--- a/system/main/shim/acl.cc
+++ b/system/main/shim/acl.cc
@@ -1483,7 +1483,7 @@ void shim::legacy::Acl::OnConnectSuccess(
->ReadRemoteControllerInformation();
TRY_POSTING_ON_MAIN(acl_interface_.connection.classic.on_connected, bd_addr,
- handle, false);
+ handle, false, locally_initiated);
LOG_DEBUG("Connection successful classic remote:%s handle:%hu initiator:%s",
PRIVATE_ADDRESS(remote_address), handle,
(locally_initiated) ? "local" : "remote");
@@ -1494,10 +1494,11 @@ void shim::legacy::Acl::OnConnectSuccess(
}
void shim::legacy::Acl::OnConnectFail(hci::Address address,
- hci::ErrorCode reason) {
+ hci::ErrorCode reason,
+ bool locally_initiated) {
const RawAddress bd_addr = ToRawAddress(address);
TRY_POSTING_ON_MAIN(acl_interface_.connection.classic.on_failed, bd_addr,
- ToLegacyHciErrorCode(reason));
+ ToLegacyHciErrorCode(reason), locally_initiated);
LOG_WARN("Connection failed classic remote:%s reason:%s",
PRIVATE_ADDRESS(address), hci::ErrorCodeText(reason).c_str());
BTM_LogHistory(kBtmLogTag, ToRawAddress(address), "Connection failed",
@@ -1606,7 +1607,8 @@ void shim::legacy::Acl::OnLeConnectSuccess(
}
void shim::legacy::Acl::OnLeConnectFail(hci::AddressWithType address_with_type,
- hci::ErrorCode reason) {
+ hci::ErrorCode reason,
+ bool locally_initiated) {
tBLE_BD_ADDR legacy_address_with_type =
ToLegacyAddressWithType(address_with_type);
@@ -1614,10 +1616,14 @@ void shim::legacy::Acl::OnLeConnectFail(hci::AddressWithType address_with_type,
bool enhanced = true; /* TODO logging metrics only */
tHCI_STATUS status = ToLegacyHciErrorCode(reason);
- pimpl_->shadow_acceptlist_.Remove(address_with_type);
-
TRY_POSTING_ON_MAIN(acl_interface_.connection.le.on_failed,
- legacy_address_with_type, handle, enhanced, status);
+ legacy_address_with_type, handle, enhanced, status,
+ locally_initiated);
+ if (!locally_initiated) {
+ return;
+ }
+
+ pimpl_->shadow_acceptlist_.Remove(address_with_type);
LOG_WARN("Connection failed le remote:%s",
PRIVATE_ADDRESS(address_with_type));
BTM_LogHistory(
diff --git a/system/main/shim/acl.h b/system/main/shim/acl.h
index a4ede40354..859071a315 100644
--- a/system/main/shim/acl.h
+++ b/system/main/shim/acl.h
@@ -54,7 +54,8 @@ class Acl : public hci::acl_manager::ConnectionCallbacks,
// hci::acl_manager::ConnectionCallbacks
void OnConnectSuccess(
std::unique_ptr<hci::acl_manager::ClassicAclConnection>) override;
- void OnConnectFail(hci::Address, hci::ErrorCode reason) override;
+ void OnConnectFail(hci::Address, hci::ErrorCode reason,
+ bool locally_initiated) override;
void HACK_OnEscoConnectRequest(hci::Address, hci::ClassOfDevice) override;
void HACK_OnScoConnectRequest(hci::Address, hci::ClassOfDevice) override;
@@ -65,7 +66,8 @@ class Acl : public hci::acl_manager::ConnectionCallbacks,
void OnLeConnectSuccess(
hci::AddressWithType,
std::unique_ptr<hci::acl_manager::LeAclConnection>) override;
- void OnLeConnectFail(hci::AddressWithType, hci::ErrorCode reason) override;
+ void OnLeConnectFail(hci::AddressWithType, hci::ErrorCode reason,
+ bool locally_initiated) override;
void OnLeLinkDisconnected(uint16_t handle, hci::ErrorCode reason);
bluetooth::hci::AddressWithType GetConnectionLocalAddress(
const RawAddress& remote_bda);
diff --git a/system/main/shim/acl_legacy_interface.h b/system/main/shim/acl_legacy_interface.h
index 5422df8335..cdc429a473 100644
--- a/system/main/shim/acl_legacy_interface.h
+++ b/system/main/shim/acl_legacy_interface.h
@@ -34,9 +34,10 @@ namespace shim {
namespace legacy {
typedef struct {
- void (*on_connected)(const RawAddress& bda, uint16_t handle,
- uint8_t enc_mode);
- void (*on_failed)(const RawAddress& bda, tHCI_STATUS status);
+ void (*on_connected)(const RawAddress& bda, uint16_t handle, uint8_t enc_mode,
+ bool locally_initiated);
+ void (*on_failed)(const RawAddress& bda, tHCI_STATUS status,
+ bool locally_initiated);
void (*on_disconnected)(tHCI_STATUS status, uint16_t handle,
tHCI_STATUS reason);
} acl_classic_connection_interface_t;
@@ -48,7 +49,7 @@ typedef struct {
const RawAddress& local_rpa, const RawAddress& peer_rpa,
tBLE_ADDR_TYPE peer_addr_type);
void (*on_failed)(const tBLE_BD_ADDR& address_with_type, uint16_t handle,
- bool enhanced, tHCI_STATUS status);
+ bool enhanced, tHCI_STATUS status, bool locally_initiated);
void (*on_disconnected)(tHCI_STATUS status, uint16_t handle,
tHCI_STATUS reason);
void (*on_iso_disconnected)(uint16_t handle, tHCI_STATUS reason);
diff --git a/system/main/test/main_shim_test.cc b/system/main/test/main_shim_test.cc
index fd4d108c82..71ee878dde 100644
--- a/system/main/test/main_shim_test.cc
+++ b/system/main/test/main_shim_test.cc
@@ -122,10 +122,12 @@ void mock_on_send_data_upwards(BT_HDR*) {}
void mock_on_packets_completed(uint16_t handle, uint16_t num_packets) {}
void mock_connection_classic_on_connected(const RawAddress& bda,
- uint16_t handle, uint8_t enc_mode) {}
+ uint16_t handle, uint8_t enc_mode,
+ bool locally_initiated) {}
void mock_connection_classic_on_failed(const RawAddress& bda,
- tHCI_STATUS status) {}
+ tHCI_STATUS status,
+ bool locally_initiated) {}
void mock_connection_classic_on_disconnected(tHCI_STATUS status,
uint16_t handle,
@@ -141,7 +143,7 @@ void mock_connection_le_on_connected(
tBLE_ADDR_TYPE peer_addr_type) {}
void mock_connection_le_on_failed(const tBLE_BD_ADDR& address_with_type,
uint16_t handle, bool enhanced,
- tHCI_STATUS status) {}
+ tHCI_STATUS status, bool locally_initiated) {}
static std::promise<uint16_t> mock_connection_le_on_disconnected_promise;
void mock_connection_le_on_disconnected(tHCI_STATUS status, uint16_t handle,
tHCI_STATUS reason) {
diff --git a/system/service/adapter.cc b/system/service/adapter.cc
index 19e7400a62..a89477240e 100644
--- a/system/service/adapter.cc
+++ b/system/service/adapter.cc
@@ -692,7 +692,8 @@ class AdapterImpl : public Adapter, public hal::BluetoothInterface::Observer {
void AclStateChangedCallback(bt_status_t status,
const RawAddress& remote_bdaddr,
bt_acl_state_t state, int transport_link_type,
- bt_hci_error_code_t hci_reason) override {
+ bt_hci_error_code_t hci_reason,
+ bt_conn_direction_t direction) override {
std::string device_address = BtAddrString(&remote_bdaddr);
bool connected = (state == BT_ACL_STATE_CONNECTED);
LOG(INFO) << "ACL state changed: " << device_address
diff --git a/system/service/hal/bluetooth_interface.cc b/system/service/hal/bluetooth_interface.cc
index 7167919ec5..01f2ff5714 100644
--- a/system/service/hal/bluetooth_interface.cc
+++ b/system/service/hal/bluetooth_interface.cc
@@ -163,7 +163,8 @@ void LeAddressAssociateCallback(RawAddress* main_bd_addr,
void AclStateChangedCallback(bt_status_t status, RawAddress* remote_bd_addr,
bt_acl_state_t state, int transport_link_type,
- bt_hci_error_code_t hci_reason) {
+ bt_hci_error_code_t hci_reason,
+ bt_conn_direction_t direction) {
shared_lock<shared_mutex_impl> lock(g_instance_lock);
VERIFY_INTERFACE_OR_RETURN();
CHECK(remote_bd_addr);
@@ -172,8 +173,9 @@ void AclStateChangedCallback(bt_status_t status, RawAddress* remote_bd_addr,
<< " - BD_ADDR: " << BtAddrString(remote_bd_addr) << " - state: "
<< ((state == BT_ACL_STATE_CONNECTED) ? "CONNECTED" : "DISCONNECTED")
<< " - HCI_REASON: " << std::to_string(hci_reason);
- FOR_EACH_BLUETOOTH_OBSERVER(AclStateChangedCallback(
- status, *remote_bd_addr, state, transport_link_type, hci_reason));
+ FOR_EACH_BLUETOOTH_OBSERVER(
+ AclStateChangedCallback(status, *remote_bd_addr, state,
+ transport_link_type, hci_reason, direction));
}
void ThreadEventCallback(bt_cb_thread_evt evt) {
@@ -452,7 +454,7 @@ void BluetoothInterface::Observer::BondStateChangedCallback(
void BluetoothInterface::Observer::AclStateChangedCallback(
bt_status_t /* status */, const RawAddress& /* remote_bdaddr */,
bt_acl_state_t /* state */, int /* transport_link_type */,
- bt_hci_error_code_t /* hci_reason */) {
+ bt_hci_error_code_t /* hci_reason */, bt_conn_direction_t /* direction */) {
// Do nothing.
}
diff --git a/system/service/hal/bluetooth_interface.h b/system/service/hal/bluetooth_interface.h
index 10f9c1e1c3..82f9f9c07a 100644
--- a/system/service/hal/bluetooth_interface.h
+++ b/system/service/hal/bluetooth_interface.h
@@ -76,7 +76,8 @@ class BluetoothInterface {
const RawAddress& remote_bdaddr,
bt_acl_state_t state,
int transport_link_type,
- bt_hci_error_code_t hci_reason);
+ bt_hci_error_code_t hci_reason,
+ bt_conn_direction_t direction);
virtual void LinkQualityReportCallback(
uint64_t timestamp, int report_id, int rssi, int snr,
int retransmission_count, int packets_not_receive_count,
diff --git a/system/service/hal/fake_bluetooth_interface.cc b/system/service/hal/fake_bluetooth_interface.cc
index 4635408687..bcd7382b46 100644
--- a/system/service/hal/fake_bluetooth_interface.cc
+++ b/system/service/hal/fake_bluetooth_interface.cc
@@ -157,10 +157,12 @@ void FakeBluetoothInterface::NotifyAdapterLocalLeFeaturesPropertyChanged(
void FakeBluetoothInterface::NotifyAclStateChangedCallback(
bt_status_t status, const RawAddress& remote_bdaddr, bt_acl_state_t state,
- int transport_link_type, bt_hci_error_code_t hci_reason) {
+ int transport_link_type, bt_hci_error_code_t hci_reason,
+ bt_conn_direction_t direction) {
for (auto& observer : observers_) {
observer.AclStateChangedCallback(status, remote_bdaddr, state,
- transport_link_type, hci_reason);
+ transport_link_type, hci_reason,
+ direction);
}
}
diff --git a/system/service/hal/fake_bluetooth_interface.h b/system/service/hal/fake_bluetooth_interface.h
index 08f189a737..9beabe26ce 100644
--- a/system/service/hal/fake_bluetooth_interface.h
+++ b/system/service/hal/fake_bluetooth_interface.h
@@ -62,7 +62,8 @@ class FakeBluetoothInterface : public BluetoothInterface {
const RawAddress& remote_bdaddr,
bt_acl_state_t state,
int transport_link_type,
- bt_hci_error_code_t hci_reason);
+ bt_hci_error_code_t hci_reason,
+ bt_conn_direction_t direction);
// hal::BluetoothInterface overrides:
void AddObserver(Observer* observer) override;
diff --git a/system/service/test/adapter_unittest.cc b/system/service/test/adapter_unittest.cc
index 6c736097dc..c88dc2d6e7 100644
--- a/system/service/test/adapter_unittest.cc
+++ b/system/service/test/adapter_unittest.cc
@@ -262,8 +262,8 @@ TEST_F(AdapterTest, IsDeviceConnected) {
// status != BT_STATUS_SUCCESS should be ignored
fake_hal_iface_->NotifyAclStateChangedCallback(
- BT_STATUS_FAIL, hal_addr, BT_ACL_STATE_CONNECTED, BT_TRANSPORT_LE,
- 0xff); // HCI_ERR_UNDEFINED
+ BT_STATUS_FAIL, hal_addr, BT_ACL_STATE_CONNECTED, BT_TRANSPORT_LE, 0xff,
+ BT_CONN_DIRECTION_OUTGOING); // HCI_ERR_UNDEFINED
EXPECT_FALSE(adapter_->IsDeviceConnected(kDeviceAddr));
EXPECT_TRUE(observer.last_connection_state_address().empty());
EXPECT_FALSE(observer.last_device_connected_state());
@@ -271,7 +271,7 @@ TEST_F(AdapterTest, IsDeviceConnected) {
// Connected
fake_hal_iface_->NotifyAclStateChangedCallback(
BT_STATUS_SUCCESS, hal_addr, BT_ACL_STATE_CONNECTED, BT_TRANSPORT_LE,
- 0x00); // HCI_SUCCESS
+ 0x00, BT_CONN_DIRECTION_OUTGOING); // HCI_SUCCESS
EXPECT_TRUE(adapter_->IsDeviceConnected(kDeviceAddr));
EXPECT_EQ(kDeviceAddr, observer.last_connection_state_address());
EXPECT_TRUE(observer.last_device_connected_state());
@@ -279,7 +279,7 @@ TEST_F(AdapterTest, IsDeviceConnected) {
// Disconnected
fake_hal_iface_->NotifyAclStateChangedCallback(
BT_STATUS_SUCCESS, hal_addr, BT_ACL_STATE_DISCONNECTED, BT_TRANSPORT_LE,
- 0x16); // HCI_ERR_CONN_CAUSE_LOCAL_HOST
+ 0x16, BT_CONN_DIRECTION_OUTGOING); // HCI_ERR_CONN_CAUSE_LOCAL_HOST
EXPECT_FALSE(adapter_->IsDeviceConnected(kDeviceAddr));
EXPECT_EQ(kDeviceAddr, observer.last_connection_state_address());
EXPECT_FALSE(observer.last_device_connected_state());
diff --git a/system/stack/acl/acl.h b/system/stack/acl/acl.h
index 1e65b242cb..97364723e5 100644
--- a/system/stack/acl/acl.h
+++ b/system/stack/acl/acl.h
@@ -396,6 +396,7 @@ struct tACL_CB {
uint16_t btm_acl_pkt_types_supported = kDefaultPacketTypeMask;
uint16_t btm_def_link_policy;
tHCI_STATUS acl_disc_reason = HCI_ERR_UNDEFINED;
+ bool locally_initiated;
public:
void SetDefaultPacketTypeMask(uint16_t packet_type_mask) {
@@ -404,6 +405,8 @@ struct tACL_CB {
tHCI_STATUS get_disconnect_reason() const { return acl_disc_reason; }
void set_disconnect_reason(tHCI_STATUS reason) { acl_disc_reason = reason; }
+ bool is_locally_initiated() const { return locally_initiated; }
+ void set_locally_initiated(bool value) { locally_initiated = value; }
uint16_t DefaultPacketTypes() const { return btm_acl_pkt_types_supported; }
uint16_t DefaultLinkPolicy() const { return btm_def_link_policy; }
diff --git a/system/stack/acl/ble_acl.cc b/system/stack/acl/ble_acl.cc
index ea651d9e2f..e373cc1950 100644
--- a/system/stack/acl/ble_acl.cc
+++ b/system/stack/acl/ble_acl.cc
@@ -131,6 +131,7 @@ void acl_ble_enhanced_connection_complete_from_shim(
const bool is_in_security_db = maybe_resolve_received_address(
address_with_type, &resolved_address_with_type);
+ acl_set_locally_initiated(role == tHCI_ROLE::HCI_ROLE_CENTRAL);
acl_ble_enhanced_connection_complete(resolved_address_with_type, handle, role,
is_in_security_db, conn_interval,
conn_latency, conn_timeout, local_rpa,
@@ -142,8 +143,16 @@ void acl_ble_enhanced_connection_complete_from_shim(
}
void acl_ble_connection_fail(const tBLE_BD_ADDR& address_with_type,
- uint16_t handle, bool enhanced,
- tHCI_STATUS status) {
+ uint16_t handle, bool enhanced, tHCI_STATUS status,
+ bool locally_initiated) {
+ acl_set_locally_initiated(locally_initiated);
+ btm_acl_create_failed(address_with_type.bda, BT_TRANSPORT_LE, status);
+
+ // Stop here if the connection is not locally initiated.
+ if (!locally_initiated) {
+ return;
+ }
+
if (status != HCI_ERR_ADVERTISING_TIMEOUT) {
btm_cb.ble_ctr_cb.set_connection_state_idle();
btm_ble_clear_topology_mask(BTM_BLE_STATE_INIT_BIT);
@@ -161,8 +170,6 @@ void acl_ble_connection_fail(const tBLE_BD_ADDR& address_with_type,
}
btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, &address_with_type.bda,
status);
-
- btm_acl_create_failed(address_with_type.bda, BT_TRANSPORT_LE, status);
}
void gatt_notify_conn_update(const RawAddress& remote, uint16_t interval,
diff --git a/system/stack/acl/btm_acl.cc b/system/stack/acl/btm_acl.cc
index 98bdced377..9831e8cb55 100644
--- a/system/stack/acl/btm_acl.cc
+++ b/system/stack/acl/btm_acl.cc
@@ -1205,6 +1205,20 @@ tHCI_REASON btm_get_acl_disc_reason_code(void) {
/*******************************************************************************
*
+ * Function btm_is_acl_locally_initiated
+ *
+ * Description This function is called to get which side initiates the
+ * connection, at HCI connection complete event.
+ *
+ * Returns true if connection is locally initiated, else false.
+ *
+ ******************************************************************************/
+bool btm_is_acl_locally_initiated(void) {
+ return btm_cb.acl_cb_.is_locally_initiated();
+}
+
+/*******************************************************************************
+ *
* Function BTM_GetHCIConnHandle
*
* Description This function is called to get the handle for an ACL
@@ -2512,6 +2526,10 @@ void acl_set_disconnect_reason(tHCI_STATUS acl_disc_reason) {
btm_cb.acl_cb_.set_disconnect_reason(acl_disc_reason);
}
+void acl_set_locally_initiated(bool locally_initiated) {
+ btm_cb.acl_cb_.set_locally_initiated(locally_initiated);
+}
+
bool acl_is_role_switch_allowed() {
return btm_cb.acl_cb_.DefaultLinkPolicy() &
HCI_ENABLE_CENTRAL_PERIPHERAL_SWITCH;
@@ -2534,7 +2552,7 @@ bool acl_set_peer_le_features_from_handle(uint16_t hci_handle,
}
void on_acl_br_edr_connected(const RawAddress& bda, uint16_t handle,
- uint8_t enc_mode) {
+ uint8_t enc_mode, bool locally_initiated) {
if (delayed_role_change_ != nullptr && delayed_role_change_->bd_addr == bda) {
btm_sec_connected(bda, handle, HCI_SUCCESS, enc_mode,
delayed_role_change_->new_role);
@@ -2554,6 +2572,8 @@ void on_acl_br_edr_connected(const RawAddress& bda, uint16_t handle,
return;
}
+ acl_set_locally_initiated(locally_initiated);
+
/*
* The legacy code path informs the upper layer via the BTA
* layer after all relevant read_remote_ commands are complete.
@@ -2563,7 +2583,8 @@ void on_acl_br_edr_connected(const RawAddress& bda, uint16_t handle,
NotifyAclLinkUp(*p_acl);
}
-void on_acl_br_edr_failed(const RawAddress& bda, tHCI_STATUS status) {
+void on_acl_br_edr_failed(const RawAddress& bda, tHCI_STATUS status,
+ bool locally_initiated) {
ASSERT_LOG(status != HCI_SUCCESS,
"Successful connection entering failing code path");
if (delayed_role_change_ != nullptr && delayed_role_change_->bd_addr == bda) {
@@ -2576,6 +2597,7 @@ void on_acl_br_edr_failed(const RawAddress& bda, tHCI_STATUS status) {
btm_acl_set_paging(false);
l2c_link_hci_conn_comp(status, HCI_INVALID_HANDLE, bda);
+ acl_set_locally_initiated(locally_initiated);
btm_acl_create_failed(bda, BT_TRANSPORT_BR_EDR, status);
}
@@ -2583,9 +2605,10 @@ void btm_acl_connected(const RawAddress& bda, uint16_t handle,
tHCI_STATUS status, uint8_t enc_mode) {
switch (status) {
case HCI_SUCCESS:
- return on_acl_br_edr_connected(bda, handle, enc_mode);
+ return on_acl_br_edr_connected(bda, handle, enc_mode,
+ true /* locally_initiated */);
default:
- return on_acl_br_edr_failed(bda, status);
+ return on_acl_br_edr_failed(bda, status, /* locally_initiated */ true);
}
}
diff --git a/system/stack/include/acl_api.h b/system/stack/include/acl_api.h
index cc7d458782..d296630500 100644
--- a/system/stack/include/acl_api.h
+++ b/system/stack/include/acl_api.h
@@ -251,6 +251,8 @@ uint8_t acl_link_role_from_handle(uint16_t handle);
void acl_set_disconnect_reason(tHCI_STATUS acl_disc_reason);
+void acl_set_locally_initiated(bool is_locally_initiated);
+
bool acl_is_role_switch_allowed();
uint16_t acl_get_supported_packet_types();
@@ -312,6 +314,8 @@ uint8_t btm_handle_to_acl_index(uint16_t hci_handle);
tHCI_REASON btm_get_acl_disc_reason_code(void);
+bool btm_is_acl_locally_initiated(void);
+
extern tBTM_STATUS btm_remove_acl(const RawAddress& bd_addr,
tBT_TRANSPORT transport);
diff --git a/system/stack/include/acl_hci_link_interface.h b/system/stack/include/acl_hci_link_interface.h
index dcd86e30ec..45a8c86f3b 100644
--- a/system/stack/include/acl_hci_link_interface.h
+++ b/system/stack/include/acl_hci_link_interface.h
@@ -33,8 +33,9 @@ void btm_acl_connection_request(const RawAddress& bda, uint8_t* dc);
void btm_acl_connected(const RawAddress& bda, uint16_t handle,
tHCI_STATUS status, uint8_t enc_mode);
void on_acl_br_edr_connected(const RawAddress& bda, uint16_t handle,
- uint8_t enc_mode);
-void on_acl_br_edr_failed(const RawAddress& bda, tHCI_STATUS status);
+ uint8_t enc_mode, bool locally_initiated);
+void on_acl_br_edr_failed(const RawAddress& bda, tHCI_STATUS status,
+ bool locally_initiated);
void btm_acl_disconnected(tHCI_STATUS status, uint16_t handle,
tHCI_STATUS reason);
void btm_acl_iso_disconnected(uint16_t handle, tHCI_STATUS reason);
diff --git a/system/stack/include/ble_acl_interface.h b/system/stack/include/ble_acl_interface.h
index d7c373cee6..e8719691ea 100644
--- a/system/stack/include/ble_acl_interface.h
+++ b/system/stack/include/ble_acl_interface.h
@@ -37,8 +37,8 @@ void acl_ble_enhanced_connection_complete_from_shim(
const RawAddress& local_rpa, const RawAddress& peer_rpa,
tBLE_ADDR_TYPE peer_addr_type);
void acl_ble_connection_fail(const tBLE_BD_ADDR& address_with_type,
- uint16_t handle, bool enhanced,
- tHCI_STATUS status);
+ uint16_t handle, bool enhanced, tHCI_STATUS status,
+ bool locally_initiated);
void acl_ble_update_event_received(tHCI_STATUS status, uint16_t handle,
uint16_t interval, uint16_t latency,
uint16_t timeout);
diff --git a/system/stack/include/hci_error_code.h b/system/stack/include/hci_error_code.h
index c2abb8d340..2ad1a82619 100644
--- a/system/stack/include/hci_error_code.h
+++ b/system/stack/include/hci_error_code.h
@@ -44,6 +44,7 @@ typedef enum : uint8_t {
HCI_ERR_HOST_TIMEOUT = 0x10, // stack/btm/btm_ble_gap,
HCI_ERR_ILLEGAL_PARAMETER_FMT = 0x12,
HCI_ERR_PEER_USER = 0x13,
+ HCI_ERR_REMOTE_LOW_RESOURCE = 0x14,
HCI_ERR_REMOTE_POWER_OFF = 0x15,
HCI_ERR_CONN_CAUSE_LOCAL_HOST = 0x16,
HCI_ERR_REPEATED_ATTEMPTS = 0x17,
diff --git a/system/test/headless/headless.cc b/system/test/headless/headless.cc
index f3ff188327..4489adc41e 100644
--- a/system/test/headless/headless.cc
+++ b/system/test/headless/headless.cc
@@ -117,7 +117,8 @@ void le_address_associate(RawAddress* main_bd_addr,
/** Bluetooth ACL connection state changed callback */
void acl_state_changed(bt_status_t status, RawAddress* remote_bd_addr,
bt_acl_state_t state, int transport_link_type,
- bt_hci_error_code_t hci_reason) {
+ bt_hci_error_code_t hci_reason,
+ bt_conn_direction_t direction) {
auto callback_list = interface_api_callback_map_.at(__func__);
for (auto callback : callback_list) {
interface_data_t params{
@@ -126,6 +127,7 @@ void acl_state_changed(bt_status_t status, RawAddress* remote_bd_addr,
.params.acl_state_changed.remote_bd_addr = remote_bd_addr,
.params.acl_state_changed.state = state,
.params.acl_state_changed.hci_reason = hci_reason,
+ .params.acl_state_changed.direction = direction,
};
(callback)(params);
}
diff --git a/system/test/headless/interface.h b/system/test/headless/interface.h
index 468e5622c4..e39c26acd6 100644
--- a/system/test/headless/interface.h
+++ b/system/test/headless/interface.h
@@ -14,6 +14,7 @@ using acl_state_changed_params_t = struct {
RawAddress* remote_bd_addr;
bt_acl_state_t state;
bt_hci_error_code_t hci_reason;
+ bt_conn_direction_t direction;
};
using callback_params_t = union {
diff --git a/system/test/mock/mock_bluetooth_interface.cc b/system/test/mock/mock_bluetooth_interface.cc
index a80322dde4..ed63b61ab9 100644
--- a/system/test/mock/mock_bluetooth_interface.cc
+++ b/system/test/mock/mock_bluetooth_interface.cc
@@ -262,7 +262,8 @@ void invoke_le_address_associate_cb(RawAddress main_bd_addr,
void invoke_acl_state_changed_cb(bt_status_t status, RawAddress bd_addr,
bt_acl_state_t state, int transport_link_type,
- bt_hci_error_code_t hci_reason) {}
+ bt_hci_error_code_t hci_reason,
+ bt_conn_direction_t direction) {}
void invoke_thread_evt_cb(bt_cb_thread_evt event) {}
diff --git a/system/test/mock/mock_stack_acl.cc b/system/test/mock/mock_stack_acl.cc
index 91ee709ccb..2986960565 100644
--- a/system/test/mock/mock_stack_acl.cc
+++ b/system/test/mock/mock_stack_acl.cc
@@ -87,6 +87,7 @@ struct BTM_SetLinkSuperTout BTM_SetLinkSuperTout;
struct BTM_SwitchRoleToCentral BTM_SwitchRoleToCentral;
struct btm_remove_acl btm_remove_acl;
struct btm_get_acl_disc_reason_code btm_get_acl_disc_reason_code;
+struct btm_is_acl_locally_initiated btm_is_acl_locally_initiated;
struct BTM_GetHCIConnHandle BTM_GetHCIConnHandle;
struct BTM_GetMaxPacketSize BTM_GetMaxPacketSize;
struct BTM_GetNumAclLinks BTM_GetNumAclLinks;
@@ -358,6 +359,10 @@ tHCI_REASON btm_get_acl_disc_reason_code(void) {
mock_function_count_map[__func__]++;
return test::mock::stack_acl::btm_get_acl_disc_reason_code();
}
+bool btm_is_acl_locally_initiated(void) {
+ mock_function_count_map[__func__]++;
+ return test::mock::stack_acl::btm_is_acl_locally_initiated();
+}
uint16_t BTM_GetHCIConnHandle(const RawAddress& remote_bda,
tBT_TRANSPORT transport) {
mock_function_count_map[__func__]++;
@@ -695,13 +700,15 @@ void hci_btm_set_link_supervision_timeout(tACL_CONN& link, uint16_t timeout) {
test::mock::stack_acl::hci_btm_set_link_supervision_timeout(link, timeout);
}
void on_acl_br_edr_connected(const RawAddress& bda, uint16_t handle,
- uint8_t enc_mode) {
+ uint8_t enc_mode, bool locally_initiated) {
mock_function_count_map[__func__]++;
- test::mock::stack_acl::on_acl_br_edr_connected(bda, handle, enc_mode);
+ test::mock::stack_acl::on_acl_br_edr_connected(bda, handle, enc_mode,
+ locally_initiated);
}
-void on_acl_br_edr_failed(const RawAddress& bda, tHCI_STATUS status) {
+void on_acl_br_edr_failed(const RawAddress& bda, tHCI_STATUS status,
+ bool locally_initiated) {
mock_function_count_map[__func__]++;
- test::mock::stack_acl::on_acl_br_edr_failed(bda, status);
+ test::mock::stack_acl::on_acl_br_edr_failed(bda, status, locally_initiated);
}
// END mockcify generation
diff --git a/system/test/mock/mock_stack_acl.h b/system/test/mock/mock_stack_acl.h
index 8747ed7927..db05b80a89 100644
--- a/system/test/mock/mock_stack_acl.h
+++ b/system/test/mock/mock_stack_acl.h
@@ -483,6 +483,14 @@ struct btm_get_acl_disc_reason_code {
tHCI_REASON operator()(void) { return body(); };
};
extern struct btm_get_acl_disc_reason_code btm_get_acl_disc_reason_code;
+// Name: btm_is_acl_locally_initiated
+// Params: void
+// Returns: bool
+struct btm_is_acl_locally_initiated {
+ std::function<bool(void)> body{[](void) { return true; }};
+ bool operator()(void) { return body(); };
+};
+extern struct btm_is_acl_locally_initiated btm_is_acl_locally_initiated;
// Name: BTM_GetHCIConnHandle
// Params: const RawAddress& remote_bda, tBT_TRANSPORT transport
// Returns: uint16_t
@@ -1255,24 +1263,30 @@ struct hci_btm_set_link_supervision_timeout {
extern struct hci_btm_set_link_supervision_timeout
hci_btm_set_link_supervision_timeout;
// Name: on_acl_br_edr_connected
-// Params: const RawAddress& bda, uint16_t handle, uint8_t enc_mode
-// Returns: void
+// Params: const RawAddress& bda, uint16_t handle, uint8_t enc_mode, bool
+// locally_initiated Returns: void
struct on_acl_br_edr_connected {
- std::function<void(const RawAddress& bda, uint16_t handle, uint8_t enc_mode)>
- body{[](const RawAddress& bda, uint16_t handle, uint8_t enc_mode) { ; }};
- void operator()(const RawAddress& bda, uint16_t handle, uint8_t enc_mode) {
- body(bda, handle, enc_mode);
+ std::function<void(const RawAddress& bda, uint16_t handle, uint8_t enc_mode,
+ bool locally_initiated)>
+ body{[](const RawAddress& bda, uint16_t handle, uint8_t enc_mode,
+ bool locally_initiated) { ; }};
+ void operator()(const RawAddress& bda, uint16_t handle, uint8_t enc_mode,
+ bool locally_initiated) {
+ body(bda, handle, enc_mode, locally_initiated);
};
};
extern struct on_acl_br_edr_connected on_acl_br_edr_connected;
// Name: on_acl_br_edr_failed
-// Params: const RawAddress& bda, tHCI_STATUS status
+// Params: const RawAddress& bda, tHCI_STATUS status, bool locally_initiated
// Returns: void
struct on_acl_br_edr_failed {
- std::function<void(const RawAddress& bda, tHCI_STATUS status)> body{
- [](const RawAddress& bda, tHCI_STATUS status) { ; }};
- void operator()(const RawAddress& bda, tHCI_STATUS status) {
- body(bda, status);
+ std::function<void(const RawAddress& bda, tHCI_STATUS status,
+ bool locally_initiated)>
+ body{[](const RawAddress& bda, tHCI_STATUS status,
+ bool locally_initiated) { ; }};
+ void operator()(const RawAddress& bda, tHCI_STATUS status,
+ bool locally_initiated) {
+ body(bda, status, locally_initiated);
};
};
extern struct on_acl_br_edr_failed on_acl_br_edr_failed;
diff --git a/system/test/mock/mock_stack_acl_ble.cc b/system/test/mock/mock_stack_acl_ble.cc
index 7a1925425c..8e87f4d9e0 100644
--- a/system/test/mock/mock_stack_acl_ble.cc
+++ b/system/test/mock/mock_stack_acl_ble.cc
@@ -48,8 +48,8 @@ void acl_ble_connection_complete(const tBLE_BD_ADDR& address_with_type,
mock_function_count_map[__func__]++;
}
void acl_ble_connection_fail(const tBLE_BD_ADDR& address_with_type,
- uint16_t handle, bool enhanced,
- tHCI_STATUS status) {
+ uint16_t handle, bool enhanced, tHCI_STATUS status,
+ bool locally_initiated) {
mock_function_count_map[__func__]++;
}
void acl_ble_enhanced_connection_complete(