• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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