Loading system/gd/hci/hci_layer.cc +56 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,42 @@ void on_hci_timeout(OpCode op_code) { } } // namespace class SecurityInterfaceImpl : public SecurityInterface { public: SecurityInterfaceImpl(HciLayer& hci) : hci_(hci) {} virtual ~SecurityInterfaceImpl() = default; virtual void EnqueueCommand(std::unique_ptr<SecurityCommandBuilder> command, common::OnceCallback<void(CommandCompleteView)> on_complete, os::Handler* handler) override { hci_.EnqueueCommand(std::move(command), std::move(on_complete), handler); } virtual void EnqueueCommand(std::unique_ptr<SecurityCommandBuilder> command, common::OnceCallback<void(CommandStatusView)> on_status, os::Handler* handler) override { hci_.EnqueueCommand(std::move(command), std::move(on_status), handler); } HciLayer& hci_; }; class LeSecurityInterfaceImpl : public LeSecurityInterface { public: LeSecurityInterfaceImpl(HciLayer& hci) : hci_(hci) {} virtual ~LeSecurityInterfaceImpl() = default; virtual void EnqueueCommand(std::unique_ptr<LeSecurityCommandBuilder> command, common::OnceCallback<void(CommandCompleteView)> on_complete, os::Handler* handler) override { hci_.EnqueueCommand(std::move(command), std::move(on_complete), handler); } virtual void EnqueueCommand(std::unique_ptr<LeSecurityCommandBuilder> command, common::OnceCallback<void(CommandStatusView)> on_status, os::Handler* handler) override { hci_.EnqueueCommand(std::move(command), std::move(on_status), handler); } HciLayer& hci_; }; struct HciLayer::impl : public hal::HciHalCallbacks { impl(HciLayer& module) : hal_(nullptr), module_(module) {} Loading Loading @@ -349,6 +385,10 @@ struct HciLayer::impl : public hal::HciHalCallbacks { // A reference to the HciLayer module HciLayer& module_; // Interfaces SecurityInterfaceImpl security_interface{module_}; LeSecurityInterfaceImpl le_security_interface{module_}; // Command Handling std::list<CommandQueueEntry> command_queue_; Loading Loading @@ -401,6 +441,22 @@ void HciLayer::UnregisterLeEventHandler(SubeventCode subevent_code) { impl_->UnregisterLeEventHandler(subevent_code); } const SecurityInterface* HciLayer::GetSecurityInterface(common::Callback<void(EventPacketView)> event_handler, os::Handler* handler) { for (const auto event : SecurityInterface::SecurityEvents) { RegisterEventHandler(event, event_handler, handler); } return &impl_->security_interface; } const LeSecurityInterface* HciLayer::GetLeSecurityInterface(common::Callback<void(LeMetaEventView)> event_handler, os::Handler* handler) { for (const auto subevent : LeSecurityInterface::LeSecurityEvents) { RegisterLeEventHandler(subevent, event_handler, handler); } return &impl_->le_security_interface; } const ModuleFactory HciLayer::Factory = ModuleFactory([]() { return new HciLayer(); }); void HciLayer::ListDependencies(ModuleList* list) { Loading system/gd/hci/hci_layer.h +8 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ #include "common/callback.h" #include "hal/hci_hal.h" #include "hci/hci_packets.h" #include "hci/le_security_interface.h" #include "hci/security_interface.h" #include "module.h" #include "os/utils.h" Loading Loading @@ -55,6 +57,12 @@ class HciLayer : public Module { virtual void UnregisterLeEventHandler(SubeventCode subevent_code); const SecurityInterface* GetSecurityInterface(common::Callback<void(EventPacketView)> event_handler, os::Handler* handler); const LeSecurityInterface* GetLeSecurityInterface(common::Callback<void(LeMetaEventView)> event_handler, os::Handler* handler); static const ModuleFactory Factory; void ListDependencies(ModuleList* list) override; Loading system/gd/hci/hci_layer_test.cc +82 −0 Original line number Diff line number Diff line Loading @@ -158,6 +158,26 @@ class DependsOnHci : public Module { GetHandler()); } void SendSecurityCommandExpectingComplete(std::unique_ptr<SecurityCommandBuilder> command) { if (security_interface_ == nullptr) { security_interface_ = hci_->GetSecurityInterface( common::Bind(&DependsOnHci::handle_event<EventPacketView>, common::Unretained(this)), GetHandler()); } hci_->EnqueueCommand(std::move(command), common::Bind(&DependsOnHci::handle_event<CommandCompleteView>, common::Unretained(this)), GetHandler()); } void SendLeSecurityCommandExpectingComplete(std::unique_ptr<LeSecurityCommandBuilder> command) { if (le_security_interface_ == nullptr) { le_security_interface_ = hci_->GetLeSecurityInterface( common::Bind(&DependsOnHci::handle_event<LeMetaEventView>, common::Unretained(this)), GetHandler()); } hci_->EnqueueCommand(std::move(command), common::Bind(&DependsOnHci::handle_event<CommandCompleteView>, common::Unretained(this)), GetHandler()); } void SendAclData(std::unique_ptr<AclPacketBuilder> acl) { outgoing_acl_.push(std::move(acl)); auto queue_end = hci_->GetAclQueueEnd(); Loading Loading @@ -216,6 +236,8 @@ class DependsOnHci : public Module { private: HciLayer* hci_ = nullptr; const SecurityInterface* security_interface_; const LeSecurityInterface* le_security_interface_; std::list<EventPacketView> incoming_events_; std::list<AclPacketView> incoming_acl_packets_; std::unique_ptr<std::promise<void>> event_promise_; Loading Loading @@ -478,6 +500,66 @@ TEST_F(HciTest, creditsTest) { .IsValid()); } TEST_F(HciTest, leSecurityInterfaceTest) { // Send LeRand to the controller auto command_future = hal->GetSentCommandFuture(); upper->SendLeSecurityCommandExpectingComplete(LeRandBuilder::Create()); auto command_sent_status = command_future.wait_for(kTimeout); ASSERT_EQ(command_sent_status, std::future_status::ready); // Check the command auto sent_command = hal->GetSentCommand(); ASSERT_LT(0, sent_command.size()); LeRandView view = LeRandView::Create(LeSecurityCommandView::Create(CommandPacketView::Create(sent_command))); ASSERT_TRUE(view.IsValid()); // Send a Command Complete to the host auto event_future = upper->GetReceivedEventFuture(); uint8_t num_packets = 1; ErrorCode status = ErrorCode::SUCCESS; uint64_t rand = 0x0123456789abcdef; hal->callbacks->hciEventReceived(GetPacketBytes(LeRandCompleteBuilder::Create(num_packets, status, rand))); // Verify the event auto event_status = event_future.wait_for(kTimeout); ASSERT_EQ(event_status, std::future_status::ready); auto event = upper->GetReceivedEvent(); ASSERT_TRUE(event.IsValid()); ASSERT_EQ(EventCode::COMMAND_COMPLETE, event.GetEventCode()); ASSERT_TRUE(LeRandCompleteView::Create(CommandCompleteView::Create(event)).IsValid()); } TEST_F(HciTest, securityInterfacesTest) { // Send WriteSimplePairingMode to the controller auto command_future = hal->GetSentCommandFuture(); Enable enable = Enable::ENABLED; upper->SendSecurityCommandExpectingComplete(WriteSimplePairingModeBuilder::Create(enable)); auto command_sent_status = command_future.wait_for(kTimeout); ASSERT_EQ(command_sent_status, std::future_status::ready); // Check the command auto sent_command = hal->GetSentCommand(); ASSERT_LT(0, sent_command.size()); auto view = WriteSimplePairingModeView::Create(SecurityCommandView::Create(CommandPacketView::Create(sent_command))); ASSERT_TRUE(view.IsValid()); // Send a Command Complete to the host auto event_future = upper->GetReceivedEventFuture(); uint8_t num_packets = 1; ErrorCode status = ErrorCode::SUCCESS; hal->callbacks->hciEventReceived(GetPacketBytes(WriteSimplePairingModeCompleteBuilder::Create(num_packets, status))); // Verify the event auto event_status = event_future.wait_for(kTimeout); ASSERT_EQ(event_status, std::future_status::ready); auto event = upper->GetReceivedEvent(); ASSERT_TRUE(event.IsValid()); ASSERT_EQ(EventCode::COMMAND_COMPLETE, event.GetEventCode()); ASSERT_TRUE(WriteSimplePairingModeCompleteView::Create(CommandCompleteView::Create(event)).IsValid()); } TEST_F(HciTest, createConnectionTest) { // Send CreateConnection to the controller auto command_future = hal->GetSentCommandFuture(); Loading system/gd/hci/hci_packets.pdl +5 −1 Original line number Diff line number Diff line Loading @@ -1936,7 +1936,11 @@ packet LeEncrypt : LeSecurityCommand (op_code = LE_ENCRYPT) { } packet LeRand : LeSecurityCommand (op_code = LE_RAND) { _payload_, // placeholder (unimplemented) } packet LeRandComplete : CommandComplete (command_op_code = LE_RAND) { status : ErrorCode, random_number : 64, } packet LeStartEncryption : LeSecurityCommand (op_code = LE_START_ENCRYPTION) { Loading system/gd/hci/le_security_interface.h 0 → 100644 +45 −0 Original line number Diff line number Diff line /* * 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 "common/callback.h" #include "hci/hci_packets.h" #include "os/utils.h" namespace bluetooth { namespace hci { class LeSecurityInterface { public: LeSecurityInterface() = default; virtual ~LeSecurityInterface() = default; DISALLOW_COPY_AND_ASSIGN(LeSecurityInterface); virtual void EnqueueCommand(std::unique_ptr<LeSecurityCommandBuilder> command, common::OnceCallback<void(CommandCompleteView)> on_complete, os::Handler* handler) = 0; virtual void EnqueueCommand(std::unique_ptr<LeSecurityCommandBuilder> command, common::OnceCallback<void(CommandStatusView)> on_status, os::Handler* handler) = 0; static constexpr hci::SubeventCode LeSecurityEvents[] = { hci::SubeventCode::LONG_TERM_KEY_REQUEST, hci::SubeventCode::READ_LOCAL_P256_PUBLIC_KEY_COMPLETE, hci::SubeventCode::GENERATE_DHKEY_COMPLETE, }; }; } // namespace hci } // namespace bluetooth Loading
system/gd/hci/hci_layer.cc +56 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,42 @@ void on_hci_timeout(OpCode op_code) { } } // namespace class SecurityInterfaceImpl : public SecurityInterface { public: SecurityInterfaceImpl(HciLayer& hci) : hci_(hci) {} virtual ~SecurityInterfaceImpl() = default; virtual void EnqueueCommand(std::unique_ptr<SecurityCommandBuilder> command, common::OnceCallback<void(CommandCompleteView)> on_complete, os::Handler* handler) override { hci_.EnqueueCommand(std::move(command), std::move(on_complete), handler); } virtual void EnqueueCommand(std::unique_ptr<SecurityCommandBuilder> command, common::OnceCallback<void(CommandStatusView)> on_status, os::Handler* handler) override { hci_.EnqueueCommand(std::move(command), std::move(on_status), handler); } HciLayer& hci_; }; class LeSecurityInterfaceImpl : public LeSecurityInterface { public: LeSecurityInterfaceImpl(HciLayer& hci) : hci_(hci) {} virtual ~LeSecurityInterfaceImpl() = default; virtual void EnqueueCommand(std::unique_ptr<LeSecurityCommandBuilder> command, common::OnceCallback<void(CommandCompleteView)> on_complete, os::Handler* handler) override { hci_.EnqueueCommand(std::move(command), std::move(on_complete), handler); } virtual void EnqueueCommand(std::unique_ptr<LeSecurityCommandBuilder> command, common::OnceCallback<void(CommandStatusView)> on_status, os::Handler* handler) override { hci_.EnqueueCommand(std::move(command), std::move(on_status), handler); } HciLayer& hci_; }; struct HciLayer::impl : public hal::HciHalCallbacks { impl(HciLayer& module) : hal_(nullptr), module_(module) {} Loading Loading @@ -349,6 +385,10 @@ struct HciLayer::impl : public hal::HciHalCallbacks { // A reference to the HciLayer module HciLayer& module_; // Interfaces SecurityInterfaceImpl security_interface{module_}; LeSecurityInterfaceImpl le_security_interface{module_}; // Command Handling std::list<CommandQueueEntry> command_queue_; Loading Loading @@ -401,6 +441,22 @@ void HciLayer::UnregisterLeEventHandler(SubeventCode subevent_code) { impl_->UnregisterLeEventHandler(subevent_code); } const SecurityInterface* HciLayer::GetSecurityInterface(common::Callback<void(EventPacketView)> event_handler, os::Handler* handler) { for (const auto event : SecurityInterface::SecurityEvents) { RegisterEventHandler(event, event_handler, handler); } return &impl_->security_interface; } const LeSecurityInterface* HciLayer::GetLeSecurityInterface(common::Callback<void(LeMetaEventView)> event_handler, os::Handler* handler) { for (const auto subevent : LeSecurityInterface::LeSecurityEvents) { RegisterLeEventHandler(subevent, event_handler, handler); } return &impl_->le_security_interface; } const ModuleFactory HciLayer::Factory = ModuleFactory([]() { return new HciLayer(); }); void HciLayer::ListDependencies(ModuleList* list) { Loading
system/gd/hci/hci_layer.h +8 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ #include "common/callback.h" #include "hal/hci_hal.h" #include "hci/hci_packets.h" #include "hci/le_security_interface.h" #include "hci/security_interface.h" #include "module.h" #include "os/utils.h" Loading Loading @@ -55,6 +57,12 @@ class HciLayer : public Module { virtual void UnregisterLeEventHandler(SubeventCode subevent_code); const SecurityInterface* GetSecurityInterface(common::Callback<void(EventPacketView)> event_handler, os::Handler* handler); const LeSecurityInterface* GetLeSecurityInterface(common::Callback<void(LeMetaEventView)> event_handler, os::Handler* handler); static const ModuleFactory Factory; void ListDependencies(ModuleList* list) override; Loading
system/gd/hci/hci_layer_test.cc +82 −0 Original line number Diff line number Diff line Loading @@ -158,6 +158,26 @@ class DependsOnHci : public Module { GetHandler()); } void SendSecurityCommandExpectingComplete(std::unique_ptr<SecurityCommandBuilder> command) { if (security_interface_ == nullptr) { security_interface_ = hci_->GetSecurityInterface( common::Bind(&DependsOnHci::handle_event<EventPacketView>, common::Unretained(this)), GetHandler()); } hci_->EnqueueCommand(std::move(command), common::Bind(&DependsOnHci::handle_event<CommandCompleteView>, common::Unretained(this)), GetHandler()); } void SendLeSecurityCommandExpectingComplete(std::unique_ptr<LeSecurityCommandBuilder> command) { if (le_security_interface_ == nullptr) { le_security_interface_ = hci_->GetLeSecurityInterface( common::Bind(&DependsOnHci::handle_event<LeMetaEventView>, common::Unretained(this)), GetHandler()); } hci_->EnqueueCommand(std::move(command), common::Bind(&DependsOnHci::handle_event<CommandCompleteView>, common::Unretained(this)), GetHandler()); } void SendAclData(std::unique_ptr<AclPacketBuilder> acl) { outgoing_acl_.push(std::move(acl)); auto queue_end = hci_->GetAclQueueEnd(); Loading Loading @@ -216,6 +236,8 @@ class DependsOnHci : public Module { private: HciLayer* hci_ = nullptr; const SecurityInterface* security_interface_; const LeSecurityInterface* le_security_interface_; std::list<EventPacketView> incoming_events_; std::list<AclPacketView> incoming_acl_packets_; std::unique_ptr<std::promise<void>> event_promise_; Loading Loading @@ -478,6 +500,66 @@ TEST_F(HciTest, creditsTest) { .IsValid()); } TEST_F(HciTest, leSecurityInterfaceTest) { // Send LeRand to the controller auto command_future = hal->GetSentCommandFuture(); upper->SendLeSecurityCommandExpectingComplete(LeRandBuilder::Create()); auto command_sent_status = command_future.wait_for(kTimeout); ASSERT_EQ(command_sent_status, std::future_status::ready); // Check the command auto sent_command = hal->GetSentCommand(); ASSERT_LT(0, sent_command.size()); LeRandView view = LeRandView::Create(LeSecurityCommandView::Create(CommandPacketView::Create(sent_command))); ASSERT_TRUE(view.IsValid()); // Send a Command Complete to the host auto event_future = upper->GetReceivedEventFuture(); uint8_t num_packets = 1; ErrorCode status = ErrorCode::SUCCESS; uint64_t rand = 0x0123456789abcdef; hal->callbacks->hciEventReceived(GetPacketBytes(LeRandCompleteBuilder::Create(num_packets, status, rand))); // Verify the event auto event_status = event_future.wait_for(kTimeout); ASSERT_EQ(event_status, std::future_status::ready); auto event = upper->GetReceivedEvent(); ASSERT_TRUE(event.IsValid()); ASSERT_EQ(EventCode::COMMAND_COMPLETE, event.GetEventCode()); ASSERT_TRUE(LeRandCompleteView::Create(CommandCompleteView::Create(event)).IsValid()); } TEST_F(HciTest, securityInterfacesTest) { // Send WriteSimplePairingMode to the controller auto command_future = hal->GetSentCommandFuture(); Enable enable = Enable::ENABLED; upper->SendSecurityCommandExpectingComplete(WriteSimplePairingModeBuilder::Create(enable)); auto command_sent_status = command_future.wait_for(kTimeout); ASSERT_EQ(command_sent_status, std::future_status::ready); // Check the command auto sent_command = hal->GetSentCommand(); ASSERT_LT(0, sent_command.size()); auto view = WriteSimplePairingModeView::Create(SecurityCommandView::Create(CommandPacketView::Create(sent_command))); ASSERT_TRUE(view.IsValid()); // Send a Command Complete to the host auto event_future = upper->GetReceivedEventFuture(); uint8_t num_packets = 1; ErrorCode status = ErrorCode::SUCCESS; hal->callbacks->hciEventReceived(GetPacketBytes(WriteSimplePairingModeCompleteBuilder::Create(num_packets, status))); // Verify the event auto event_status = event_future.wait_for(kTimeout); ASSERT_EQ(event_status, std::future_status::ready); auto event = upper->GetReceivedEvent(); ASSERT_TRUE(event.IsValid()); ASSERT_EQ(EventCode::COMMAND_COMPLETE, event.GetEventCode()); ASSERT_TRUE(WriteSimplePairingModeCompleteView::Create(CommandCompleteView::Create(event)).IsValid()); } TEST_F(HciTest, createConnectionTest) { // Send CreateConnection to the controller auto command_future = hal->GetSentCommandFuture(); Loading
system/gd/hci/hci_packets.pdl +5 −1 Original line number Diff line number Diff line Loading @@ -1936,7 +1936,11 @@ packet LeEncrypt : LeSecurityCommand (op_code = LE_ENCRYPT) { } packet LeRand : LeSecurityCommand (op_code = LE_RAND) { _payload_, // placeholder (unimplemented) } packet LeRandComplete : CommandComplete (command_op_code = LE_RAND) { status : ErrorCode, random_number : 64, } packet LeStartEncryption : LeSecurityCommand (op_code = LE_START_ENCRYPTION) { Loading
system/gd/hci/le_security_interface.h 0 → 100644 +45 −0 Original line number Diff line number Diff line /* * 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 "common/callback.h" #include "hci/hci_packets.h" #include "os/utils.h" namespace bluetooth { namespace hci { class LeSecurityInterface { public: LeSecurityInterface() = default; virtual ~LeSecurityInterface() = default; DISALLOW_COPY_AND_ASSIGN(LeSecurityInterface); virtual void EnqueueCommand(std::unique_ptr<LeSecurityCommandBuilder> command, common::OnceCallback<void(CommandCompleteView)> on_complete, os::Handler* handler) = 0; virtual void EnqueueCommand(std::unique_ptr<LeSecurityCommandBuilder> command, common::OnceCallback<void(CommandStatusView)> on_status, os::Handler* handler) = 0; static constexpr hci::SubeventCode LeSecurityEvents[] = { hci::SubeventCode::LONG_TERM_KEY_REQUEST, hci::SubeventCode::READ_LOCAL_P256_PUBLIC_KEY_COMPLETE, hci::SubeventCode::GENERATE_DHKEY_COMPLETE, }; }; } // namespace hci } // namespace bluetooth