1 /*
2 * Copyright 2019 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 "hci/hci_layer.h"
18
19 #include "common/bind.h"
20 #include "common/init_flags.h"
21 #include "common/stop_watch.h"
22 #include "hci/hci_metrics_logging.h"
23 #include "os/alarm.h"
24 #include "os/metrics.h"
25 #include "os/queue.h"
26 #include "packet/packet_builder.h"
27 #include "storage/storage_module.h"
28
29 namespace bluetooth {
30 namespace hci {
31 using bluetooth::common::BindOn;
32 using bluetooth::common::BindOnce;
33 using bluetooth::common::ContextualCallback;
34 using bluetooth::common::ContextualOnceCallback;
35 using bluetooth::hci::CommandBuilder;
36 using bluetooth::hci::CommandCompleteView;
37 using bluetooth::hci::CommandStatusView;
38 using bluetooth::hci::EventView;
39 using bluetooth::hci::LeMetaEventView;
40 using bluetooth::os::Handler;
41 using common::BidiQueue;
42 using common::BidiQueueEnd;
43 using hci::OpCode;
44 using hci::ResetCompleteView;
45 using os::Alarm;
46 using os::Handler;
47 using std::unique_ptr;
48
fail_if_reset_complete_not_success(CommandCompleteView complete)49 static void fail_if_reset_complete_not_success(CommandCompleteView complete) {
50 auto reset_complete = ResetCompleteView::Create(complete);
51 ASSERT(reset_complete.IsValid());
52 LOG_DEBUG("Reset completed with status: %s", ErrorCodeText(ErrorCode::SUCCESS).c_str());
53 ASSERT(reset_complete.GetStatus() == ErrorCode::SUCCESS);
54 }
55
abort_after_time_out(OpCode op_code)56 static void abort_after_time_out(OpCode op_code) {
57 bluetooth::os::LogMetricHciTimeoutEvent(static_cast<uint32_t>(op_code));
58 ASSERT_LOG(false, "Done waiting for debug information after HCI timeout (%s)", OpCodeText(op_code).c_str());
59 }
60
61 class CommandQueueEntry {
62 public:
CommandQueueEntry(unique_ptr<CommandBuilder> command_packet,ContextualOnceCallback<void (CommandCompleteView)> on_complete_function)63 CommandQueueEntry(
64 unique_ptr<CommandBuilder> command_packet,
65 ContextualOnceCallback<void(CommandCompleteView)> on_complete_function)
66 : command(std::move(command_packet)),
67 waiting_for_status_(false),
68 on_complete(std::move(on_complete_function)) {}
69
CommandQueueEntry(unique_ptr<CommandBuilder> command_packet,ContextualOnceCallback<void (CommandStatusView)> on_status_function)70 CommandQueueEntry(
71 unique_ptr<CommandBuilder> command_packet,
72 ContextualOnceCallback<void(CommandStatusView)> on_status_function)
73 : command(std::move(command_packet)),
74 waiting_for_status_(true),
75 on_status(std::move(on_status_function)) {}
76
77 unique_ptr<CommandBuilder> command;
78 unique_ptr<CommandView> command_view;
79
80 bool waiting_for_status_;
81 ContextualOnceCallback<void(CommandStatusView)> on_status;
82 ContextualOnceCallback<void(CommandCompleteView)> on_complete;
83
84 template <typename TView>
GetCallback()85 ContextualOnceCallback<void(TView)>* GetCallback() {
86 return nullptr;
87 }
88
89 template <>
GetCallback()90 ContextualOnceCallback<void(CommandStatusView)>* GetCallback<CommandStatusView>() {
91 return &on_status;
92 }
93
94 template <>
GetCallback()95 ContextualOnceCallback<void(CommandCompleteView)>* GetCallback<CommandCompleteView>() {
96 return &on_complete;
97 }
98 };
99
100 struct HciLayer::impl {
implbluetooth::hci::HciLayer::impl101 impl(hal::HciHal* hal, HciLayer& module) : hal_(hal), module_(module) {
102 hci_timeout_alarm_ = new Alarm(module.GetHandler());
103 }
104
~implbluetooth::hci::HciLayer::impl105 ~impl() {
106 incoming_acl_buffer_.Clear();
107 incoming_sco_buffer_.Clear();
108 incoming_iso_buffer_.Clear();
109 if (hci_timeout_alarm_ != nullptr) {
110 delete hci_timeout_alarm_;
111 }
112 if (hci_abort_alarm_ != nullptr) {
113 delete hci_abort_alarm_;
114 }
115 command_queue_.clear();
116 }
117
dropbluetooth::hci::HciLayer::impl118 void drop(EventView event) {
119 LOG_INFO("Dropping event %s", EventCodeText(event.GetEventCode()).c_str());
120 }
121
on_outbound_acl_readybluetooth::hci::HciLayer::impl122 void on_outbound_acl_ready() {
123 auto packet = acl_queue_.GetDownEnd()->TryDequeue();
124 std::vector<uint8_t> bytes;
125 BitInserter bi(bytes);
126 packet->Serialize(bi);
127 hal_->sendAclData(bytes);
128 }
129
on_outbound_sco_readybluetooth::hci::HciLayer::impl130 void on_outbound_sco_ready() {
131 auto packet = sco_queue_.GetDownEnd()->TryDequeue();
132 std::vector<uint8_t> bytes;
133 BitInserter bi(bytes);
134 packet->Serialize(bi);
135 hal_->sendScoData(bytes);
136 }
137
on_outbound_iso_readybluetooth::hci::HciLayer::impl138 void on_outbound_iso_ready() {
139 auto packet = iso_queue_.GetDownEnd()->TryDequeue();
140 std::vector<uint8_t> bytes;
141 BitInserter bi(bytes);
142 packet->Serialize(bi);
143 hal_->sendIsoData(bytes);
144 }
145
146 template <typename TResponse>
enqueue_commandbluetooth::hci::HciLayer::impl147 void enqueue_command(unique_ptr<CommandBuilder> command, ContextualOnceCallback<void(TResponse)> on_response) {
148 command_queue_.emplace_back(std::move(command), std::move(on_response));
149 send_next_command();
150 }
151
on_command_statusbluetooth::hci::HciLayer::impl152 void on_command_status(EventView event) {
153 CommandStatusView response_view = CommandStatusView::Create(event);
154 ASSERT(response_view.IsValid());
155 OpCode op_code = response_view.GetCommandOpCode();
156 ErrorCode status = response_view.GetStatus();
157 if (status != ErrorCode::SUCCESS) {
158 LOG_ERROR(
159 "Received UNEXPECTED command status:%s opcode:0x%02hx (%s)",
160 ErrorCodeText(status).c_str(),
161 op_code,
162 OpCodeText(op_code).c_str());
163 }
164 handle_command_response<CommandStatusView>(event, "status");
165 }
166
on_command_completebluetooth::hci::HciLayer::impl167 void on_command_complete(EventView event) {
168 handle_command_response<CommandCompleteView>(event, "complete");
169 }
170
171 template <typename TResponse>
handle_command_responsebluetooth::hci::HciLayer::impl172 void handle_command_response(EventView event, std::string logging_id) {
173 TResponse response_view = TResponse::Create(event);
174 ASSERT(response_view.IsValid());
175 command_credits_ = response_view.GetNumHciCommandPackets();
176 OpCode op_code = response_view.GetCommandOpCode();
177 if (op_code == OpCode::NONE) {
178 send_next_command();
179 return;
180 }
181 bool is_status = logging_id == "status";
182
183 ASSERT_LOG(
184 !command_queue_.empty(),
185 "Unexpected %s event with OpCode 0x%02hx (%s)",
186 logging_id.c_str(),
187 op_code,
188 OpCodeText(op_code).c_str());
189 if (waiting_command_ == OpCode::CONTROLLER_DEBUG_INFO && op_code != OpCode::CONTROLLER_DEBUG_INFO) {
190 LOG_ERROR("Discarding event that came after timeout 0x%02hx (%s)", op_code, OpCodeText(op_code).c_str());
191 return;
192 }
193 ASSERT_LOG(
194 waiting_command_ == op_code,
195 "Waiting for 0x%02hx (%s), got 0x%02hx (%s)",
196 waiting_command_,
197 OpCodeText(waiting_command_).c_str(),
198 op_code,
199 OpCodeText(op_code).c_str());
200
201 bool is_vendor_specific = static_cast<int>(op_code) & (0x3f << 10);
202 CommandStatusView status_view = CommandStatusView::Create(event);
203 if (is_vendor_specific && (is_status && !command_queue_.front().waiting_for_status_) &&
204 (status_view.IsValid() && status_view.GetStatus() == ErrorCode::UNKNOWN_HCI_COMMAND)) {
205 // If this is a command status of a vendor specific command, and command complete is expected,
206 // we can't treat this as hard failure since we have no way of probing this lack of support at
207 // earlier time. Instead we let the command complete handler handle a empty Command Complete
208 // packet, which will be interpreted as invalid response.
209 CommandCompleteView command_complete_view = CommandCompleteView::Create(
210 EventView::Create(PacketView<kLittleEndian>(std::make_shared<std::vector<uint8_t>>(std::vector<uint8_t>()))));
211 command_queue_.front().GetCallback<CommandCompleteView>()->Invoke(
212 std::move(command_complete_view));
213 } else {
214 ASSERT_LOG(
215 command_queue_.front().waiting_for_status_ == is_status,
216 "0x%02hx (%s) was not expecting %s event",
217 op_code,
218 OpCodeText(op_code).c_str(),
219 logging_id.c_str());
220
221 command_queue_.front().GetCallback<TResponse>()->Invoke(std::move(response_view));
222 }
223
224 command_queue_.pop_front();
225 waiting_command_ = OpCode::NONE;
226 if (hci_timeout_alarm_ != nullptr) {
227 hci_timeout_alarm_->Cancel();
228 send_next_command();
229 }
230 }
231
on_hci_timeoutbluetooth::hci::HciLayer::impl232 void on_hci_timeout(OpCode op_code) {
233 common::StopWatch::DumpStopWatchLog();
234 LOG_ERROR("Timed out waiting for 0x%02hx (%s)", op_code, OpCodeText(op_code).c_str());
235 // TODO: LogMetricHciTimeoutEvent(static_cast<uint32_t>(op_code));
236
237 LOG_ERROR("Flushing %zd waiting commands", command_queue_.size());
238 // Clear any waiting commands (there is an abort coming anyway)
239 command_queue_.clear();
240 command_credits_ = 1;
241 waiting_command_ = OpCode::NONE;
242 // Ignore the response, since we don't know what might come back.
243 enqueue_command(ControllerDebugInfoBuilder::Create(), module_.GetHandler()->BindOnce([](CommandCompleteView) {}));
244 // Don't time out for this one;
245 if (hci_timeout_alarm_ != nullptr) {
246 hci_timeout_alarm_->Cancel();
247 delete hci_timeout_alarm_;
248 hci_timeout_alarm_ = nullptr;
249 }
250 if (hci_abort_alarm_ == nullptr) {
251 hci_abort_alarm_ = new Alarm(module_.GetHandler());
252 hci_abort_alarm_->Schedule(BindOnce(&abort_after_time_out, op_code), kHciTimeoutRestartMs);
253 } else {
254 LOG_WARN("Unable to schedul abort timer");
255 }
256 }
257
send_next_commandbluetooth::hci::HciLayer::impl258 void send_next_command() {
259 if (command_credits_ == 0) {
260 return;
261 }
262 if (waiting_command_ != OpCode::NONE) {
263 return;
264 }
265 if (command_queue_.size() == 0) {
266 return;
267 }
268 std::shared_ptr<std::vector<uint8_t>> bytes = std::make_shared<std::vector<uint8_t>>();
269 BitInserter bi(*bytes);
270 command_queue_.front().command->Serialize(bi);
271 hal_->sendHciCommand(*bytes);
272
273 auto cmd_view = CommandView::Create(PacketView<kLittleEndian>(bytes));
274 ASSERT(cmd_view.IsValid());
275 OpCode op_code = cmd_view.GetOpCode();
276 command_queue_.front().command_view = std::make_unique<CommandView>(std::move(cmd_view));
277 log_link_layer_connection_command(command_queue_.front().command_view);
278 log_classic_pairing_command_status(command_queue_.front().command_view, ErrorCode::STATUS_UNKNOWN);
279 waiting_command_ = op_code;
280 command_credits_ = 0; // Only allow one outstanding command
281 if (hci_timeout_alarm_ != nullptr) {
282 hci_timeout_alarm_->Schedule(BindOnce(&impl::on_hci_timeout, common::Unretained(this), op_code), kHciTimeoutMs);
283 } else {
284 LOG_WARN("%s sent without an hci-timeout timer", OpCodeText(op_code).c_str());
285 }
286 }
287
register_eventbluetooth::hci::HciLayer::impl288 void register_event(EventCode event, ContextualCallback<void(EventView)> handler) {
289 ASSERT_LOG(
290 event != EventCode::LE_META_EVENT,
291 "Can not register handler for %02hhx (%s)",
292 EventCode::LE_META_EVENT,
293 EventCodeText(EventCode::LE_META_EVENT).c_str());
294 ASSERT_LOG(
295 event_handlers_.count(event) == 0,
296 "Can not register a second handler for %02hhx (%s)",
297 event,
298 EventCodeText(event).c_str());
299 event_handlers_[event] = handler;
300 }
301
unregister_eventbluetooth::hci::HciLayer::impl302 void unregister_event(EventCode event) {
303 event_handlers_.erase(event);
304 }
305
register_le_eventbluetooth::hci::HciLayer::impl306 void register_le_event(SubeventCode event, ContextualCallback<void(LeMetaEventView)> handler) {
307 ASSERT_LOG(
308 subevent_handlers_.count(event) == 0,
309 "Can not register a second handler for %02hhx (%s)",
310 event,
311 SubeventCodeText(event).c_str());
312 subevent_handlers_[event] = handler;
313 }
314
unregister_le_eventbluetooth::hci::HciLayer::impl315 void unregister_le_event(SubeventCode event) {
316 subevent_handlers_.erase(subevent_handlers_.find(event));
317 }
318
abort_after_root_inflammationbluetooth::hci::HciLayer::impl319 static void abort_after_root_inflammation(uint8_t vse_error) {
320 ASSERT_LOG(false, "Root inflammation with reason 0x%02hhx", vse_error);
321 }
322
handle_root_inflammationbluetooth::hci::HciLayer::impl323 void handle_root_inflammation(uint8_t vse_error_reason) {
324 LOG_ERROR("Received a Root Inflammation Event vendor reason 0x%02hhx, scheduling an abort",
325 vse_error_reason);
326 bluetooth::os::LogMetricBluetoothHalCrashReason(Address::kEmpty, 0, vse_error_reason);
327 // Add Logging for crash reason
328 if (hci_timeout_alarm_ != nullptr) {
329 hci_timeout_alarm_->Cancel();
330 delete hci_timeout_alarm_;
331 hci_timeout_alarm_ = nullptr;
332 }
333 if (hci_abort_alarm_ == nullptr) {
334 hci_abort_alarm_ = new Alarm(module_.GetHandler());
335 hci_abort_alarm_->Schedule(BindOnce(&abort_after_root_inflammation, vse_error_reason), kHciTimeoutRestartMs);
336 } else {
337 LOG_WARN("Abort timer already scheduled");
338 }
339 }
340
on_hci_eventbluetooth::hci::HciLayer::impl341 void on_hci_event(EventView event) {
342 ASSERT(event.IsValid());
343 if (command_queue_.empty()) {
344 auto event_code = event.GetEventCode();
345 // BT Core spec 5.2 (Volume 4, Part E section 4.4) allows anytime
346 // COMMAND_COMPLETE and COMMAND_STATUS with opcode 0x0 for flow control
347 if (event_code == EventCode::COMMAND_COMPLETE) {
348 auto view = CommandCompleteView::Create(event);
349 ASSERT(view.IsValid());
350 auto op_code = view.GetCommandOpCode();
351 ASSERT_LOG(
352 op_code == OpCode::NONE,
353 "Received %s event with OpCode 0x%02hx (%s) without a waiting command"
354 "(is the HAL sending commands, but not handling the events?)",
355 EventCodeText(event_code).c_str(),
356 op_code,
357 OpCodeText(op_code).c_str());
358 }
359 if (event_code == EventCode::COMMAND_STATUS) {
360 auto view = CommandStatusView::Create(event);
361 ASSERT(view.IsValid());
362 auto op_code = view.GetCommandOpCode();
363 ASSERT_LOG(
364 op_code == OpCode::NONE,
365 "Received %s event with OpCode 0x%02hx (%s) without a waiting command"
366 "(is the HAL sending commands, but not handling the events?)",
367 EventCodeText(event_code).c_str(),
368 op_code,
369 OpCodeText(op_code).c_str());
370 }
371 std::unique_ptr<CommandView> no_waiting_command{nullptr};
372 log_hci_event(no_waiting_command, event, module_.GetDependency<storage::StorageModule>());
373 } else {
374 log_hci_event(command_queue_.front().command_view, event, module_.GetDependency<storage::StorageModule>());
375 }
376 EventCode event_code = event.GetEventCode();
377 // Root Inflamation is a special case, since it aborts here
378 if (event_code == EventCode::VENDOR_SPECIFIC) {
379 auto view = VendorSpecificEventView::Create(event);
380 ASSERT(view.IsValid());
381 if (view.GetSubeventCode() == VseSubeventCode::BQR_EVENT) {
382 auto bqr_event = BqrEventView::Create(view);
383 auto inflammation = BqrRootInflammationEventView::Create(bqr_event);
384 if (bqr_event.IsValid() && inflammation.IsValid()) {
385 handle_root_inflammation(inflammation.GetVendorSpecificErrorCode());
386 return;
387 }
388 }
389 }
390 switch (event_code) {
391 case EventCode::COMMAND_COMPLETE:
392 on_command_complete(event);
393 break;
394 case EventCode::COMMAND_STATUS:
395 on_command_status(event);
396 break;
397 case EventCode::LE_META_EVENT:
398 on_le_meta_event(event);
399 break;
400 default:
401 if (event_handlers_.find(event_code) == event_handlers_.end()) {
402 LOG_WARN(
403 "Unhandled event of type 0x%02hhx (%s)",
404 event_code,
405 EventCodeText(event_code).c_str());
406 } else {
407 event_handlers_[event_code].Invoke(event);
408 }
409 }
410 }
411
on_le_meta_eventbluetooth::hci::HciLayer::impl412 void on_le_meta_event(EventView event) {
413 LeMetaEventView meta_event_view = LeMetaEventView::Create(event);
414 ASSERT(meta_event_view.IsValid());
415 SubeventCode subevent_code = meta_event_view.GetSubeventCode();
416 if (subevent_handlers_.find(subevent_code) == subevent_handlers_.end()) {
417 LOG_WARN("Unhandled le subevent of type 0x%02hhx (%s)", subevent_code, SubeventCodeText(subevent_code).c_str());
418 return;
419 }
420 subevent_handlers_[subevent_code].Invoke(meta_event_view);
421 }
422
423 hal::HciHal* hal_;
424 HciLayer& module_;
425
426 // Command Handling
427 std::list<CommandQueueEntry> command_queue_;
428
429 std::map<EventCode, ContextualCallback<void(EventView)>> event_handlers_;
430 std::map<SubeventCode, ContextualCallback<void(LeMetaEventView)>> subevent_handlers_;
431 OpCode waiting_command_{OpCode::NONE};
432 uint8_t command_credits_{1}; // Send reset first
433 Alarm* hci_timeout_alarm_{nullptr};
434 Alarm* hci_abort_alarm_{nullptr};
435
436 // Acl packets
437 BidiQueue<AclView, AclBuilder> acl_queue_{3 /* TODO: Set queue depth */};
438 os::EnqueueBuffer<AclView> incoming_acl_buffer_{acl_queue_.GetDownEnd()};
439
440 // SCO packets
441 BidiQueue<ScoView, ScoBuilder> sco_queue_{3 /* TODO: Set queue depth */};
442 os::EnqueueBuffer<ScoView> incoming_sco_buffer_{sco_queue_.GetDownEnd()};
443
444 // ISO packets
445 BidiQueue<IsoView, IsoBuilder> iso_queue_{3 /* TODO: Set queue depth */};
446 os::EnqueueBuffer<IsoView> incoming_iso_buffer_{iso_queue_.GetDownEnd()};
447 };
448
449 // All functions here are running on the HAL thread
450 struct HciLayer::hal_callbacks : public hal::HciHalCallbacks {
hal_callbacksbluetooth::hci::HciLayer::hal_callbacks451 hal_callbacks(HciLayer& module) : module_(module) {}
452
hciEventReceivedbluetooth::hci::HciLayer::hal_callbacks453 void hciEventReceived(hal::HciPacket event_bytes) override {
454 auto packet = packet::PacketView<packet::kLittleEndian>(std::make_shared<std::vector<uint8_t>>(event_bytes));
455 EventView event = EventView::Create(packet);
456 module_.CallOn(module_.impl_, &impl::on_hci_event, std::move(event));
457 }
458
aclDataReceivedbluetooth::hci::HciLayer::hal_callbacks459 void aclDataReceived(hal::HciPacket data_bytes) override {
460 auto packet = packet::PacketView<packet::kLittleEndian>(
461 std::make_shared<std::vector<uint8_t>>(std::move(data_bytes)));
462 auto acl = std::make_unique<AclView>(AclView::Create(packet));
463 module_.impl_->incoming_acl_buffer_.Enqueue(std::move(acl), module_.GetHandler());
464 }
465
scoDataReceivedbluetooth::hci::HciLayer::hal_callbacks466 void scoDataReceived(hal::HciPacket data_bytes) override {
467 auto packet = packet::PacketView<packet::kLittleEndian>(
468 std::make_shared<std::vector<uint8_t>>(std::move(data_bytes)));
469 auto sco = std::make_unique<ScoView>(ScoView::Create(packet));
470 module_.impl_->incoming_sco_buffer_.Enqueue(std::move(sco), module_.GetHandler());
471 }
472
isoDataReceivedbluetooth::hci::HciLayer::hal_callbacks473 void isoDataReceived(hal::HciPacket data_bytes) override {
474 auto packet = packet::PacketView<packet::kLittleEndian>(
475 std::make_shared<std::vector<uint8_t>>(std::move(data_bytes)));
476 auto iso = std::make_unique<IsoView>(IsoView::Create(packet));
477 module_.impl_->incoming_iso_buffer_.Enqueue(std::move(iso), module_.GetHandler());
478 }
479
480 HciLayer& module_;
481 };
482
HciLayer()483 HciLayer::HciLayer() : impl_(nullptr), hal_callbacks_(nullptr) {}
484
~HciLayer()485 HciLayer::~HciLayer() {}
486
GetAclQueueEnd()487 common::BidiQueueEnd<AclBuilder, AclView>* HciLayer::GetAclQueueEnd() {
488 return impl_->acl_queue_.GetUpEnd();
489 }
490
GetScoQueueEnd()491 common::BidiQueueEnd<ScoBuilder, ScoView>* HciLayer::GetScoQueueEnd() {
492 return impl_->sco_queue_.GetUpEnd();
493 }
494
GetIsoQueueEnd()495 common::BidiQueueEnd<IsoBuilder, IsoView>* HciLayer::GetIsoQueueEnd() {
496 return impl_->iso_queue_.GetUpEnd();
497 }
498
EnqueueCommand(unique_ptr<CommandBuilder> command,ContextualOnceCallback<void (CommandCompleteView)> on_complete)499 void HciLayer::EnqueueCommand(
500 unique_ptr<CommandBuilder> command, ContextualOnceCallback<void(CommandCompleteView)> on_complete) {
501 CallOn(
502 impl_,
503 &impl::enqueue_command<CommandCompleteView>,
504 std::move(command),
505 std::move(on_complete));
506 }
507
EnqueueCommand(unique_ptr<CommandBuilder> command,ContextualOnceCallback<void (CommandStatusView)> on_status)508 void HciLayer::EnqueueCommand(
509 unique_ptr<CommandBuilder> command, ContextualOnceCallback<void(CommandStatusView)> on_status) {
510 CallOn(
511 impl_, &impl::enqueue_command<CommandStatusView>, std::move(command), std::move(on_status));
512 }
513
RegisterEventHandler(EventCode event,ContextualCallback<void (EventView)> handler)514 void HciLayer::RegisterEventHandler(EventCode event, ContextualCallback<void(EventView)> handler) {
515 CallOn(impl_, &impl::register_event, event, handler);
516 }
517
UnregisterEventHandler(EventCode event)518 void HciLayer::UnregisterEventHandler(EventCode event) {
519 CallOn(impl_, &impl::unregister_event, event);
520 }
521
RegisterLeEventHandler(SubeventCode event,ContextualCallback<void (LeMetaEventView)> handler)522 void HciLayer::RegisterLeEventHandler(SubeventCode event, ContextualCallback<void(LeMetaEventView)> handler) {
523 CallOn(impl_, &impl::register_le_event, event, handler);
524 }
525
UnregisterLeEventHandler(SubeventCode event)526 void HciLayer::UnregisterLeEventHandler(SubeventCode event) {
527 CallOn(impl_, &impl::unregister_le_event, event);
528 }
529
on_disconnection_complete(EventView event_view)530 void HciLayer::on_disconnection_complete(EventView event_view) {
531 auto disconnection_view = DisconnectionCompleteView::Create(event_view);
532 if (!disconnection_view.IsValid()) {
533 LOG_INFO("Dropping invalid disconnection packet");
534 return;
535 }
536
537 uint16_t handle = disconnection_view.GetConnectionHandle();
538 ErrorCode reason = disconnection_view.GetReason();
539 Disconnect(handle, reason);
540 }
541
Disconnect(uint16_t handle,ErrorCode reason)542 void HciLayer::Disconnect(uint16_t handle, ErrorCode reason) {
543 std::unique_lock<std::mutex> lock(callback_handlers_guard_);
544 for (auto callback : disconnect_handlers_) {
545 callback.Invoke(handle, reason);
546 }
547 }
548
on_read_remote_version_complete(EventView event_view)549 void HciLayer::on_read_remote_version_complete(EventView event_view) {
550 auto view = ReadRemoteVersionInformationCompleteView::Create(event_view);
551 ASSERT_LOG(view.IsValid(), "Read remote version information packet invalid");
552 ReadRemoteVersion(
553 view.GetStatus(),
554 view.GetConnectionHandle(),
555 view.GetVersion(),
556 view.GetManufacturerName(),
557 view.GetSubVersion());
558 }
559
ReadRemoteVersion(hci::ErrorCode hci_status,uint16_t handle,uint8_t version,uint16_t manufacturer_name,uint16_t sub_version)560 void HciLayer::ReadRemoteVersion(
561 hci::ErrorCode hci_status, uint16_t handle, uint8_t version, uint16_t manufacturer_name, uint16_t sub_version) {
562 std::unique_lock<std::mutex> lock(callback_handlers_guard_);
563 for (auto callback : read_remote_version_handlers_) {
564 callback.Invoke(hci_status, handle, version, manufacturer_name, sub_version);
565 }
566 }
567
GetAclConnectionInterface(ContextualCallback<void (EventView)> event_handler,ContextualCallback<void (uint16_t,ErrorCode)> on_disconnect,ContextualCallback<void (hci::ErrorCode hci_status,uint16_t,uint8_t version,uint16_t manufacturer_name,uint16_t sub_version)> on_read_remote_version)568 AclConnectionInterface* HciLayer::GetAclConnectionInterface(
569 ContextualCallback<void(EventView)> event_handler,
570 ContextualCallback<void(uint16_t, ErrorCode)> on_disconnect,
571 ContextualCallback<
572 void(hci::ErrorCode hci_status, uint16_t, uint8_t version, uint16_t manufacturer_name, uint16_t sub_version)>
573 on_read_remote_version) {
574 {
575 std::unique_lock<std::mutex> lock(callback_handlers_guard_);
576 disconnect_handlers_.push_back(on_disconnect);
577 read_remote_version_handlers_.push_back(on_read_remote_version);
578 }
579 for (const auto event : AclConnectionEvents) {
580 RegisterEventHandler(event, event_handler);
581 }
582 return &acl_connection_manager_interface_;
583 }
584
PutAclConnectionInterface()585 void HciLayer::PutAclConnectionInterface() {
586 for (const auto event : AclConnectionEvents) {
587 UnregisterEventHandler(event);
588 }
589 {
590 std::unique_lock<std::mutex> lock(callback_handlers_guard_);
591 disconnect_handlers_.clear();
592 read_remote_version_handlers_.clear();
593 }
594 }
595
GetLeAclConnectionInterface(ContextualCallback<void (LeMetaEventView)> event_handler,ContextualCallback<void (uint16_t,ErrorCode)> on_disconnect,ContextualCallback<void (hci::ErrorCode hci_status,uint16_t,uint8_t version,uint16_t manufacturer_name,uint16_t sub_version)> on_read_remote_version)596 LeAclConnectionInterface* HciLayer::GetLeAclConnectionInterface(
597 ContextualCallback<void(LeMetaEventView)> event_handler,
598 ContextualCallback<void(uint16_t, ErrorCode)> on_disconnect,
599 ContextualCallback<
600 void(hci::ErrorCode hci_status, uint16_t, uint8_t version, uint16_t manufacturer_name, uint16_t sub_version)>
601 on_read_remote_version) {
602 {
603 std::unique_lock<std::mutex> lock(callback_handlers_guard_);
604 disconnect_handlers_.push_back(on_disconnect);
605 read_remote_version_handlers_.push_back(on_read_remote_version);
606 }
607 for (const auto event : LeConnectionManagementEvents) {
608 RegisterLeEventHandler(event, event_handler);
609 }
610 return &le_acl_connection_manager_interface_;
611 }
612
PutLeAclConnectionInterface()613 void HciLayer::PutLeAclConnectionInterface() {
614 for (const auto event : LeConnectionManagementEvents) {
615 UnregisterLeEventHandler(event);
616 }
617 {
618 std::unique_lock<std::mutex> lock(callback_handlers_guard_);
619 disconnect_handlers_.clear();
620 read_remote_version_handlers_.clear();
621 }
622 }
623
GetSecurityInterface(ContextualCallback<void (EventView)> event_handler)624 SecurityInterface* HciLayer::GetSecurityInterface(ContextualCallback<void(EventView)> event_handler) {
625 for (const auto event : SecurityEvents) {
626 RegisterEventHandler(event, event_handler);
627 }
628 return &security_interface;
629 }
630
GetLeSecurityInterface(ContextualCallback<void (LeMetaEventView)> event_handler)631 LeSecurityInterface* HciLayer::GetLeSecurityInterface(ContextualCallback<void(LeMetaEventView)> event_handler) {
632 for (const auto subevent : LeSecurityEvents) {
633 RegisterLeEventHandler(subevent, event_handler);
634 }
635 return &le_security_interface;
636 }
637
GetLeAdvertisingInterface(ContextualCallback<void (LeMetaEventView)> event_handler)638 LeAdvertisingInterface* HciLayer::GetLeAdvertisingInterface(ContextualCallback<void(LeMetaEventView)> event_handler) {
639 for (const auto subevent : LeAdvertisingEvents) {
640 RegisterLeEventHandler(subevent, event_handler);
641 }
642 return &le_advertising_interface;
643 }
644
GetLeScanningInterface(ContextualCallback<void (LeMetaEventView)> event_handler)645 LeScanningInterface* HciLayer::GetLeScanningInterface(ContextualCallback<void(LeMetaEventView)> event_handler) {
646 for (const auto subevent : LeScanningEvents) {
647 RegisterLeEventHandler(subevent, event_handler);
648 }
649 return &le_scanning_interface;
650 }
651
GetLeIsoInterface(ContextualCallback<void (LeMetaEventView)> event_handler)652 LeIsoInterface* HciLayer::GetLeIsoInterface(ContextualCallback<void(LeMetaEventView)> event_handler) {
653 for (const auto subevent : LeIsoEvents) {
654 RegisterLeEventHandler(subevent, event_handler);
655 }
656 return &le_iso_interface;
657 }
658
__anona796fe140202() 659 const ModuleFactory HciLayer::Factory = ModuleFactory([]() { return new HciLayer(); });
660
ListDependencies(ModuleList * list) const661 void HciLayer::ListDependencies(ModuleList* list) const {
662 list->add<hal::HciHal>();
663 list->add<storage::StorageModule>();
664 }
665
Start()666 void HciLayer::Start() {
667 auto hal = GetDependency<hal::HciHal>();
668 impl_ = new impl(hal, *this);
669 hal_callbacks_ = new hal_callbacks(*this);
670
671 Handler* handler = GetHandler();
672 impl_->acl_queue_.GetDownEnd()->RegisterDequeue(handler, BindOn(impl_, &impl::on_outbound_acl_ready));
673 impl_->sco_queue_.GetDownEnd()->RegisterDequeue(handler, BindOn(impl_, &impl::on_outbound_sco_ready));
674 impl_->iso_queue_.GetDownEnd()->RegisterDequeue(
675 handler, BindOn(impl_, &impl::on_outbound_iso_ready));
676 RegisterEventHandler(EventCode::DISCONNECTION_COMPLETE, handler->BindOn(this, &HciLayer::on_disconnection_complete));
677 RegisterEventHandler(
678 EventCode::READ_REMOTE_VERSION_INFORMATION_COMPLETE,
679 handler->BindOn(this, &HciLayer::on_read_remote_version_complete));
680 auto drop_packet = handler->BindOn(impl_, &impl::drop);
681 RegisterEventHandler(EventCode::PAGE_SCAN_REPETITION_MODE_CHANGE, drop_packet);
682 RegisterEventHandler(EventCode::MAX_SLOTS_CHANGE, drop_packet);
683
684 hal->registerIncomingPacketCallback(hal_callbacks_);
685 EnqueueCommand(ResetBuilder::Create(), handler->BindOnce(&fail_if_reset_complete_not_success));
686 }
687
Stop()688 void HciLayer::Stop() {
689 auto hal = GetDependency<hal::HciHal>();
690 hal->unregisterIncomingPacketCallback();
691 delete hal_callbacks_;
692
693 impl_->acl_queue_.GetDownEnd()->UnregisterDequeue();
694 impl_->sco_queue_.GetDownEnd()->UnregisterDequeue();
695 impl_->iso_queue_.GetDownEnd()->UnregisterDequeue();
696 delete impl_;
697 }
698
699 } // namespace hci
700 } // namespace bluetooth
701