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