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