• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 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 <optional>
20 #include <queue>
21 #include <unordered_set>
22 #include <variant>
23 
24 #include "hci/acl_manager/acl_scheduler.h"
25 #include "hci/acl_manager/event_checkers.h"
26 #include "hci/hci_layer.h"
27 
28 namespace bluetooth {
29 namespace hci {
30 
31 struct RemoteNameRequestModule::impl {
32  public:
implbluetooth::hci::RemoteNameRequestModule::impl33   impl(const RemoteNameRequestModule& module) : module_(module) {}
34 
Startbluetooth::hci::RemoteNameRequestModule::impl35   void Start() {
36     LOG_INFO("Starting RemoteNameRequestModule");
37     hci_layer_ = module_.GetDependency<HciLayer>();
38     acl_scheduler_ = module_.GetDependency<acl_manager::AclScheduler>();
39     handler_ = module_.GetHandler();
40 
41     hci_layer_->RegisterEventHandler(
42         EventCode::REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION,
43         handler_->BindOn(
44             this, &RemoteNameRequestModule::impl::on_remote_host_supported_features_notification));
45     hci_layer_->RegisterEventHandler(
46         EventCode::REMOTE_NAME_REQUEST_COMPLETE,
47         handler_->BindOn(this, &RemoteNameRequestModule::impl::on_remote_name_request_complete));
48   }
49 
Stopbluetooth::hci::RemoteNameRequestModule::impl50   void Stop() {
51     LOG_INFO("Stopping RemoteNameRequestModule");
52     hci_layer_->UnregisterEventHandler(EventCode::REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION);
53     hci_layer_->UnregisterEventHandler(EventCode::REMOTE_NAME_REQUEST_COMPLETE);
54   }
55 
StartRemoteNameRequestbluetooth::hci::RemoteNameRequestModule::impl56   void StartRemoteNameRequest(
57       Address address,
58       std::unique_ptr<RemoteNameRequestBuilder> request,
59       CompletionCallback on_completion,
60       RemoteHostSupportedFeaturesCallback on_remote_host_supported_features_notification,
61       RemoteNameCallback on_remote_name_complete) {
62     LOG_INFO("Enqueuing remote name request to %s", address.ToRedactedStringForLogging().c_str());
63 
64     // This callback needs to be shared between the *start* callback and the *cancel_completed*
65     // callback, so we refcount it for safety. But since the scheduler guarantees that exactly one
66     // of these callbacks will be invokes, this is safe.
67     auto on_remote_name_complete_ptr =
68         std::make_shared<RemoteNameCallback>(std::move(on_remote_name_complete));
69 
70     acl_scheduler_->EnqueueRemoteNameRequest(
71         address,
72         handler_->BindOnceOn(
73             this,
74             &impl::actually_start_remote_name_request,
75             address,
76             std::move(request),
77             std::move(on_completion),
78             std::move(on_remote_host_supported_features_notification),
79             on_remote_name_complete_ptr),
80         handler_->BindOnce(
81             [&](Address address, std::shared_ptr<RemoteNameCallback> on_remote_name_complete_ptr) {
82               LOG_INFO(
83                   "Dequeued remote name request to %s since it was cancelled",
84                   address.ToRedactedStringForLogging().c_str());
85               on_remote_name_complete_ptr->Invoke(ErrorCode::PAGE_TIMEOUT, {});
86             },
87             address,
88             on_remote_name_complete_ptr));
89   }
90 
CancelRemoteNameRequestbluetooth::hci::RemoteNameRequestModule::impl91   void CancelRemoteNameRequest(Address address) {
92     LOG_INFO(
93         "Enqueuing cancel of remote name request to %s",
94         address.ToRedactedStringForLogging().c_str());
95     acl_scheduler_->CancelRemoteNameRequest(
96         address, handler_->BindOnceOn(this, &impl::actually_cancel_remote_name_request, address));
97   }
98 
ReportRemoteNameRequestCancellationbluetooth::hci::RemoteNameRequestModule::impl99   void ReportRemoteNameRequestCancellation(Address address) {
100     if (pending_) {
101       LOG_INFO(
102           "Received CONNECTION_COMPLETE (corresponding INCORRECTLY to an RNR cancellation) from %s",
103           address.ToRedactedStringForLogging().c_str());
104       pending_ = false;
105       on_remote_name_complete_.Invoke(ErrorCode::UNKNOWN_CONNECTION, {});
106       acl_scheduler_->ReportRemoteNameRequestCompletion(address);
107     } else {
108       LOG_ERROR(
109           "Received unexpected CONNECTION_COMPLETE when no Remote Name Request OR ACL connection "
110           "is outstanding");
111     }
112   }
113 
114  private:
actually_start_remote_name_requestbluetooth::hci::RemoteNameRequestModule::impl115   void actually_start_remote_name_request(
116       Address address,
117       std::unique_ptr<RemoteNameRequestBuilder> request,
118       CompletionCallback on_completion,
119       RemoteHostSupportedFeaturesCallback on_remote_host_supported_features_notification,
120       std::shared_ptr<RemoteNameCallback> on_remote_name_complete_ptr) {
121     LOG_INFO("Starting remote name request to %s", address.ToRedactedStringForLogging().c_str());
122     ASSERT(pending_ == false);
123     pending_ = true;
124     on_remote_host_supported_features_notification_ =
125         std::move(on_remote_host_supported_features_notification);
126     on_remote_name_complete_ = std::move(*on_remote_name_complete_ptr.get());
127     hci_layer_->EnqueueCommand(
128         std::move(request),
129         handler_->BindOnceOn(
130             this, &impl::on_start_remote_name_request_status, address, std::move(on_completion)));
131   }
132 
on_start_remote_name_request_statusbluetooth::hci::RemoteNameRequestModule::impl133   void on_start_remote_name_request_status(
134       Address address, CompletionCallback on_completion, CommandStatusView status) {
135     ASSERT(pending_ == true);
136     ASSERT(status.GetCommandOpCode() == OpCode::REMOTE_NAME_REQUEST);
137     LOG_INFO(
138         "Got status %hhu when starting remote name request to to %s",
139         status.GetStatus(),
140         address.ToString().c_str());
141     on_completion.Invoke(status.GetStatus());
142     if (status.GetStatus() != ErrorCode::SUCCESS /* pending */) {
143       pending_ = false;
144       acl_scheduler_->ReportRemoteNameRequestCompletion(address);
145     }
146   }
147 
actually_cancel_remote_name_requestbluetooth::hci::RemoteNameRequestModule::impl148   void actually_cancel_remote_name_request(Address address) {
149     ASSERT(pending_ == true);
150     LOG_INFO("Cancelling remote name request to %s", address.ToRedactedStringForLogging().c_str());
151     hci_layer_->EnqueueCommand(
152         RemoteNameRequestCancelBuilder::Create(address),
153         handler_->BindOnce(
154             &acl_manager::check_command_complete<RemoteNameRequestCancelCompleteView>));
155   }
156 
on_remote_host_supported_features_notificationbluetooth::hci::RemoteNameRequestModule::impl157   void on_remote_host_supported_features_notification(EventView view) {
158     auto packet = RemoteHostSupportedFeaturesNotificationView::Create(view);
159     ASSERT(packet.IsValid());
160     if (pending_) {
161       LOG_INFO(
162           "Received REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION from %s",
163           packet.GetBdAddr().ToRedactedStringForLogging().c_str());
164       on_remote_host_supported_features_notification_.Invoke(packet.GetHostSupportedFeatures());
165     } else {
166       LOG_ERROR(
167           "Received unexpected REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION when no Remote Name "
168           "Request is outstanding");
169     }
170   }
171 
on_remote_name_request_completebluetooth::hci::RemoteNameRequestModule::impl172   void on_remote_name_request_complete(EventView view) {
173     auto packet = RemoteNameRequestCompleteView::Create(view);
174     ASSERT(packet.IsValid());
175     if (pending_) {
176       LOG_INFO(
177           "Received REMOTE_NAME_REQUEST_COMPLETE from %s",
178           packet.GetBdAddr().ToRedactedStringForLogging().c_str());
179       pending_ = false;
180       on_remote_name_complete_.Invoke(packet.GetStatus(), packet.GetRemoteName());
181       acl_scheduler_->ReportRemoteNameRequestCompletion(packet.GetBdAddr());
182     } else {
183       LOG_ERROR(
184           "Received unexpected REMOTE_NAME_REQUEST_COMPLETE when no Remote Name Request is "
185           "outstanding");
186     }
187   }
188 
189   const RemoteNameRequestModule& module_;
190   HciLayer* hci_layer_;
191   acl_manager::AclScheduler* acl_scheduler_;
192   os::Handler* handler_;
193 
194   bool pending_ = false;
195   RemoteHostSupportedFeaturesCallback on_remote_host_supported_features_notification_;
196   RemoteNameCallback on_remote_name_complete_;
197 };
198 
199 const ModuleFactory RemoteNameRequestModule::Factory =
__anonac4010980202() 200     ModuleFactory([]() { return new RemoteNameRequestModule(); });
201 
RemoteNameRequestModule()202 RemoteNameRequestModule::RemoteNameRequestModule() : pimpl_(std::make_unique<impl>(*this)){};
203 RemoteNameRequestModule::~RemoteNameRequestModule() = default;
204 
StartRemoteNameRequest(Address address,std::unique_ptr<RemoteNameRequestBuilder> request,CompletionCallback on_completion,RemoteHostSupportedFeaturesCallback on_remote_host_supported_features_notification,RemoteNameCallback on_remote_name_complete)205 void RemoteNameRequestModule::StartRemoteNameRequest(
206     Address address,
207     std::unique_ptr<RemoteNameRequestBuilder> request,
208     CompletionCallback on_completion,
209     RemoteHostSupportedFeaturesCallback on_remote_host_supported_features_notification,
210     RemoteNameCallback on_remote_name_complete) {
211   CallOn(
212       pimpl_.get(),
213       &impl::StartRemoteNameRequest,
214       address,
215       std::move(request),
216       std::move(on_completion),
217       std::move(on_remote_host_supported_features_notification),
218       std::move(on_remote_name_complete));
219 }
220 
CancelRemoteNameRequest(Address address)221 void RemoteNameRequestModule::CancelRemoteNameRequest(Address address) {
222   CallOn(pimpl_.get(), &impl::CancelRemoteNameRequest, address);
223 }
224 
ReportRemoteNameRequestCancellation(Address address)225 void RemoteNameRequestModule::ReportRemoteNameRequestCancellation(Address address) {
226   CallOn(pimpl_.get(), &impl::ReportRemoteNameRequestCancellation, address);
227 }
228 
ListDependencies(ModuleList * list) const229 void RemoteNameRequestModule::ListDependencies(ModuleList* list) const {
230   list->add<HciLayer>();
231   list->add<acl_manager::AclScheduler>();
232 }
233 
Start()234 void RemoteNameRequestModule::Start() {
235   pimpl_->Start();
236 }
237 
Stop()238 void RemoteNameRequestModule::Stop() {
239   pimpl_->Stop();
240 }
241 
242 }  // namespace hci
243 }  // namespace bluetooth