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