Merge "gd: Authenticate only if necessary"
diff --git a/gd/hci/acl_manager.cc b/gd/hci/acl_manager.cc
index 7b4ca62..0271854 100644
--- a/gd/hci/acl_manager.cc
+++ b/gd/hci/acl_manager.cc
@@ -209,7 +209,9 @@
Bind(&impl::on_read_remote_version_information_complete, common::Unretained(this)),
handler_);
hci_layer_->RegisterEventHandler(EventCode::ENCRYPTION_CHANGE,
- Bind(&impl::on_read_remote_version_information_complete, common::Unretained(this)),
+ Bind(&impl::on_encryption_change, common::Unretained(this)), handler_);
+ hci_layer_->RegisterEventHandler(EventCode::LINK_SUPERVISION_TIMEOUT_CHANGED,
+ Bind(&impl::on_link_supervision_timeout_changed, common::Unretained(this)),
handler_);
hci_mtu_ = controller_->GetControllerAclPacketLength();
}
@@ -742,15 +744,27 @@
}
void on_read_remote_version_information_complete(EventPacketView packet) {
- LOG_INFO("Called");
+ auto view = ReadRemoteVersionInformationCompleteView::Create(packet);
+ ASSERT_LOG(view.IsValid(), "Read remote version information packet invalid");
+ LOG_INFO("UNIMPLEMENTED called");
}
void on_read_remote_supported_features_complete(EventPacketView packet) {
- LOG_INFO("called");
+ auto view = ReadRemoteSupportedFeaturesCompleteView::Create(packet);
+ ASSERT_LOG(view.IsValid(), "Read remote supported features packet invalid");
+ LOG_INFO("UNIMPLEMENTED called");
}
void on_read_remote_extended_features_complete(EventPacketView packet) {
- LOG_INFO("called");
+ auto view = ReadRemoteExtendedFeaturesCompleteView::Create(packet);
+ ASSERT_LOG(view.IsValid(), "Read remote extended features packet invalid");
+ LOG_INFO("UNIMPLEMENTED called");
+ }
+
+ void on_link_supervision_timeout_changed(EventPacketView packet) {
+ auto view = LinkSupervisionTimeoutChangedView::Create(packet);
+ ASSERT_LOG(view.IsValid(), "Link supervision timeout changed packet invalid");
+ LOG_INFO("UNIMPLEMENTED called");
}
void on_role_discovery_complete(CommandCompleteView view) {
@@ -964,17 +978,17 @@
void on_read_remote_version_information_status(CommandStatusView view) {
ASSERT_LOG(view.IsValid(), "Bad status packet!");
- LOG_INFO("called: %s", hci::ErrorCodeText(view.GetStatus()).c_str());
+ LOG_INFO("UNIMPLEMENTED called: %s", hci::ErrorCodeText(view.GetStatus()).c_str());
}
void on_read_remote_supported_features_status(CommandStatusView view) {
ASSERT_LOG(view.IsValid(), "Bad status packet!");
- LOG_INFO("called: %s", hci::ErrorCodeText(view.GetStatus()).c_str());
+ LOG_INFO("UNIMPLEMENTED called: %s", hci::ErrorCodeText(view.GetStatus()).c_str());
}
void on_read_remote_extended_features_status(CommandStatusView view) {
ASSERT_LOG(view.IsValid(), "Broken");
- LOG_INFO("called: %s", hci::ErrorCodeText(view.GetStatus()).c_str());
+ LOG_INFO("UNIMPLEMENTED called: %s", hci::ErrorCodeText(view.GetStatus()).c_str());
}
void on_read_clock_complete(CommandCompleteView view) {
diff --git a/gd/hci/hci_packets.pdl b/gd/hci/hci_packets.pdl
index 993ea66..1a3db54 100644
--- a/gd/hci/hci_packets.pdl
+++ b/gd/hci/hci_packets.pdl
@@ -699,6 +699,7 @@
UNSPECIFIED_ERROR = 0x1F,
UNSUPPORTED_LMP_OR_LL_PARAMETER = 0x20,
ROLE_CHANGE_NOT_ALLOWED = 0x21,
+ LINK_LAYER_COLLISION = 0x23,
ENCRYPTION_MODE_NOT_ACCEPTABLE = 0x25,
CONTROLLER_BUSY = 0x3A,
}
diff --git a/gd/neighbor/Android.bp b/gd/neighbor/Android.bp
index 2c45ec9..35ec925 100644
--- a/gd/neighbor/Android.bp
+++ b/gd/neighbor/Android.bp
@@ -5,6 +5,7 @@
"discoverability.cc",
"inquiry.cc",
"name.cc",
+ "name_db.cc",
"page.cc",
"scan.cc",
],
diff --git a/gd/neighbor/name.cc b/gd/neighbor/name.cc
index 34fa86b..f373486 100644
--- a/gd/neighbor/name.cc
+++ b/gd/neighbor/name.cc
@@ -41,7 +41,7 @@
os::Handler* handler;
};
-constexpr std::array<uint8_t, 248> kEmptyName{};
+constexpr RemoteName kEmptyName{};
struct NameModule::impl {
void ReadRemoteNameRequest(hci::Address address, hci::PageScanRepetitionMode page_scan_repetition_mode,
@@ -195,6 +195,8 @@
hci::PageScanRepetitionMode page_scan_repetition_mode,
uint16_t clock_offset, hci::ClockOffsetValid clock_offset_valid,
ReadRemoteNameCallback callback, os::Handler* handler) {
+ ASSERT(callback);
+ ASSERT(handler != nullptr);
GetHandler()->Post(common::BindOnce(&NameModule::impl::ReadRemoteNameRequest, common::Unretained(pimpl_.get()),
address, page_scan_repetition_mode, clock_offset, clock_offset_valid,
std::move(callback), handler));
@@ -202,6 +204,8 @@
void neighbor::NameModule::CancelRemoteNameRequest(hci::Address address, CancelRemoteNameCallback callback,
os::Handler* handler) {
+ ASSERT(callback);
+ ASSERT(handler != nullptr);
GetHandler()->Post(common::BindOnce(&NameModule::impl::CancelRemoteNameRequest, common::Unretained(pimpl_.get()),
address, std::move(callback), handler));
}
diff --git a/gd/neighbor/name.h b/gd/neighbor/name.h
index 291e1de..c671ddc 100644
--- a/gd/neighbor/name.h
+++ b/gd/neighbor/name.h
@@ -27,8 +27,8 @@
namespace bluetooth {
namespace neighbor {
-using ReadRemoteNameCallback =
- common::OnceCallback<void(hci::ErrorCode status, hci::Address address, std::array<uint8_t, 248> name)>;
+using RemoteName = std::array<uint8_t, 248>;
+using ReadRemoteNameCallback = common::OnceCallback<void(hci::ErrorCode status, hci::Address address, RemoteName name)>;
using CancelRemoteNameCallback = common::OnceCallback<void(hci::ErrorCode status, hci::Address address)>;
class NameModule : public bluetooth::Module {
diff --git a/gd/neighbor/name_db.cc b/gd/neighbor/name_db.cc
new file mode 100644
index 0000000..e82cc5e
--- /dev/null
+++ b/gd/neighbor/name_db.cc
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2020 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.
+ */
+#define LOG_TAG "bt_gd_neigh"
+
+#include "neighbor/name_db.h"
+
+#include <memory>
+#include <unordered_map>
+#include <utility>
+
+#include "common/bind.h"
+#include "module.h"
+#include "neighbor/name.h"
+#include "os/handler.h"
+#include "os/log.h"
+
+namespace bluetooth {
+namespace neighbor {
+
+namespace {
+struct PendingRemoteNameRead {
+ ReadRemoteNameDbCallback callback_;
+ os::Handler* handler_;
+};
+} // namespace
+
+struct NameDbModule::impl {
+ void ReadRemoteNameRequest(hci::Address address, ReadRemoteNameDbCallback callback, os::Handler* handler);
+
+ bool IsNameCached(hci::Address address) const;
+ RemoteName ReadCachedRemoteName(hci::Address address) const;
+
+ impl(const NameDbModule& module);
+
+ void Start();
+ void Stop();
+
+ private:
+ std::unordered_map<hci::Address, PendingRemoteNameRead> address_to_pending_read_map_;
+ std::unordered_map<hci::Address, RemoteName> address_to_name_map_;
+
+ void OnRemoteNameResponse(hci::ErrorCode status, hci::Address address, RemoteName name);
+
+ neighbor::NameModule* name_module_;
+
+ const NameDbModule& module_;
+ os::Handler* handler_;
+};
+
+const ModuleFactory neighbor::NameDbModule::Factory = ModuleFactory([]() { return new neighbor::NameDbModule(); });
+
+neighbor::NameDbModule::impl::impl(const neighbor::NameDbModule& module) : module_(module) {}
+
+void neighbor::NameDbModule::impl::ReadRemoteNameRequest(hci::Address address, ReadRemoteNameDbCallback callback,
+ os::Handler* handler) {
+ if (address_to_pending_read_map_.find(address) != address_to_pending_read_map_.end()) {
+ LOG_WARN("Already have remote read db in progress and currently can only have one outstanding");
+ return;
+ }
+
+ address_to_pending_read_map_[address] = {std::move(callback), std::move(handler)};
+
+ // TODO(cmanton) Use remote name request defaults for now
+ hci::PageScanRepetitionMode page_scan_repetition_mode = hci::PageScanRepetitionMode::R1;
+ uint16_t clock_offset = 0;
+ hci::ClockOffsetValid clock_offset_valid = hci::ClockOffsetValid::INVALID;
+ name_module_->ReadRemoteNameRequest(
+ address, page_scan_repetition_mode, clock_offset, clock_offset_valid,
+ common::BindOnce(&NameDbModule::impl::OnRemoteNameResponse, common::Unretained(this)), handler_);
+}
+
+void neighbor::NameDbModule::impl::OnRemoteNameResponse(hci::ErrorCode status, hci::Address address, RemoteName name) {
+ ASSERT(address_to_pending_read_map_.find(address) != address_to_pending_read_map_.end());
+ PendingRemoteNameRead callback_handler = std::move(address_to_pending_read_map_.at(address));
+
+ if (status == hci::ErrorCode::SUCCESS) {
+ address_to_name_map_[address] = name;
+ }
+ callback_handler.handler_->Post(
+ common::BindOnce(std::move(callback_handler.callback_), address, status == hci::ErrorCode::SUCCESS));
+}
+
+bool neighbor::NameDbModule::impl::IsNameCached(hci::Address address) const {
+ return address_to_name_map_.count(address) == 1;
+}
+
+RemoteName neighbor::NameDbModule::impl::ReadCachedRemoteName(hci::Address address) const {
+ ASSERT(IsNameCached(address));
+ return address_to_name_map_.at(address);
+}
+
+/**
+ * General API here
+ */
+neighbor::NameDbModule::NameDbModule() : pimpl_(std::make_unique<impl>(*this)) {}
+
+neighbor::NameDbModule::~NameDbModule() {
+ pimpl_.reset();
+}
+
+void neighbor::NameDbModule::ReadRemoteNameRequest(hci::Address address, ReadRemoteNameDbCallback callback,
+ os::Handler* handler) {
+ GetHandler()->Post(common::BindOnce(&NameDbModule::impl::ReadRemoteNameRequest, common::Unretained(pimpl_.get()),
+ address, std::move(callback), handler));
+}
+
+bool neighbor::NameDbModule::IsNameCached(hci::Address address) const {
+ return pimpl_->IsNameCached(address);
+}
+
+RemoteName neighbor::NameDbModule::ReadCachedRemoteName(hci::Address address) const {
+ return pimpl_->ReadCachedRemoteName(address);
+}
+
+void neighbor::NameDbModule::impl::Start() {
+ name_module_ = module_.GetDependency<neighbor::NameModule>();
+ handler_ = module_.GetHandler();
+}
+
+void neighbor::NameDbModule::impl::Stop() {}
+
+/**
+ * Module methods here
+ */
+void neighbor::NameDbModule::ListDependencies(ModuleList* list) {
+ list->add<neighbor::NameModule>();
+}
+
+void neighbor::NameDbModule::Start() {
+ pimpl_->Start();
+}
+
+void neighbor::NameDbModule::Stop() {
+ pimpl_->Stop();
+}
+
+} // namespace neighbor
+} // namespace bluetooth
diff --git a/gd/neighbor/name_db.h b/gd/neighbor/name_db.h
new file mode 100644
index 0000000..010c4941
--- /dev/null
+++ b/gd/neighbor/name_db.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2020 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 <array>
+#include <cstdint>
+#include <memory>
+
+#include "common/bind.h"
+#include "hci/address.h"
+#include "hci/hci_packets.h"
+#include "module.h"
+#include "neighbor/name.h"
+
+namespace bluetooth {
+namespace neighbor {
+
+using ReadRemoteNameDbCallback = common::OnceCallback<void(hci::Address address, bool success)>;
+
+class NameDbModule : public bluetooth::Module {
+ public:
+ void ReadRemoteNameRequest(hci::Address address, ReadRemoteNameDbCallback callback, os::Handler* handler);
+
+ bool IsNameCached(hci::Address address) const;
+ RemoteName ReadCachedRemoteName(hci::Address address) const;
+
+ static const ModuleFactory Factory;
+
+ NameDbModule();
+ ~NameDbModule();
+
+ protected:
+ void ListDependencies(ModuleList* list) override;
+ void Start() override;
+ void Stop() override;
+
+ private:
+ struct impl;
+ std::unique_ptr<impl> pimpl_;
+
+ DISALLOW_COPY_AND_ASSIGN(NameDbModule);
+};
+
+} // namespace neighbor
+} // namespace bluetooth
diff --git a/gd/security/internal/security_manager_impl.cc b/gd/security/internal/security_manager_impl.cc
index f7afa4f..7da6e9c 100644
--- a/gd/security/internal/security_manager_impl.cc
+++ b/gd/security/internal/security_manager_impl.cc
@@ -33,7 +33,8 @@
namespace security {
namespace internal {
-void SecurityManagerImpl::DispatchPairingHandler(record::SecurityRecord& record, bool locally_initiated) {
+void SecurityManagerImpl::DispatchPairingHandler(record::SecurityRecord& record, bool locally_initiated,
+ hci::AuthenticationRequirements authentication_requirements) {
common::OnceCallback<void(hci::Address, PairingResultOrFailure)> callback =
common::BindOnce(&SecurityManagerImpl::OnPairingHandlerComplete, common::Unretained(this));
auto entry = pairing_handler_map_.find(record.GetPseudoAddress().GetAddress());
@@ -58,7 +59,7 @@
record.GetPseudoAddress().GetAddress(), pairing_handler);
pairing_handler_map_.insert(std::move(new_entry));
pairing_handler->Initiate(locally_initiated, pairing::kDefaultIoCapability, pairing::kDefaultOobDataPresent,
- pairing::kDefaultAuthenticationRequirements);
+ authentication_requirements);
}
void SecurityManagerImpl::Init() {
@@ -74,7 +75,7 @@
NotifyDeviceBonded(device);
} else {
// Dispatch pairing handler, if we are calling create we are the initiator
- DispatchPairingHandler(record, true);
+ DispatchPairingHandler(record, true, pairing::kDefaultAuthenticationRequirements);
}
}
@@ -162,26 +163,27 @@
void SecurityManagerImpl::HandleEvent(T packet) {
ASSERT(packet.IsValid());
auto entry = pairing_handler_map_.find(packet.GetBdAddr());
- if (entry != pairing_handler_map_.end()) {
- entry->second->OnReceive(packet);
- } else {
+
+ if (entry == pairing_handler_map_.end()) {
auto bd_addr = packet.GetBdAddr();
auto event_code = packet.GetEventCode();
auto event = hci::EventPacketView::Create(std::move(packet));
ASSERT_LOG(event.IsValid(), "Received invalid packet");
+
const hci::EventCode code = event.GetEventCode();
+ if (code != hci::EventCode::LINK_KEY_REQUEST) {
+ LOG_ERROR("No classic pairing handler for device '%s' ready for command '%hhx' ", bd_addr.ToString().c_str(),
+ event_code);
+ return;
+ }
+
auto record =
security_database_.FindOrCreate(hci::AddressWithType{bd_addr, hci::AddressType::PUBLIC_DEVICE_ADDRESS});
- switch (code) {
- case hci::EventCode::LINK_KEY_REQUEST:
- DispatchPairingHandler(record, true);
- break;
- default:
- LOG_ERROR("No classic pairing handler for device '%s' ready for command '%hhx' ", bd_addr.ToString().c_str(),
- event_code);
- break;
- }
+ auto authentication_requirements = hci::AuthenticationRequirements::NO_BONDING;
+ DispatchPairingHandler(record, true, authentication_requirements);
+ entry = pairing_handler_map_.find(packet.GetBdAddr());
}
+ entry->second->OnReceive(packet);
}
void SecurityManagerImpl::OnHciEventReceived(hci::EventPacketView packet) {
diff --git a/gd/security/internal/security_manager_impl.h b/gd/security/internal/security_manager_impl.h
index cec0971..d38c31a 100644
--- a/gd/security/internal/security_manager_impl.h
+++ b/gd/security/internal/security_manager_impl.h
@@ -133,7 +133,8 @@
template <class T>
void HandleEvent(T packet);
- void DispatchPairingHandler(record::SecurityRecord& record, bool locally_initiated);
+ void DispatchPairingHandler(record::SecurityRecord& record, bool locally_initiated,
+ hci::AuthenticationRequirements authentication_requirements);
void OnL2capRegistrationCompleteLe(l2cap::le::FixedChannelManager::RegistrationResult result,
std::unique_ptr<l2cap::le::FixedChannelService> le_smp_service);
void OnSmpCommandLe();
diff --git a/stack/btm/btm_ble_gap.cc b/stack/btm/btm_ble_gap.cc
index 1e8d455..5ea05f3 100644
--- a/stack/btm/btm_ble_gap.cc
+++ b/stack/btm/btm_ble_gap.cc
@@ -1306,6 +1306,7 @@
/* enable IRK list */
btm_ble_enable_resolving_list_for_platform(BTM_BLE_RL_SCAN);
#endif
+ p_ble_cb->inq_var.scan_type = BTM_BLE_SCAN_MODE_ACTI;
p_ble_cb->inq_var.scan_duplicate_filter = BTM_BLE_DUPLICATE_DISABLE;
status = btm_ble_start_scan();
} else if ((p_ble_cb->inq_var.scan_interval !=
@@ -1893,18 +1894,23 @@
btm_ble_process_adv_addr(bda, &addr_type);
uint16_t event_type;
- if (legacy_evt_type == 0x00) { // ADV_IND;
- event_type = 0x0013;
- } else if (legacy_evt_type == 0x01) { // ADV_DIRECT_IND;
- event_type = 0x0015;
- } else if (legacy_evt_type == 0x02) { // ADV_SCAN_IND;
- event_type = 0x0012;
- } else if (legacy_evt_type == 0x03) { // ADV_NONCONN_IND;
- event_type = 0x0010;
- } else if (legacy_evt_type == 0x04) { // SCAN_RSP;
+ event_type = 1 << BLE_EVT_LEGACY_BIT;
+ if (legacy_evt_type == BTM_BLE_ADV_IND_EVT) {
+ event_type |= (1 << BLE_EVT_CONNECTABLE_BIT)|
+ (1 << BLE_EVT_SCANNABLE_BIT);
+ } else if (legacy_evt_type == BTM_BLE_ADV_DIRECT_IND_EVT) {
+ event_type |= (1 << BLE_EVT_CONNECTABLE_BIT)|
+ (1 << BLE_EVT_DIRECTED_BIT);
+ } else if (legacy_evt_type == BTM_BLE_ADV_SCAN_IND_EVT) {
+ event_type |= (1 << BLE_EVT_SCANNABLE_BIT);
+ } else if (legacy_evt_type == BTM_BLE_ADV_NONCONN_IND_EVT) {
+ event_type = (1 << BLE_EVT_LEGACY_BIT);//0x0010;
+ } else if (legacy_evt_type == BTM_BLE_SCAN_RSP_EVT) { // SCAN_RSP;
// We can't distinguish between "SCAN_RSP to an ADV_IND", and "SCAN_RSP to
// an ADV_SCAN_IND", so always return "SCAN_RSP to an ADV_IND"
- event_type = 0x001B;
+ event_type |= (1 << BLE_EVT_CONNECTABLE_BIT)|
+ (1 << BLE_EVT_SCANNABLE_BIT)|
+ (1 << BLE_EVT_SCAN_RESPONSE_BIT);
} else {
BTM_TRACE_ERROR(
"Malformed LE Advertising Report Event - unsupported "
diff --git a/stack/include/btm_ble_api_types.h b/stack/include/btm_ble_api_types.h
index bf69ed3..6c59a75 100644
--- a/stack/include/btm_ble_api_types.h
+++ b/stack/include/btm_ble_api_types.h
@@ -36,7 +36,11 @@
#define BTM_BLE_NON_CONNECT_EVT 0x03
/* Connectable low duty cycle directed advertising */
#define BTM_BLE_CONNECT_LO_DUTY_DIR_EVT 0x04
-/* 0x00 - 0x05 can be received on adv event type */
+/* 0x00 - 0x04 can be received on adv event type */
+#define BTM_BLE_ADV_IND_EVT 0x00
+#define BTM_BLE_ADV_DIRECT_IND_EVT 0x01
+#define BTM_BLE_ADV_SCAN_IND_EVT 0x02
+#define BTM_BLE_ADV_NONCONN_IND_EVT 0x03
#define BTM_BLE_SCAN_RSP_EVT 0x04
#define BTM_BLE_UNKNOWN_EVT 0xff