Loading system/gd/hci/remote_name_request.cc +30 −13 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ #include <bluetooth/log.h> #include "hci/acl_manager/acl_scheduler.h" #include "hci/event_checkers.h" #include "hci/hci_layer.h" #include "hci/hci_packets.h" Loading Loading @@ -145,7 +144,7 @@ struct RemoteNameRequestModule::impl { "assert failed: status.GetCommandOpCode() == OpCode::REMOTE_NAME_REQUEST"); log::info( "Started remote name request peer:{} status:{}", address.ToString(), address.ToRedactedStringForLogging(), ErrorCodeText(status.GetStatus())); on_completion.Invoke(status.GetStatus()); if (status.GetStatus() != ErrorCode::SUCCESS /* pending */) { Loading @@ -160,7 +159,7 @@ struct RemoteNameRequestModule::impl { log::info("Cancelling remote name request to {}", address.ToRedactedStringForLogging()); hci_layer_->EnqueueCommand( RemoteNameRequestCancelBuilder::Create(address), handler_->BindOnce(check_complete<RemoteNameRequestCancelCompleteView>)); handler_->BindOnceOn(this, &impl::check_cancel_status, address)); } else { log::info( "Ignoring cancel RNR as RNR event already received to {}", Loading @@ -171,7 +170,7 @@ struct RemoteNameRequestModule::impl { log::info("Cancelling remote name request to {}", address.ToRedactedStringForLogging()); hci_layer_->EnqueueCommand( RemoteNameRequestCancelBuilder::Create(address), handler_->BindOnce(check_complete<RemoteNameRequestCancelCompleteView>)); handler_->BindOnceOn(this, &impl::check_cancel_status, address)); } } Loading @@ -196,20 +195,38 @@ struct RemoteNameRequestModule::impl { } } void on_remote_name_request_complete(EventView view) { auto packet = RemoteNameRequestCompleteView::Create(view); log::assert_that(packet.IsValid(), "assert failed: packet.IsValid()"); void completed(ErrorCode status, std::array<uint8_t, 248> name, Address address) { if (pending_) { log::info( "Received REMOTE_NAME_REQUEST_COMPLETE from {}", packet.GetBdAddr().ToRedactedStringForLogging()); "Received REMOTE_NAME_REQUEST_COMPLETE from {} with status {}", address.ToRedactedStringForLogging(), ErrorCodeText(status)); pending_ = false; on_remote_name_complete_.Invoke(packet.GetStatus(), packet.GetRemoteName()); acl_scheduler_->ReportRemoteNameRequestCompletion(packet.GetBdAddr()); on_remote_name_complete_.Invoke(status, name); acl_scheduler_->ReportRemoteNameRequestCompletion(address); } else { log::error( "Received unexpected REMOTE_NAME_REQUEST_COMPLETE when no Remote Name Request is " "outstanding"); "Received unexpected REMOTE_NAME_REQUEST_COMPLETE from {} with status {}", address.ToRedactedStringForLogging(), ErrorCodeText(status)); } } void on_remote_name_request_complete(EventView view) { auto packet = RemoteNameRequestCompleteView::Create(view); log::assert_that(packet.IsValid(), "Invalid packet"); completed(packet.GetStatus(), packet.GetRemoteName(), packet.GetBdAddr()); } void check_cancel_status(Address remote, CommandCompleteView complete) { auto packet = RemoteNameRequestCancelCompleteView::Create(complete); if (!packet.IsValid()) { completed(ErrorCode::UNSPECIFIED_ERROR, std::array<uint8_t, 248>{}, remote); return; } auto status = packet.GetStatus(); if (status != ErrorCode::SUCCESS) { completed(status, std::array<uint8_t, 248>{}, packet.GetBdAddr()); } } Loading system/gd/hci/remote_name_request_test.cc +30 −0 Original line number Diff line number Diff line Loading @@ -327,6 +327,36 @@ TEST_F(RemoteNameRequestModuleTest, SendCommandThenCancelItCallbackInteropWorkar Eq(std::make_tuple(ErrorCode::UNKNOWN_CONNECTION, std::array<uint8_t, 248>{})))); } TEST_F(RemoteNameRequestModuleTest, SendCommandThenCancelItCancelFails) { auto promise = std::promise<std::tuple<ErrorCode, std::array<uint8_t, 248>>>{}; auto future = promise.get_future(); // start a remote name request remote_name_request_module_->StartRemoteNameRequest( address1, RemoteNameRequestBuilder::Create( address1, PageScanRepetitionMode::R0, 3, ClockOffsetValid::INVALID), emptyCallback<ErrorCode>(), impossibleCallback<uint64_t>(), capturingPromiseCallback<ErrorCode, std::array<uint8_t, 248>>(std::move(promise))); // we successfully start test_hci_layer_->GetCommand(); test_hci_layer_->IncomingEvent(RemoteNameRequestStatusBuilder::Create(ErrorCode::SUCCESS, 1)); // but then the request is cancelled successfully (the status doesn't matter) remote_name_request_module_->CancelRemoteNameRequest(address1); test_hci_layer_->GetCommand(); test_hci_layer_->IncomingEvent(RemoteNameRequestCancelCompleteBuilder::Create( 1, ErrorCode::INVALID_HCI_COMMAND_PARAMETERS, address1)); // we expect the name callback to be invoked nonetheless EXPECT_THAT( future, IsSetWithValue(Eq( std::make_tuple(ErrorCode::INVALID_HCI_COMMAND_PARAMETERS, std::array<uint8_t, 248>{})))); } TEST_F(RemoteNameRequestModuleTest, HostSupportedEvents) { auto promise = std::promise<uint64_t>{}; auto future = promise.get_future(); Loading Loading
system/gd/hci/remote_name_request.cc +30 −13 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ #include <bluetooth/log.h> #include "hci/acl_manager/acl_scheduler.h" #include "hci/event_checkers.h" #include "hci/hci_layer.h" #include "hci/hci_packets.h" Loading Loading @@ -145,7 +144,7 @@ struct RemoteNameRequestModule::impl { "assert failed: status.GetCommandOpCode() == OpCode::REMOTE_NAME_REQUEST"); log::info( "Started remote name request peer:{} status:{}", address.ToString(), address.ToRedactedStringForLogging(), ErrorCodeText(status.GetStatus())); on_completion.Invoke(status.GetStatus()); if (status.GetStatus() != ErrorCode::SUCCESS /* pending */) { Loading @@ -160,7 +159,7 @@ struct RemoteNameRequestModule::impl { log::info("Cancelling remote name request to {}", address.ToRedactedStringForLogging()); hci_layer_->EnqueueCommand( RemoteNameRequestCancelBuilder::Create(address), handler_->BindOnce(check_complete<RemoteNameRequestCancelCompleteView>)); handler_->BindOnceOn(this, &impl::check_cancel_status, address)); } else { log::info( "Ignoring cancel RNR as RNR event already received to {}", Loading @@ -171,7 +170,7 @@ struct RemoteNameRequestModule::impl { log::info("Cancelling remote name request to {}", address.ToRedactedStringForLogging()); hci_layer_->EnqueueCommand( RemoteNameRequestCancelBuilder::Create(address), handler_->BindOnce(check_complete<RemoteNameRequestCancelCompleteView>)); handler_->BindOnceOn(this, &impl::check_cancel_status, address)); } } Loading @@ -196,20 +195,38 @@ struct RemoteNameRequestModule::impl { } } void on_remote_name_request_complete(EventView view) { auto packet = RemoteNameRequestCompleteView::Create(view); log::assert_that(packet.IsValid(), "assert failed: packet.IsValid()"); void completed(ErrorCode status, std::array<uint8_t, 248> name, Address address) { if (pending_) { log::info( "Received REMOTE_NAME_REQUEST_COMPLETE from {}", packet.GetBdAddr().ToRedactedStringForLogging()); "Received REMOTE_NAME_REQUEST_COMPLETE from {} with status {}", address.ToRedactedStringForLogging(), ErrorCodeText(status)); pending_ = false; on_remote_name_complete_.Invoke(packet.GetStatus(), packet.GetRemoteName()); acl_scheduler_->ReportRemoteNameRequestCompletion(packet.GetBdAddr()); on_remote_name_complete_.Invoke(status, name); acl_scheduler_->ReportRemoteNameRequestCompletion(address); } else { log::error( "Received unexpected REMOTE_NAME_REQUEST_COMPLETE when no Remote Name Request is " "outstanding"); "Received unexpected REMOTE_NAME_REQUEST_COMPLETE from {} with status {}", address.ToRedactedStringForLogging(), ErrorCodeText(status)); } } void on_remote_name_request_complete(EventView view) { auto packet = RemoteNameRequestCompleteView::Create(view); log::assert_that(packet.IsValid(), "Invalid packet"); completed(packet.GetStatus(), packet.GetRemoteName(), packet.GetBdAddr()); } void check_cancel_status(Address remote, CommandCompleteView complete) { auto packet = RemoteNameRequestCancelCompleteView::Create(complete); if (!packet.IsValid()) { completed(ErrorCode::UNSPECIFIED_ERROR, std::array<uint8_t, 248>{}, remote); return; } auto status = packet.GetStatus(); if (status != ErrorCode::SUCCESS) { completed(status, std::array<uint8_t, 248>{}, packet.GetBdAddr()); } } Loading
system/gd/hci/remote_name_request_test.cc +30 −0 Original line number Diff line number Diff line Loading @@ -327,6 +327,36 @@ TEST_F(RemoteNameRequestModuleTest, SendCommandThenCancelItCallbackInteropWorkar Eq(std::make_tuple(ErrorCode::UNKNOWN_CONNECTION, std::array<uint8_t, 248>{})))); } TEST_F(RemoteNameRequestModuleTest, SendCommandThenCancelItCancelFails) { auto promise = std::promise<std::tuple<ErrorCode, std::array<uint8_t, 248>>>{}; auto future = promise.get_future(); // start a remote name request remote_name_request_module_->StartRemoteNameRequest( address1, RemoteNameRequestBuilder::Create( address1, PageScanRepetitionMode::R0, 3, ClockOffsetValid::INVALID), emptyCallback<ErrorCode>(), impossibleCallback<uint64_t>(), capturingPromiseCallback<ErrorCode, std::array<uint8_t, 248>>(std::move(promise))); // we successfully start test_hci_layer_->GetCommand(); test_hci_layer_->IncomingEvent(RemoteNameRequestStatusBuilder::Create(ErrorCode::SUCCESS, 1)); // but then the request is cancelled successfully (the status doesn't matter) remote_name_request_module_->CancelRemoteNameRequest(address1); test_hci_layer_->GetCommand(); test_hci_layer_->IncomingEvent(RemoteNameRequestCancelCompleteBuilder::Create( 1, ErrorCode::INVALID_HCI_COMMAND_PARAMETERS, address1)); // we expect the name callback to be invoked nonetheless EXPECT_THAT( future, IsSetWithValue(Eq( std::make_tuple(ErrorCode::INVALID_HCI_COMMAND_PARAMETERS, std::array<uint8_t, 248>{})))); } TEST_F(RemoteNameRequestModuleTest, HostSupportedEvents) { auto promise = std::promise<uint64_t>{}; auto future = promise.get_future(); Loading