return local_address_;
}
+ virtual void SetLocalAddress(AddressWithType local_address) {
+ local_address_ = local_address;
+ }
+
virtual AddressWithType GetRemoteAddress() const {
return remote_address_;
}
auto peer_address_type = connection_complete.GetPeerAddressType();
auto peer_resolvable_address = connection_complete.GetPeerResolvablePrivateAddress();
AddressWithType remote_address(address, peer_address_type);
- AddressWithType local_address = le_address_manager_->GetCurrentAddress();
if (!peer_resolvable_address.IsEmpty()) {
remote_address = AddressWithType(peer_resolvable_address, AddressType::RANDOM_DEVICE_ADDRESS);
}
common::Unretained(le_client_callbacks_), remote_address, status));
return;
}
+
+ auto role = connection_complete.GetRole();
+ AddressWithType local_address;
+ if (role == hci::Role::MASTER) {
+ local_address = le_address_manager_->GetCurrentAddress();
+ } else {
+ // when accepting connection, we must obtain the address from the advertiser.
+ // When we receive "set terminated event", we associate connection handle with advertiser address
+ local_address = AddressWithType{};
+ }
+
uint16_t conn_interval = connection_complete.GetConnInterval();
uint16_t conn_latency = connection_complete.GetConnLatency();
uint16_t supervision_timeout = connection_complete.GetSupervisionTimeout();
std::forward_as_tuple(remote_address, queue->GetDownEnd(), handler_));
auto& connection_proxy = check_and_get_le_connection(handle);
round_robin_scheduler_->Register(RoundRobinScheduler::ConnectionType::LE, handle, queue);
- auto role = connection_complete.GetRole();
auto do_disconnect =
common::BindOnce(&DisconnectorForLe::handle_disconnect, common::Unretained(disconnector_), handle);
std::unique_ptr<LeAclConnection> connection(new LeAclConnection(std::move(queue), le_acl_connection_interface_,
struct Advertiser {
os::Handler* handler;
+ AddressWithType current_address;
common::Callback<void(Address, AddressType)> scan_callback;
common::Callback<void(ErrorCode, uint8_t, uint8_t)> set_terminated_callback;
};
return num_instances_;
}
+ void register_set_terminated_callback(
+ common::ContextualCallback<void(ErrorCode, uint16_t, hci::AddressWithType)> set_terminated_callback) {
+ set_terminated_callback_ = std::move(set_terminated_callback);
+ }
+
void handle_event(LeMetaEventView event) {
switch (event.GetSubeventCode()) {
case hci::SubeventCode::SCAN_REQUEST_RECEIVED:
LOG_INFO("Dropping invalid advertising event");
return;
}
- registered_handler_->Post(common::BindOnce(set_terminated_callback_, event_view.GetStatus(),
- event_view.GetAdvertisingHandle(),
- event_view.GetNumCompletedExtendedAdvertisingEvents()));
+
+ AddressWithType advertiser_address = advertising_sets_[event_view.GetAdvertisingHandle()].current_address;
+
+ set_terminated_callback_.InvokeIfNotEmpty(
+ event_view.GetStatus(), event_view.GetConnectionHandle(), advertiser_address);
}
AdvertiserId allocate_advertiser() {
advertising_sets_[id].scan_callback = scan_callback;
advertising_sets_[id].set_terminated_callback = set_terminated_callback;
advertising_sets_[id].handler = handler;
+ advertising_sets_[id].current_address = AddressWithType{};
if (!address_manager_registered) {
le_address_manager_->Register(this);
hci::LeMultiAdvtSetScanRespBuilder::Create(config.scan_response, id),
module_handler_->BindOnce(impl::check_status<LeMultiAdvtCompleteView>));
}
+
+ advertising_sets_[id].current_address = le_address_manager_->GetAnotherAddress();
le_advertising_interface_->EnqueueCommand(
- hci::LeMultiAdvtSetRandomAddrBuilder::Create(le_address_manager_->GetAnotherAddress().GetAddress(), id),
+ hci::LeMultiAdvtSetRandomAddrBuilder::Create(advertising_sets_[id].current_address.GetAddress(), id),
module_handler_->BindOnce(impl::check_status<LeMultiAdvtCompleteView>));
if (!paused) {
le_advertising_interface_->EnqueueCommand(
module_handler_->BindOnce(impl::check_status<LeSetExtendedAdvertisingParametersCompleteView>));
}
+ advertising_sets_[id].current_address = le_address_manager_->GetAnotherAddress();
le_advertising_interface_->EnqueueCommand(
hci::LeSetExtendedAdvertisingRandomAddressBuilder::Create(
- id, le_address_manager_->GetAnotherAddress().GetAddress()),
+ id, advertising_sets_[id].current_address.GetAddress()),
module_handler_->BindOnce(impl::check_status<LeSetExtendedAdvertisingRandomAddressCompleteView>));
if (!config.scan_response.empty()) {
le_advertising_interface_->EnqueueCommand(
}
common::Callback<void(Address, AddressType)> scan_callback_;
- common::Callback<void(ErrorCode, uint8_t, uint8_t)> set_terminated_callback_;
+ common::ContextualCallback<void(ErrorCode, uint16_t, hci::AddressWithType)> set_terminated_callback_;
os::Handler* registered_handler_{nullptr};
Module* module_;
os::Handler* module_handler_;
}
void LeAdvertisingManager::RemoveAdvertiser(AdvertiserId id) {
- GetHandler()->Post(common::BindOnce(&impl::remove_advertiser, common::Unretained(pimpl_.get()), id));
+ GetHandler()->CallOn(pimpl_.get(), &impl::remove_advertiser, id);
+}
+
+void LeAdvertisingManager::RegisterSetTerminatedCallback(
+ common::ContextualCallback<void(ErrorCode, uint16_t, hci::AddressWithType)> set_terminated_callback) {
+ GetHandler()->CallOn(pimpl_.get(), &impl::register_set_terminated_callback, set_terminated_callback);
}
} // namespace hci
#include <memory>
+#include "hci/address_with_type.h"
#include "hci/hci_packets.h"
#include "module.h"
void RemoveAdvertiser(AdvertiserId id);
+ virtual void RegisterSetTerminatedCallback(
+ common::ContextualCallback<void(ErrorCode, uint16_t, hci::AddressWithType)> set_terminated_callback);
+
static const ModuleFactory Factory;
protected:
--- /dev/null
+/*
+ * Copyright 2019 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.
+ */
+#pragma once
+
+#include "hci/le_advertising_manager.h"
+
+#include <gmock/gmock.h>
+
+// Unit test interfaces
+namespace bluetooth {
+namespace hci {
+
+struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallback {};
+
+namespace testing {
+
+using hci::AdvertiserId;
+using hci::LeAdvertisingManager;
+
+class MockLeAdvertisingManager : public LeAdvertisingManager {
+ public:
+ MOCK_METHOD(size_t, GetNumberOfAdvertisingInstances, (), (const));
+ MOCK_METHOD(
+ AdvertiserId,
+ CreateAdvertiser,
+ (const AdvertisingConfig&,
+ const common::Callback<void(Address, AddressType)>&,
+ const common::Callback<void(ErrorCode, uint8_t, uint8_t)>&,
+ os::Handler*));
+ MOCK_METHOD(
+ AdvertiserId,
+ ExtendedCreateAdvertiser,
+ (const ExtendedAdvertisingConfig&,
+ const common::Callback<void(Address, AddressType)>&,
+ const common::Callback<void(ErrorCode, uint8_t, uint8_t)>&,
+ os::Handler*));
+ MOCK_METHOD(void, RemoveAdvertiser, (AdvertiserId));
+ MOCK_METHOD(
+ void,
+ RegisterSetTerminatedCallback,
+ (common::ContextualCallback<void(ErrorCode, uint16_t, hci::AddressWithType)>), (override));
+
+};
+
+} // namespace testing
+} // namespace hci
+} // namespace bluetooth
pending_links_.erase(pending_link);
}
+void LinkManager::OnAdvertisingSetTerminated(
+ bluetooth::hci::ErrorCode status, uint16_t connection_handle, hci::AddressWithType advertiser_address) {
+ for (auto& [address, link] : links_) {
+ if (link.GetAclConnection()->GetHandle() == connection_handle) {
+ link.GetAclConnection()->SetLocalAddress(advertiser_address);
+ return;
+ }
+ }
+}
+
void LinkManager::OnDisconnect(bluetooth::hci::AddressWithType address_with_type) {
auto* link = GetLink(address_with_type);
ASSERT_LOG(link != nullptr, "Device %s is disconnected but not in local database",
#include "hci/acl_manager/le_acl_connection.h"
#include "hci/address.h"
#include "hci/address_with_type.h"
+#include "hci/le_advertising_manager.h"
#include "l2cap/internal/parameter_provider.h"
#include "l2cap/internal/scheduler.h"
#include "l2cap/le/fixed_channel_manager.h"
class LinkManager : public hci::acl_manager::LeConnectionCallbacks {
public:
- LinkManager(os::Handler* l2cap_handler, hci::AclManager* acl_manager, FixedChannelServiceManagerImpl* service_manager,
- DynamicChannelServiceManagerImpl* dynamic_service_manager,
- l2cap::internal::ParameterProvider* parameter_provider)
- : l2cap_handler_(l2cap_handler), acl_manager_(acl_manager), fixed_channel_service_manager_(service_manager),
- dynamic_channel_service_manager_(dynamic_service_manager), parameter_provider_(parameter_provider) {
+ LinkManager(
+ os::Handler* l2cap_handler,
+ hci::AclManager* acl_manager,
+ hci::LeAdvertisingManager* le_advertising_manager,
+ FixedChannelServiceManagerImpl* service_manager,
+ DynamicChannelServiceManagerImpl* dynamic_service_manager,
+ l2cap::internal::ParameterProvider* parameter_provider)
+ : l2cap_handler_(l2cap_handler),
+ acl_manager_(acl_manager),
+ le_advertising_manager_(le_advertising_manager),
+ fixed_channel_service_manager_(service_manager),
+ dynamic_channel_service_manager_(dynamic_service_manager),
+ parameter_provider_(parameter_provider) {
acl_manager_->RegisterLeCallbacks(this, l2cap_handler_);
+ le_advertising_manager_->RegisterSetTerminatedCallback(
+ l2cap_handler->BindOn(this, &LinkManager::OnAdvertisingSetTerminated));
}
struct PendingFixedChannelConnection {
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 OnAdvertisingSetTerminated(
+ bluetooth::hci::ErrorCode status, uint16_t connnection_handle, hci::AddressWithType advertiser_address);
// FixedChannelManager methods
// Dependencies
os::Handler* l2cap_handler_;
hci::AclManager* acl_manager_;
+ hci::LeAdvertisingManager* le_advertising_manager_;
FixedChannelServiceManagerImpl* fixed_channel_service_manager_;
DynamicChannelServiceManagerImpl* dynamic_channel_service_manager_;
l2cap::internal::ParameterProvider* parameter_provider_;
#include "common/testing/bind_test_util.h"
#include "hci/acl_manager_mock.h"
#include "hci/address.h"
+#include "hci/le_advertising_manager_mock.h"
#include "l2cap/cid.h"
#include "l2cap/internal/parameter_provider_mock.h"
#include "l2cap/le/fixed_channel_manager.h"
using hci::testing::MockAclManager;
using hci::testing::MockLeAclConnection;
+using hci::testing::MockLeAdvertisingManager;
using l2cap::internal::testing::MockParameterProvider;
using ::testing::_; // Matcher to any value
using ::testing::ByMove;
TEST_F(L2capLeLinkManagerTest, connect_fixed_channel_service_without_acl) {
MockFixedChannelServiceManagerImpl mock_le_fixed_channel_service_manager;
MockAclManager mock_acl_manager;
+ MockLeAdvertisingManager mock_le_advertising_manager;
hci::AddressWithType address_with_type({{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}},
hci::AddressType::RANDOM_DEVICE_ADDRESS);
os::Handler* hci_callback_handler = nullptr;
EXPECT_CALL(mock_acl_manager, RegisterLeCallbacks(_, _))
.WillOnce(DoAll(SaveArg<0>(&hci_le_connection_callbacks), SaveArg<1>(&hci_callback_handler)));
- LinkManager le_link_manager(l2cap_handler_, &mock_acl_manager, &mock_le_fixed_channel_service_manager, nullptr,
- mock_parameter_provider_);
+ EXPECT_CALL(mock_le_advertising_manager, RegisterSetTerminatedCallback(_));
+ LinkManager le_link_manager(
+ l2cap_handler_,
+ &mock_acl_manager,
+ &mock_le_advertising_manager,
+ &mock_le_fixed_channel_service_manager,
+ nullptr,
+ mock_parameter_provider_);
EXPECT_EQ(hci_le_connection_callbacks, &le_link_manager);
EXPECT_EQ(hci_callback_handler, l2cap_handler_);
TEST_F(L2capLeLinkManagerTest, connect_fixed_channel_service_without_acl_with_no_service) {
MockFixedChannelServiceManagerImpl mock_le_fixed_channel_service_manager;
MockAclManager mock_acl_manager;
+ MockLeAdvertisingManager mock_le_advertising_manager;
hci::AddressWithType address_with_type({{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}},
hci::AddressType::PUBLIC_DEVICE_ADDRESS);
os::Handler* hci_callback_handler = nullptr;
EXPECT_CALL(mock_acl_manager, RegisterLeCallbacks(_, _))
.WillOnce(DoAll(SaveArg<0>(&hci_le_connection_callbacks), SaveArg<1>(&hci_callback_handler)));
- LinkManager le_link_manager(l2cap_handler_, &mock_acl_manager, &mock_le_fixed_channel_service_manager, nullptr,
- mock_parameter_provider_);
+ EXPECT_CALL(mock_le_advertising_manager, RegisterSetTerminatedCallback(_));
+ LinkManager le_link_manager(
+ l2cap_handler_,
+ &mock_acl_manager,
+ &mock_le_advertising_manager,
+ &mock_le_fixed_channel_service_manager,
+ nullptr,
+ mock_parameter_provider_);
EXPECT_EQ(hci_le_connection_callbacks, &le_link_manager);
EXPECT_EQ(hci_callback_handler, l2cap_handler_);
TEST_F(L2capLeLinkManagerTest, connect_fixed_channel_service_without_acl_with_hci_failure) {
MockFixedChannelServiceManagerImpl mock_le_fixed_channel_service_manager;
MockAclManager mock_acl_manager;
+ MockLeAdvertisingManager mock_le_advertising_manager;
hci::AddressWithType address_with_type({{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}},
hci::AddressType::RANDOM_DEVICE_ADDRESS);
os::Handler* hci_callback_handler = nullptr;
EXPECT_CALL(mock_acl_manager, RegisterLeCallbacks(_, _))
.WillOnce(DoAll(SaveArg<0>(&hci_le_connection_callbacks), SaveArg<1>(&hci_callback_handler)));
- LinkManager le_link_manager(l2cap_handler_, &mock_acl_manager, &mock_le_fixed_channel_service_manager, nullptr,
- mock_parameter_provider_);
+ EXPECT_CALL(mock_le_advertising_manager, RegisterSetTerminatedCallback(_));
+ LinkManager le_link_manager(
+ l2cap_handler_,
+ &mock_acl_manager,
+ &mock_le_advertising_manager,
+ &mock_le_fixed_channel_service_manager,
+ nullptr,
+ mock_parameter_provider_);
EXPECT_EQ(hci_le_connection_callbacks, &le_link_manager);
EXPECT_EQ(hci_callback_handler, l2cap_handler_);
.WillRepeatedly(Return(kTestIdleDisconnectTimeoutShort));
MockFixedChannelServiceManagerImpl mock_le_fixed_channel_service_manager;
MockAclManager mock_acl_manager;
+ MockLeAdvertisingManager mock_le_advertising_manager;
hci::AddressWithType address_with_type({{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}},
hci::AddressType::RANDOM_DEVICE_ADDRESS);
os::Handler* hci_callback_handler = nullptr;
EXPECT_CALL(mock_acl_manager, RegisterLeCallbacks(_, _))
.WillOnce(DoAll(SaveArg<0>(&hci_le_connection_callbacks), SaveArg<1>(&hci_callback_handler)));
- LinkManager le_link_manager(l2cap_handler_, &mock_acl_manager, &mock_le_fixed_channel_service_manager, nullptr,
- mock_parameter_provider_);
+ EXPECT_CALL(mock_le_advertising_manager, RegisterSetTerminatedCallback(_));
+ LinkManager le_link_manager(
+ l2cap_handler_,
+ &mock_acl_manager,
+ &mock_le_advertising_manager,
+ &mock_le_fixed_channel_service_manager,
+ nullptr,
+ mock_parameter_provider_);
EXPECT_EQ(hci_le_connection_callbacks, &le_link_manager);
EXPECT_EQ(hci_callback_handler, l2cap_handler_);
.WillRepeatedly(Return(kTestIdleDisconnectTimeoutShort));
MockFixedChannelServiceManagerImpl mock_le_fixed_channel_service_manager;
MockAclManager mock_acl_manager;
+ MockLeAdvertisingManager mock_le_advertising_manager;
hci::AddressWithType address_with_type({{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}},
hci::AddressType::RANDOM_DEVICE_ADDRESS);
os::Handler* hci_callback_handler = nullptr;
EXPECT_CALL(mock_acl_manager, RegisterLeCallbacks(_, _))
.WillOnce(DoAll(SaveArg<0>(&hci_le_connection_callbacks), SaveArg<1>(&hci_callback_handler)));
- LinkManager le_link_manager(l2cap_handler_, &mock_acl_manager, &mock_le_fixed_channel_service_manager, nullptr,
- mock_parameter_provider_);
+ EXPECT_CALL(mock_le_advertising_manager, RegisterSetTerminatedCallback(_));
+ LinkManager le_link_manager(
+ l2cap_handler_,
+ &mock_acl_manager,
+ &mock_le_advertising_manager,
+ &mock_le_fixed_channel_service_manager,
+ nullptr,
+ mock_parameter_provider_);
EXPECT_EQ(hci_le_connection_callbacks, &le_link_manager);
EXPECT_EQ(hci_callback_handler, l2cap_handler_);
.WillRepeatedly(Return(kTestIdleDisconnectTimeoutShort));
MockFixedChannelServiceManagerImpl mock_le_fixed_channel_service_manager;
MockAclManager mock_acl_manager;
+ MockLeAdvertisingManager mock_le_advertising_manager;
hci::AddressWithType address_with_type({{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}},
hci::AddressType::PUBLIC_IDENTITY_ADDRESS);
os::Handler* hci_callback_handler = nullptr;
EXPECT_CALL(mock_acl_manager, RegisterLeCallbacks(_, _))
.WillOnce(DoAll(SaveArg<0>(&hci_le_connection_callbacks), SaveArg<1>(&hci_callback_handler)));
- LinkManager le_link_manager(l2cap_handler_, &mock_acl_manager, &mock_le_fixed_channel_service_manager, nullptr,
- mock_parameter_provider_);
+ EXPECT_CALL(mock_le_advertising_manager, RegisterSetTerminatedCallback(_));
+ LinkManager le_link_manager(
+ l2cap_handler_,
+ &mock_acl_manager,
+ &mock_le_advertising_manager,
+ &mock_le_fixed_channel_service_manager,
+ nullptr,
+ mock_parameter_provider_);
EXPECT_EQ(hci_le_connection_callbacks, &le_link_manager);
EXPECT_EQ(hci_callback_handler, l2cap_handler_);
static SecurityEnforcementRejectAllImpl default_security_module_impl_;
struct L2capLeModule::impl {
- impl(os::Handler* l2cap_handler, hci::AclManager* acl_manager)
- : l2cap_handler_(l2cap_handler), acl_manager_(acl_manager) {
+ impl(os::Handler* l2cap_handler, hci::AclManager* acl_manager, hci::LeAdvertisingManager* le_advertising_manager)
+ : l2cap_handler_(l2cap_handler), acl_manager_(acl_manager), le_advertising_manager_(le_advertising_manager) {
dynamic_channel_service_manager_impl_.SetSecurityEnforcementInterface(&default_security_module_impl_);
}
os::Handler* l2cap_handler_;
hci::AclManager* acl_manager_;
+ hci::LeAdvertisingManager* le_advertising_manager_;
l2cap::internal::ParameterProvider parameter_provider_;
internal::FixedChannelServiceManagerImpl fixed_channel_service_manager_impl_{l2cap_handler_};
internal::DynamicChannelServiceManagerImpl dynamic_channel_service_manager_impl_{l2cap_handler_};
- internal::LinkManager link_manager_{l2cap_handler_, acl_manager_, &fixed_channel_service_manager_impl_,
- &dynamic_channel_service_manager_impl_, ¶meter_provider_};
+ internal::LinkManager link_manager_{l2cap_handler_,
+ acl_manager_,
+ le_advertising_manager_,
+ &fixed_channel_service_manager_impl_,
+ &dynamic_channel_service_manager_impl_,
+ ¶meter_provider_};
};
L2capLeModule::L2capLeModule() {}
void L2capLeModule::ListDependencies(ModuleList* list) {
list->add<hci::AclManager>();
+ list->add<hci::LeAdvertisingManager>();
}
void L2capLeModule::Start() {
- pimpl_ = std::make_unique<impl>(GetHandler(), GetDependency<hci::AclManager>());
+ pimpl_ = std::make_unique<impl>(
+ GetHandler(), GetDependency<hci::AclManager>(), GetDependency<hci::LeAdvertisingManager>());
}
void L2capLeModule::Stop() {