Loading system/gd/hci/hci_layer.cc +1 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ using std::unique_ptr; static void fail_if_reset_complete_not_success(CommandCompleteView complete) { auto reset_complete = ResetCompleteView::Create(complete); ASSERT(reset_complete.IsValid()); LOG_DEBUG("Reset completed with status: %s", ErrorCodeText(ErrorCode::SUCCESS).c_str()); ASSERT(reset_complete.GetStatus() == ErrorCode::SUCCESS); } Loading system/gd/hci/hci_layer_unittest.cc +109 −9 Original line number Diff line number Diff line Loading @@ -37,6 +37,12 @@ using namespace std::chrono_literals; namespace { constexpr size_t kBufSize = 512; constexpr char kOurEventHandlerWasInvoked[] = "Our event handler was invoked."; constexpr char kOurLeEventHandlerWasInvoked[] = "Our LE event handler was invoked."; } // namespace namespace bluetooth { namespace hci { Loading Loading @@ -68,7 +74,7 @@ class TestHciHal : public hal::HciHal { TestHciHal() : hal::HciHal() {} ~TestHciHal() { ASSERT_LOG(callbacks == nullptr, "unregisterIncomingPacketCallback() must be called"); ASSERT(callbacks == nullptr); } void registerIncomingPacketCallback(hal::HciHalCallbacks* callback) override { Loading @@ -81,7 +87,8 @@ class TestHciHal : public hal::HciHal { void sendHciCommand(hal::HciPacket command) override { outgoing_commands_.push_back(std::move(command)); LOG_DEBUG("Enqueued HCI command in HAL."); sent_commands_++; LOG_DEBUG("Enqueued HCI command %d in HAL.", sent_commands_); } void sendScoData(hal::HciPacket data) override {} Loading Loading @@ -111,19 +118,24 @@ class TestHciHal : public hal::HciHal { return outgoing_commands_.size(); } void InjectEvent(std::unique_ptr<packet::BasePacketBuilder> packet) { callbacks->hciEventReceived(GetPacketBytes(std::move(packet))); } std::string ToString() const override { return std::string("TestHciHal"); } void InjectResetCompleteEventWithCode(ErrorCode code) { auto reset_complete = ResetCompleteBuilder::Create(0x01, code); InjectEvent(std::move(reset_complete)); } void InjectEvent(std::unique_ptr<packet::BasePacketBuilder> packet) { callbacks->hciEventReceived(GetPacketBytes(std::move(packet))); } static const ModuleFactory Factory; private: std::list<hal::HciPacket> outgoing_commands_; std::unique_ptr<std::promise<void>> sent_command_promise_; int sent_commands_{0}; }; const ModuleFactory TestHciHal::Factory = ModuleFactory([]() { return new TestHciHal(); }); Loading Loading @@ -152,8 +164,12 @@ class HciLayerTest : public ::testing::Test { } void FailIfResetNotSent() { hci_handler_->BindOnceOn(this, &HciLayerTest::fail_if_reset_not_sent).Invoke(); } void fail_if_reset_not_sent() { std::promise<void> promise; log_capture_->WaitUntilLogContains(&promise, "Enqueued HCI command in HAL."); log_capture_->WaitUntilLogContains(&promise, "Enqueued HCI command 1 in HAL."); auto sent_command = hal_->GetSentCommand(); auto reset_view = ResetView::Create(CommandView::Create(sent_command)); ASSERT_TRUE(reset_view.IsValid()); Loading @@ -177,7 +193,7 @@ TEST_F(HciLayerTest, controller_debug_info_requested_on_hci_timeout) { FakeTimerAdvance(HciLayer::kHciTimeoutMs.count()); std::promise<void> promise; log_capture_->WaitUntilLogContains(&promise, "Enqueued HCI command in HAL."); log_capture_->WaitUntilLogContains(&promise, "Enqueued HCI command 2 in HAL."); auto sent_command = hal_->GetSentCommand(); auto debug_info_view = ControllerDebugInfoView::Create(VendorCommandView::Create(sent_command)); ASSERT_TRUE(debug_info_view.IsValid()); Loading @@ -188,7 +204,7 @@ TEST_F(HciLayerTest, abort_after_hci_restart_timeout) { FakeTimerAdvance(HciLayer::kHciTimeoutMs.count()); std::promise<void> promise; log_capture_->WaitUntilLogContains(&promise, "Enqueued HCI command in HAL."); log_capture_->WaitUntilLogContains(&promise, "Enqueued HCI command 2 in HAL."); auto sent_command = hal_->GetSentCommand(); auto debug_info_view = ControllerDebugInfoView::Create(VendorCommandView::Create(sent_command)); ASSERT_TRUE(debug_info_view.IsValid()); Loading Loading @@ -219,5 +235,89 @@ TEST_F(HciLayerTest, abort_on_root_inflammation_event) { ""); } TEST_F(HciLayerTest, successful_reset) { FailIfResetNotSent(); auto error_code = ErrorCode::SUCCESS; hal_->InjectResetCompleteEventWithCode(error_code); std::promise<void> promise; auto buf = std::make_unique<char[]>(kBufSize); std::snprintf(buf.get(), kBufSize, "Reset completed with status: %s", ErrorCodeText(error_code).c_str()); log_capture_->WaitUntilLogContains(&promise, buf.get()); } TEST_F(HciLayerTest, abort_if_reset_complete_returns_error) { FailIfResetNotSent(); ASSERT_DEATH( { auto error_code = ErrorCode::UNSPECIFIED_ERROR; hal_->InjectResetCompleteEventWithCode(error_code); std::promise<void> promise; auto buf = std::make_unique<char[]>(kBufSize); std::snprintf(buf.get(), kBufSize, "Reset completed with status: %s", ErrorCodeText(error_code).c_str()); log_capture_->WaitUntilLogContains(&promise, buf.get()); }, ""); } TEST_F(HciLayerTest, event_handler_is_invoked) { FailIfResetNotSent(); hci_->UnregisterEventHandler(EventCode::COMMAND_COMPLETE); hci_->RegisterEventHandler(EventCode::COMMAND_COMPLETE, hci_handler_->Bind([](EventView view) { LOG_DEBUG("%s", kOurEventHandlerWasInvoked); })); auto error_code = ErrorCode::SUCCESS; hal_->InjectResetCompleteEventWithCode(error_code); std::promise<void> promise; log_capture_->WaitUntilLogContains(&promise, kOurEventHandlerWasInvoked); } TEST_F(HciLayerTest, le_event_handler_is_invoked) { FailIfResetNotSent(); hci_->RegisterLeEventHandler(SubeventCode::ENHANCED_CONNECTION_COMPLETE, hci_handler_->Bind([](LeMetaEventView view) { LOG_DEBUG("%s", kOurLeEventHandlerWasInvoked); })); hci::Address remote_address; Address::FromString("D0:05:04:03:02:01", remote_address); hal_->InjectEvent(LeEnhancedConnectionCompleteBuilder::Create( ErrorCode::SUCCESS, 0x0041, Role::PERIPHERAL, AddressType::PUBLIC_DEVICE_ADDRESS, remote_address, Address::kEmpty, Address::kEmpty, 0x0024, 0x0000, 0x0011, ClockAccuracy::PPM_30)); std::promise<void> promise; log_capture_->WaitUntilLogContains(&promise, kOurLeEventHandlerWasInvoked); } TEST_F(HciLayerTest, abort_on_second_register_event_handler) { FailIfResetNotSent(); ASSERT_DEATH( { hci_->RegisterEventHandler(EventCode::COMMAND_COMPLETE, hci_handler_->Bind([](EventView view) {})); std::promise<void> promise; log_capture_->WaitUntilLogContains(&promise, "Can not register a second handler for"); }, ""); } TEST_F(HciLayerTest, abort_on_second_register_le_event_handler) { FailIfResetNotSent(); hci_->RegisterLeEventHandler( SubeventCode::ENHANCED_CONNECTION_COMPLETE, hci_handler_->Bind([](LeMetaEventView view) {})); ASSERT_DEATH( { hci_->RegisterLeEventHandler( SubeventCode::ENHANCED_CONNECTION_COMPLETE, hci_handler_->Bind([](LeMetaEventView view) {})); std::promise<void> promise; log_capture_->WaitUntilLogContains(&promise, "Can not register a second handler for"); }, ""); } } // namespace hci } // namespace bluetooth Loading
system/gd/hci/hci_layer.cc +1 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ using std::unique_ptr; static void fail_if_reset_complete_not_success(CommandCompleteView complete) { auto reset_complete = ResetCompleteView::Create(complete); ASSERT(reset_complete.IsValid()); LOG_DEBUG("Reset completed with status: %s", ErrorCodeText(ErrorCode::SUCCESS).c_str()); ASSERT(reset_complete.GetStatus() == ErrorCode::SUCCESS); } Loading
system/gd/hci/hci_layer_unittest.cc +109 −9 Original line number Diff line number Diff line Loading @@ -37,6 +37,12 @@ using namespace std::chrono_literals; namespace { constexpr size_t kBufSize = 512; constexpr char kOurEventHandlerWasInvoked[] = "Our event handler was invoked."; constexpr char kOurLeEventHandlerWasInvoked[] = "Our LE event handler was invoked."; } // namespace namespace bluetooth { namespace hci { Loading Loading @@ -68,7 +74,7 @@ class TestHciHal : public hal::HciHal { TestHciHal() : hal::HciHal() {} ~TestHciHal() { ASSERT_LOG(callbacks == nullptr, "unregisterIncomingPacketCallback() must be called"); ASSERT(callbacks == nullptr); } void registerIncomingPacketCallback(hal::HciHalCallbacks* callback) override { Loading @@ -81,7 +87,8 @@ class TestHciHal : public hal::HciHal { void sendHciCommand(hal::HciPacket command) override { outgoing_commands_.push_back(std::move(command)); LOG_DEBUG("Enqueued HCI command in HAL."); sent_commands_++; LOG_DEBUG("Enqueued HCI command %d in HAL.", sent_commands_); } void sendScoData(hal::HciPacket data) override {} Loading Loading @@ -111,19 +118,24 @@ class TestHciHal : public hal::HciHal { return outgoing_commands_.size(); } void InjectEvent(std::unique_ptr<packet::BasePacketBuilder> packet) { callbacks->hciEventReceived(GetPacketBytes(std::move(packet))); } std::string ToString() const override { return std::string("TestHciHal"); } void InjectResetCompleteEventWithCode(ErrorCode code) { auto reset_complete = ResetCompleteBuilder::Create(0x01, code); InjectEvent(std::move(reset_complete)); } void InjectEvent(std::unique_ptr<packet::BasePacketBuilder> packet) { callbacks->hciEventReceived(GetPacketBytes(std::move(packet))); } static const ModuleFactory Factory; private: std::list<hal::HciPacket> outgoing_commands_; std::unique_ptr<std::promise<void>> sent_command_promise_; int sent_commands_{0}; }; const ModuleFactory TestHciHal::Factory = ModuleFactory([]() { return new TestHciHal(); }); Loading Loading @@ -152,8 +164,12 @@ class HciLayerTest : public ::testing::Test { } void FailIfResetNotSent() { hci_handler_->BindOnceOn(this, &HciLayerTest::fail_if_reset_not_sent).Invoke(); } void fail_if_reset_not_sent() { std::promise<void> promise; log_capture_->WaitUntilLogContains(&promise, "Enqueued HCI command in HAL."); log_capture_->WaitUntilLogContains(&promise, "Enqueued HCI command 1 in HAL."); auto sent_command = hal_->GetSentCommand(); auto reset_view = ResetView::Create(CommandView::Create(sent_command)); ASSERT_TRUE(reset_view.IsValid()); Loading @@ -177,7 +193,7 @@ TEST_F(HciLayerTest, controller_debug_info_requested_on_hci_timeout) { FakeTimerAdvance(HciLayer::kHciTimeoutMs.count()); std::promise<void> promise; log_capture_->WaitUntilLogContains(&promise, "Enqueued HCI command in HAL."); log_capture_->WaitUntilLogContains(&promise, "Enqueued HCI command 2 in HAL."); auto sent_command = hal_->GetSentCommand(); auto debug_info_view = ControllerDebugInfoView::Create(VendorCommandView::Create(sent_command)); ASSERT_TRUE(debug_info_view.IsValid()); Loading @@ -188,7 +204,7 @@ TEST_F(HciLayerTest, abort_after_hci_restart_timeout) { FakeTimerAdvance(HciLayer::kHciTimeoutMs.count()); std::promise<void> promise; log_capture_->WaitUntilLogContains(&promise, "Enqueued HCI command in HAL."); log_capture_->WaitUntilLogContains(&promise, "Enqueued HCI command 2 in HAL."); auto sent_command = hal_->GetSentCommand(); auto debug_info_view = ControllerDebugInfoView::Create(VendorCommandView::Create(sent_command)); ASSERT_TRUE(debug_info_view.IsValid()); Loading Loading @@ -219,5 +235,89 @@ TEST_F(HciLayerTest, abort_on_root_inflammation_event) { ""); } TEST_F(HciLayerTest, successful_reset) { FailIfResetNotSent(); auto error_code = ErrorCode::SUCCESS; hal_->InjectResetCompleteEventWithCode(error_code); std::promise<void> promise; auto buf = std::make_unique<char[]>(kBufSize); std::snprintf(buf.get(), kBufSize, "Reset completed with status: %s", ErrorCodeText(error_code).c_str()); log_capture_->WaitUntilLogContains(&promise, buf.get()); } TEST_F(HciLayerTest, abort_if_reset_complete_returns_error) { FailIfResetNotSent(); ASSERT_DEATH( { auto error_code = ErrorCode::UNSPECIFIED_ERROR; hal_->InjectResetCompleteEventWithCode(error_code); std::promise<void> promise; auto buf = std::make_unique<char[]>(kBufSize); std::snprintf(buf.get(), kBufSize, "Reset completed with status: %s", ErrorCodeText(error_code).c_str()); log_capture_->WaitUntilLogContains(&promise, buf.get()); }, ""); } TEST_F(HciLayerTest, event_handler_is_invoked) { FailIfResetNotSent(); hci_->UnregisterEventHandler(EventCode::COMMAND_COMPLETE); hci_->RegisterEventHandler(EventCode::COMMAND_COMPLETE, hci_handler_->Bind([](EventView view) { LOG_DEBUG("%s", kOurEventHandlerWasInvoked); })); auto error_code = ErrorCode::SUCCESS; hal_->InjectResetCompleteEventWithCode(error_code); std::promise<void> promise; log_capture_->WaitUntilLogContains(&promise, kOurEventHandlerWasInvoked); } TEST_F(HciLayerTest, le_event_handler_is_invoked) { FailIfResetNotSent(); hci_->RegisterLeEventHandler(SubeventCode::ENHANCED_CONNECTION_COMPLETE, hci_handler_->Bind([](LeMetaEventView view) { LOG_DEBUG("%s", kOurLeEventHandlerWasInvoked); })); hci::Address remote_address; Address::FromString("D0:05:04:03:02:01", remote_address); hal_->InjectEvent(LeEnhancedConnectionCompleteBuilder::Create( ErrorCode::SUCCESS, 0x0041, Role::PERIPHERAL, AddressType::PUBLIC_DEVICE_ADDRESS, remote_address, Address::kEmpty, Address::kEmpty, 0x0024, 0x0000, 0x0011, ClockAccuracy::PPM_30)); std::promise<void> promise; log_capture_->WaitUntilLogContains(&promise, kOurLeEventHandlerWasInvoked); } TEST_F(HciLayerTest, abort_on_second_register_event_handler) { FailIfResetNotSent(); ASSERT_DEATH( { hci_->RegisterEventHandler(EventCode::COMMAND_COMPLETE, hci_handler_->Bind([](EventView view) {})); std::promise<void> promise; log_capture_->WaitUntilLogContains(&promise, "Can not register a second handler for"); }, ""); } TEST_F(HciLayerTest, abort_on_second_register_le_event_handler) { FailIfResetNotSent(); hci_->RegisterLeEventHandler( SubeventCode::ENHANCED_CONNECTION_COMPLETE, hci_handler_->Bind([](LeMetaEventView view) {})); ASSERT_DEATH( { hci_->RegisterLeEventHandler( SubeventCode::ENHANCED_CONNECTION_COMPLETE, hci_handler_->Bind([](LeMetaEventView view) {})); std::promise<void> promise; log_capture_->WaitUntilLogContains(&promise, "Can not register a second handler for"); }, ""); } } // namespace hci } // namespace bluetooth