1 /*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "remote_name_request.h"
18
19 #include <bluetooth/log.h>
20 #include <com_android_bluetooth_flags.h>
21
22 #include "hci/acl_manager/acl_scheduler.h"
23 #include "hci/hci_layer.h"
24 #include "hci/hci_packets.h"
25
26 namespace bluetooth {
27 namespace hci {
28
29 struct RemoteNameRequestModule::impl {
30 public:
implbluetooth::hci::RemoteNameRequestModule::impl31 impl(const RemoteNameRequestModule& module) : module_(module) {}
32
Startbluetooth::hci::RemoteNameRequestModule::impl33 void Start() {
34 log::info("Starting RemoteNameRequestModule");
35 hci_layer_ = module_.GetDependency<HciLayer>();
36 acl_scheduler_ = module_.GetDependency<acl_manager::AclScheduler>();
37 handler_ = module_.GetHandler();
38
39 hci_layer_->RegisterEventHandler(
40 EventCode::REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION,
41 handler_->BindOn(this, &RemoteNameRequestModule::impl::
42 on_remote_host_supported_features_notification));
43 hci_layer_->RegisterEventHandler(
44 EventCode::REMOTE_NAME_REQUEST_COMPLETE,
45 handler_->BindOn(this,
46 &RemoteNameRequestModule::impl::on_remote_name_request_complete));
47 }
48
Stopbluetooth::hci::RemoteNameRequestModule::impl49 void Stop() {
50 log::info("Stopping RemoteNameRequestModule");
51 hci_layer_->UnregisterEventHandler(EventCode::REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION);
52 hci_layer_->UnregisterEventHandler(EventCode::REMOTE_NAME_REQUEST_COMPLETE);
53 }
54
StartRemoteNameRequestbluetooth::hci::RemoteNameRequestModule::impl55 void StartRemoteNameRequest(
56 Address address, std::unique_ptr<RemoteNameRequestBuilder> request,
57 CompletionCallback on_completion,
58 RemoteHostSupportedFeaturesCallback on_remote_host_supported_features_notification,
59 RemoteNameCallback on_remote_name_complete) {
60 log::info("Enqueuing remote name request to {}", address.ToRedactedStringForLogging());
61
62 // This callback needs to be shared between the *start* callback and the *cancel_completed*
63 // callback, so we refcount it for safety. But since the scheduler guarantees that exactly one
64 // of these callbacks will be invokes, this is safe.
65 auto on_remote_name_complete_ptr =
66 std::make_shared<RemoteNameCallback>(std::move(on_remote_name_complete));
67
68 acl_scheduler_->EnqueueRemoteNameRequest(
69 address,
70 handler_->BindOnceOn(this, &impl::actually_start_remote_name_request, address,
71 std::move(request), std::move(on_completion),
72 std::move(on_remote_host_supported_features_notification),
73 on_remote_name_complete_ptr),
74 handler_->BindOnce(
75 [&](Address address,
76 std::shared_ptr<RemoteNameCallback> on_remote_name_complete_ptr) {
77 log::info("Dequeued remote name request to {} since it was cancelled",
78 address.ToRedactedStringForLogging());
79 (*on_remote_name_complete_ptr)(ErrorCode::PAGE_TIMEOUT, {});
80 },
81 address, on_remote_name_complete_ptr));
82 }
83
CancelRemoteNameRequestbluetooth::hci::RemoteNameRequestModule::impl84 void CancelRemoteNameRequest(Address address) {
85 log::info("Enqueuing cancel of remote name request to {}",
86 address.ToRedactedStringForLogging());
87 acl_scheduler_->CancelRemoteNameRequest(
88 address,
89 handler_->BindOnceOn(this, &impl::actually_cancel_remote_name_request, address));
90 }
91
ReportRemoteNameRequestCancellationbluetooth::hci::RemoteNameRequestModule::impl92 void ReportRemoteNameRequestCancellation(Address address) {
93 if (pending_) {
94 log::info(
95 "Received CONNECTION_COMPLETE (corresponding INCORRECTLY to an RNR cancellation) "
96 "from {}",
97 address.ToRedactedStringForLogging());
98 pending_ = false;
99 on_remote_name_complete_(ErrorCode::UNKNOWN_CONNECTION, {});
100 acl_scheduler_->ReportRemoteNameRequestCompletion(address);
101 } else {
102 log::error(
103 "Received unexpected CONNECTION_COMPLETE when no Remote Name Request OR ACL "
104 "connection is outstanding");
105 }
106 }
107
108 private:
actually_start_remote_name_requestbluetooth::hci::RemoteNameRequestModule::impl109 void actually_start_remote_name_request(
110 Address address, std::unique_ptr<RemoteNameRequestBuilder> request,
111 CompletionCallback on_completion,
112 RemoteHostSupportedFeaturesCallback on_remote_host_supported_features_notification,
113 std::shared_ptr<RemoteNameCallback> on_remote_name_complete_ptr) {
114 log::info("Starting remote name request to {}", address.ToRedactedStringForLogging());
115 log::assert_that(pending_ == false, "assert failed: pending_ == false");
116 pending_ = true;
117 on_remote_host_supported_features_notification_ =
118 std::move(on_remote_host_supported_features_notification);
119 on_remote_name_complete_ = std::move(*on_remote_name_complete_ptr.get());
120 hci_layer_->EnqueueCommand(
121 std::move(request),
122 handler_->BindOnceOn(this, &impl::on_start_remote_name_request_status, address,
123 std::move(on_completion)));
124 }
125
on_start_remote_name_request_statusbluetooth::hci::RemoteNameRequestModule::impl126 void on_start_remote_name_request_status(Address address, CompletionCallback on_completion,
127 CommandStatusView status) {
128 // TODO(b/294961421): Remove the ifdef when firmware fix in place. Realtek controllers
129 // unexpectedly sent a Remote Name Req Complete HCI event without the corresponding HCI command.
130 #ifndef TARGET_FLOSS
131 log::assert_that(pending_ == true, "assert failed: pending_ == true");
132 #else
133 if (pending_ != true) {
134 log::warn("Unexpected remote name response with no request pending");
135 return;
136 }
137 #endif
138 log::assert_that(status.GetCommandOpCode() == OpCode::REMOTE_NAME_REQUEST,
139 "assert failed: status.GetCommandOpCode() == OpCode::REMOTE_NAME_REQUEST");
140 log::info("Started remote name request peer:{} status:{}", address.ToRedactedStringForLogging(),
141 ErrorCodeText(status.GetStatus()));
142 on_completion(status.GetStatus());
143 if (status.GetStatus() != ErrorCode::SUCCESS /* pending */) {
144 pending_ = false;
145 acl_scheduler_->ReportRemoteNameRequestCompletion(address);
146 }
147 }
148
actually_cancel_remote_name_requestbluetooth::hci::RemoteNameRequestModule::impl149 void actually_cancel_remote_name_request(Address address) {
150 if (pending_) {
151 log::info("Cancelling remote name request to {}", address.ToRedactedStringForLogging());
152 hci_layer_->EnqueueCommand(RemoteNameRequestCancelBuilder::Create(address),
153 handler_->BindOnceOn(this, &impl::check_cancel_status, address));
154 } else {
155 log::info("Ignoring cancel RNR as RNR event already received to {}",
156 address.ToRedactedStringForLogging());
157 }
158 }
159
on_remote_host_supported_features_notificationbluetooth::hci::RemoteNameRequestModule::impl160 void on_remote_host_supported_features_notification(EventView view) {
161 auto packet = RemoteHostSupportedFeaturesNotificationView::Create(view);
162 log::assert_that(packet.IsValid(), "assert failed: packet.IsValid()");
163 if (pending_ && on_remote_host_supported_features_notification_) {
164 log::info("Received REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION from {}",
165 packet.GetBdAddr().ToRedactedStringForLogging());
166 on_remote_host_supported_features_notification_(packet.GetHostSupportedFeatures());
167 // Remove the callback so that we won't call it again.
168 on_remote_host_supported_features_notification_ = RemoteHostSupportedFeaturesCallback();
169 } else if (!pending_) {
170 log::error(
171 "Received unexpected REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION when no Remote Name "
172 "Request is outstanding");
173 } else { // callback is not set, which indicates we have processed the feature notification.
174 log::error(
175 "Received more than one REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION during Remote "
176 "Name Request");
177 }
178 }
179
completedbluetooth::hci::RemoteNameRequestModule::impl180 void completed(ErrorCode status, std::array<uint8_t, 248> name, Address address) {
181 if (pending_) {
182 log::info("Received REMOTE_NAME_REQUEST_COMPLETE from {} with status {}",
183 address.ToRedactedStringForLogging(), ErrorCodeText(status));
184 pending_ = false;
185 on_remote_name_complete_(status, name);
186 acl_scheduler_->ReportRemoteNameRequestCompletion(address);
187 } else {
188 log::error("Received unexpected REMOTE_NAME_REQUEST_COMPLETE from {} with status {}",
189 address.ToRedactedStringForLogging(), ErrorCodeText(status));
190 }
191 }
192
on_remote_name_request_completebluetooth::hci::RemoteNameRequestModule::impl193 void on_remote_name_request_complete(EventView view) {
194 auto packet = RemoteNameRequestCompleteView::Create(view);
195 log::assert_that(packet.IsValid(), "Invalid packet");
196 completed(packet.GetStatus(), packet.GetRemoteName(), packet.GetBdAddr());
197 }
198
check_cancel_statusbluetooth::hci::RemoteNameRequestModule::impl199 void check_cancel_status(Address remote, CommandCompleteView complete) {
200 auto packet = RemoteNameRequestCancelCompleteView::Create(complete);
201 if (!packet.IsValid()) {
202 completed(ErrorCode::UNSPECIFIED_ERROR, std::array<uint8_t, 248>{}, remote);
203 return;
204 }
205 auto status = packet.GetStatus();
206 if (status != ErrorCode::SUCCESS) {
207 completed(status, std::array<uint8_t, 248>{}, packet.GetBdAddr());
208 }
209 }
210
211 const RemoteNameRequestModule& module_;
212 HciLayer* hci_layer_;
213 acl_manager::AclScheduler* acl_scheduler_;
214 os::Handler* handler_;
215
216 bool pending_ = false;
217 RemoteHostSupportedFeaturesCallback on_remote_host_supported_features_notification_;
218 RemoteNameCallback on_remote_name_complete_;
219 };
220
221 const ModuleFactory RemoteNameRequestModule::Factory =
__anon0c3699a90202() 222 ModuleFactory([]() { return new RemoteNameRequestModule(); });
223
RemoteNameRequestModule()224 RemoteNameRequestModule::RemoteNameRequestModule() : pimpl_(std::make_unique<impl>(*this)) {}
225 RemoteNameRequestModule::~RemoteNameRequestModule() = default;
226
StartRemoteNameRequest(Address address,std::unique_ptr<RemoteNameRequestBuilder> request,CompletionCallback on_completion,RemoteHostSupportedFeaturesCallback on_remote_host_supported_features_notification,RemoteNameCallback on_remote_name_complete)227 void RemoteNameRequestModule::StartRemoteNameRequest(
228 Address address, std::unique_ptr<RemoteNameRequestBuilder> request,
229 CompletionCallback on_completion,
230 RemoteHostSupportedFeaturesCallback on_remote_host_supported_features_notification,
231 RemoteNameCallback on_remote_name_complete) {
232 CallOn(pimpl_.get(), &impl::StartRemoteNameRequest, address, std::move(request),
233 std::move(on_completion), std::move(on_remote_host_supported_features_notification),
234 std::move(on_remote_name_complete));
235 }
236
CancelRemoteNameRequest(Address address)237 void RemoteNameRequestModule::CancelRemoteNameRequest(Address address) {
238 CallOn(pimpl_.get(), &impl::CancelRemoteNameRequest, address);
239 }
240
ReportRemoteNameRequestCancellation(Address address)241 void RemoteNameRequestModule::ReportRemoteNameRequestCancellation(Address address) {
242 CallOn(pimpl_.get(), &impl::ReportRemoteNameRequestCancellation, address);
243 }
244
ListDependencies(ModuleList * list) const245 void RemoteNameRequestModule::ListDependencies(ModuleList* list) const {
246 list->add<HciLayer>();
247 list->add<acl_manager::AclScheduler>();
248 }
249
Start()250 void RemoteNameRequestModule::Start() { pimpl_->Start(); }
251
Stop()252 void RemoteNameRequestModule::Stop() { pimpl_->Stop(); }
253
254 } // namespace hci
255 } // namespace bluetooth
256