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 "os/alarm.h"
21 #include "os/queue.h"
22 #include "packet/packet_builder.h"
23
24 namespace bluetooth {
25 namespace hci {
26 using bluetooth::common::BindOn;
27 using bluetooth::common::BindOnce;
28 using bluetooth::common::ContextualCallback;
29 using bluetooth::common::ContextualOnceCallback;
30 using bluetooth::hci::CommandCompleteView;
31 using bluetooth::hci::CommandPacketBuilder;
32 using bluetooth::hci::CommandStatusView;
33 using bluetooth::hci::EventPacketView;
34 using bluetooth::hci::LeMetaEventView;
35 using bluetooth::os::Handler;
36 using common::BidiQueue;
37 using common::BidiQueueEnd;
38 using hci::OpCode;
39 using hci::ResetCompleteView;
40 using os::Alarm;
41 using os::Handler;
42 using std::move;
43 using std::unique_ptr;
44
fail_if_reset_complete_not_success(CommandCompleteView complete)45 static void fail_if_reset_complete_not_success(CommandCompleteView complete) {
46 auto reset_complete = ResetCompleteView::Create(complete);
47 ASSERT(reset_complete.IsValid());
48 ASSERT(reset_complete.GetStatus() == ErrorCode::SUCCESS);
49 }
50
on_hci_timeout(OpCode op_code)51 static void on_hci_timeout(OpCode op_code) {
52 ASSERT_LOG(false, "Timed out waiting for 0x%02hx (%s)", op_code, OpCodeText(op_code).c_str());
53 }
54
55 class CommandQueueEntry {
56 public:
CommandQueueEntry(unique_ptr<CommandPacketBuilder> command_packet,ContextualOnceCallback<void (CommandCompleteView)> on_complete_function)57 CommandQueueEntry(unique_ptr<CommandPacketBuilder> command_packet,
58 ContextualOnceCallback<void(CommandCompleteView)> on_complete_function)
59 : command(move(command_packet)), waiting_for_status_(false), on_complete(move(on_complete_function)) {}
60
CommandQueueEntry(unique_ptr<CommandPacketBuilder> command_packet,ContextualOnceCallback<void (CommandStatusView)> on_status_function)61 CommandQueueEntry(unique_ptr<CommandPacketBuilder> command_packet,
62 ContextualOnceCallback<void(CommandStatusView)> on_status_function)
63 : command(move(command_packet)), waiting_for_status_(true), on_status(move(on_status_function)) {}
64
65 unique_ptr<CommandPacketBuilder> command;
66 bool waiting_for_status_;
67 ContextualOnceCallback<void(CommandStatusView)> on_status;
68 ContextualOnceCallback<void(CommandCompleteView)> on_complete;
69
70 template <typename TView>
GetCallback()71 ContextualOnceCallback<void(TView)>* GetCallback() {
72 return nullptr;
73 }
74
75 template <>
GetCallback()76 ContextualOnceCallback<void(CommandStatusView)>* GetCallback<CommandStatusView>() {
77 return &on_status;
78 }
79
80 template <>
GetCallback()81 ContextualOnceCallback<void(CommandCompleteView)>* GetCallback<CommandCompleteView>() {
82 return &on_complete;
83 }
84 };
85
86 struct HciLayer::impl {
implbluetooth::hci::HciLayer::impl87 impl(hal::HciHal* hal, HciLayer& module) : hal_(hal), module_(module) {
88 hci_timeout_alarm_ = new Alarm(module.GetHandler());
89 }
90
~implbluetooth::hci::HciLayer::impl91 ~impl() {
92 incoming_acl_buffer_.Clear();
93 delete hci_timeout_alarm_;
94 command_queue_.clear();
95 }
96
dropbluetooth::hci::HciLayer::impl97 void drop(EventPacketView) {}
98
on_outbound_acl_readybluetooth::hci::HciLayer::impl99 void on_outbound_acl_ready() {
100 auto packet = acl_queue_.GetDownEnd()->TryDequeue();
101 std::vector<uint8_t> bytes;
102 BitInserter bi(bytes);
103 packet->Serialize(bi);
104 hal_->sendAclData(bytes);
105 }
106
107 template <typename TResponse>
enqueue_commandbluetooth::hci::HciLayer::impl108 void enqueue_command(unique_ptr<CommandPacketBuilder> command, ContextualOnceCallback<void(TResponse)> on_response) {
109 command_queue_.emplace_back(move(command), move(on_response));
110 send_next_command();
111 }
112
on_command_statusbluetooth::hci::HciLayer::impl113 void on_command_status(EventPacketView event) {
114 handle_command_response<CommandStatusView>(event, "status");
115 }
116
on_command_completebluetooth::hci::HciLayer::impl117 void on_command_complete(EventPacketView event) {
118 handle_command_response<CommandCompleteView>(event, "complete");
119 }
120
121 template <typename TResponse>
handle_command_responsebluetooth::hci::HciLayer::impl122 void handle_command_response(EventPacketView event, std::string logging_id) {
123 TResponse response_view = TResponse::Create(event);
124 ASSERT(response_view.IsValid());
125 command_credits_ = response_view.GetNumHciCommandPackets();
126 OpCode op_code = response_view.GetCommandOpCode();
127 if (op_code == OpCode::NONE) {
128 send_next_command();
129 return;
130 }
131 bool is_status = logging_id == "status";
132
133 ASSERT_LOG(!command_queue_.empty(), "Unexpected %s event with OpCode 0x%02hx (%s)", logging_id.c_str(), op_code,
134 OpCodeText(op_code).c_str());
135 ASSERT_LOG(waiting_command_ == op_code, "Waiting for 0x%02hx (%s), got 0x%02hx (%s)", waiting_command_,
136 OpCodeText(waiting_command_).c_str(), op_code, OpCodeText(op_code).c_str());
137 ASSERT_LOG(command_queue_.front().waiting_for_status_ == is_status, "0x%02hx (%s) was not expecting %s event",
138 op_code, OpCodeText(op_code).c_str(), logging_id.c_str());
139
140 command_queue_.front().GetCallback<TResponse>()->Invoke(move(response_view));
141 command_queue_.pop_front();
142 waiting_command_ = OpCode::NONE;
143 hci_timeout_alarm_->Cancel();
144 send_next_command();
145 }
146
send_next_commandbluetooth::hci::HciLayer::impl147 void send_next_command() {
148 if (command_credits_ == 0) {
149 return;
150 }
151 if (waiting_command_ != OpCode::NONE) {
152 return;
153 }
154 if (command_queue_.size() == 0) {
155 return;
156 }
157 std::shared_ptr<std::vector<uint8_t>> bytes = std::make_shared<std::vector<uint8_t>>();
158 BitInserter bi(*bytes);
159 command_queue_.front().command->Serialize(bi);
160 hal_->sendHciCommand(*bytes);
161
162 auto cmd_view = CommandPacketView::Create(PacketView<kLittleEndian>(bytes));
163 ASSERT(cmd_view.IsValid());
164 OpCode op_code = cmd_view.GetOpCode();
165 waiting_command_ = op_code;
166 command_credits_ = 0; // Only allow one outstanding command
167 hci_timeout_alarm_->Schedule(BindOnce(&on_hci_timeout, op_code), kHciTimeoutMs);
168 }
169
register_eventbluetooth::hci::HciLayer::impl170 void register_event(EventCode event, ContextualCallback<void(EventPacketView)> handler) {
171 ASSERT_LOG(event_handlers_.count(event) == 0, "Can not register a second handler for %02hhx (%s)", event,
172 EventCodeText(event).c_str());
173 event_handlers_[event] = handler;
174 }
175
unregister_eventbluetooth::hci::HciLayer::impl176 void unregister_event(EventCode event) {
177 event_handlers_.erase(event_handlers_.find(event));
178 }
179
register_le_eventbluetooth::hci::HciLayer::impl180 void register_le_event(SubeventCode event, ContextualCallback<void(LeMetaEventView)> handler) {
181 ASSERT_LOG(subevent_handlers_.count(event) == 0, "Can not register a second handler for %02hhx (%s)", event,
182 SubeventCodeText(event).c_str());
183 subevent_handlers_[event] = handler;
184 }
185
unregister_le_eventbluetooth::hci::HciLayer::impl186 void unregister_le_event(SubeventCode event) {
187 subevent_handlers_.erase(subevent_handlers_.find(event));
188 }
189
on_hci_eventbluetooth::hci::HciLayer::impl190 void on_hci_event(EventPacketView event) {
191 ASSERT(event.IsValid());
192 EventCode event_code = event.GetEventCode();
193 if (event_handlers_.find(event_code) == event_handlers_.end()) {
194 LOG_DEBUG("Dropping unregistered event of type 0x%02hhx (%s)", event_code, EventCodeText(event_code).c_str());
195 return;
196 }
197 event_handlers_[event_code].Invoke(event);
198 }
199
on_le_meta_eventbluetooth::hci::HciLayer::impl200 void on_le_meta_event(EventPacketView event) {
201 LeMetaEventView meta_event_view = LeMetaEventView::Create(event);
202 ASSERT(meta_event_view.IsValid());
203 SubeventCode subevent_code = meta_event_view.GetSubeventCode();
204 ASSERT_LOG(subevent_handlers_.find(subevent_code) != subevent_handlers_.end(),
205 "Unhandled le event of type 0x%02hhx (%s)", subevent_code, SubeventCodeText(subevent_code).c_str());
206 subevent_handlers_[subevent_code].Invoke(meta_event_view);
207 }
208
209 hal::HciHal* hal_;
210 HciLayer& module_;
211
212 // Command Handling
213 std::list<CommandQueueEntry> command_queue_;
214
215 std::map<EventCode, ContextualCallback<void(EventPacketView)>> event_handlers_;
216 std::map<SubeventCode, ContextualCallback<void(LeMetaEventView)>> subevent_handlers_;
217 OpCode waiting_command_{OpCode::NONE};
218 uint8_t command_credits_{1}; // Send reset first
219 Alarm* hci_timeout_alarm_{nullptr};
220
221 // Acl packets
222 BidiQueue<AclPacketView, AclPacketBuilder> acl_queue_{3 /* TODO: Set queue depth */};
223 os::EnqueueBuffer<AclPacketView> incoming_acl_buffer_{acl_queue_.GetDownEnd()};
224 };
225
226 // All functions here are running on the HAL thread
227 struct HciLayer::hal_callbacks : public hal::HciHalCallbacks {
hal_callbacksbluetooth::hci::HciLayer::hal_callbacks228 hal_callbacks(HciLayer& module) : module_(module) {}
229
hciEventReceivedbluetooth::hci::HciLayer::hal_callbacks230 void hciEventReceived(hal::HciPacket event_bytes) override {
231 auto packet = packet::PacketView<packet::kLittleEndian>(std::make_shared<std::vector<uint8_t>>(event_bytes));
232 EventPacketView event = EventPacketView::Create(packet);
233 module_.CallOn(module_.impl_, &impl::on_hci_event, move(event));
234 }
235
aclDataReceivedbluetooth::hci::HciLayer::hal_callbacks236 void aclDataReceived(hal::HciPacket data_bytes) override {
237 auto packet = packet::PacketView<packet::kLittleEndian>(std::make_shared<std::vector<uint8_t>>(move(data_bytes)));
238 auto acl = std::make_unique<AclPacketView>(AclPacketView::Create(packet));
239 module_.impl_->incoming_acl_buffer_.Enqueue(move(acl), module_.GetHandler());
240 }
241
scoDataReceivedbluetooth::hci::HciLayer::hal_callbacks242 void scoDataReceived(hal::HciPacket data_bytes) override {
243 // Not implemented yet
244 }
245
246 HciLayer& module_;
247 };
248
HciLayer()249 HciLayer::HciLayer() : impl_(nullptr), hal_callbacks_(nullptr) {}
250
~HciLayer()251 HciLayer::~HciLayer() {
252 }
253
GetAclQueueEnd()254 common::BidiQueueEnd<AclPacketBuilder, AclPacketView>* HciLayer::GetAclQueueEnd() {
255 return impl_->acl_queue_.GetUpEnd();
256 }
257
EnqueueCommand(unique_ptr<CommandPacketBuilder> command,ContextualOnceCallback<void (CommandCompleteView)> on_complete)258 void HciLayer::EnqueueCommand(unique_ptr<CommandPacketBuilder> command,
259 ContextualOnceCallback<void(CommandCompleteView)> on_complete) {
260 CallOn(impl_, &impl::enqueue_command<CommandCompleteView>, move(command), move(on_complete));
261 }
262
EnqueueCommand(unique_ptr<CommandPacketBuilder> command,ContextualOnceCallback<void (CommandStatusView)> on_status)263 void HciLayer::EnqueueCommand(unique_ptr<CommandPacketBuilder> command,
264 ContextualOnceCallback<void(CommandStatusView)> on_status) {
265 CallOn(impl_, &impl::enqueue_command<CommandStatusView>, move(command), move(on_status));
266 }
267
RegisterEventHandler(EventCode event,ContextualCallback<void (EventPacketView)> handler)268 void HciLayer::RegisterEventHandler(EventCode event, ContextualCallback<void(EventPacketView)> handler) {
269 CallOn(impl_, &impl::register_event, event, handler);
270 }
271
UnregisterEventHandler(EventCode event)272 void HciLayer::UnregisterEventHandler(EventCode event) {
273 CallOn(impl_, &impl::unregister_event, event);
274 }
275
RegisterLeEventHandler(SubeventCode event,ContextualCallback<void (LeMetaEventView)> handler)276 void HciLayer::RegisterLeEventHandler(SubeventCode event, ContextualCallback<void(LeMetaEventView)> handler) {
277 CallOn(impl_, &impl::register_le_event, event, handler);
278 }
279
UnregisterLeEventHandler(SubeventCode event)280 void HciLayer::UnregisterLeEventHandler(SubeventCode event) {
281 CallOn(impl_, &impl::unregister_le_event, event);
282 }
283
on_disconnection_complete(EventPacketView event_view)284 void HciLayer::on_disconnection_complete(EventPacketView event_view) {
285 auto disconnection_view = DisconnectionCompleteView::Create(event_view);
286 if (!disconnection_view.IsValid()) {
287 LOG_INFO("Dropping invalid disconnection packet");
288 return;
289 }
290
291 uint16_t handle = disconnection_view.GetConnectionHandle();
292 ErrorCode reason = disconnection_view.GetReason();
293 Disconnect(handle, reason);
294 }
295
Disconnect(uint16_t handle,ErrorCode reason)296 void HciLayer::Disconnect(uint16_t handle, ErrorCode reason) {
297 for (auto callback : disconnect_handlers_) {
298 callback.Invoke(handle, reason);
299 }
300 }
301
GetAclConnectionInterface(ContextualCallback<void (EventPacketView)> event_handler,ContextualCallback<void (uint16_t,ErrorCode)> on_disconnect)302 AclConnectionInterface* HciLayer::GetAclConnectionInterface(
303 ContextualCallback<void(EventPacketView)> event_handler,
304 ContextualCallback<void(uint16_t, ErrorCode)> on_disconnect) {
305 for (const auto event : AclConnectionEvents) {
306 RegisterEventHandler(event, event_handler);
307 }
308 disconnect_handlers_.push_back(on_disconnect);
309 return &acl_connection_manager_interface_;
310 }
311
GetLeAclConnectionInterface(ContextualCallback<void (LeMetaEventView)> event_handler,ContextualCallback<void (uint16_t,ErrorCode)> on_disconnect)312 LeAclConnectionInterface* HciLayer::GetLeAclConnectionInterface(
313 ContextualCallback<void(LeMetaEventView)> event_handler,
314 ContextualCallback<void(uint16_t, ErrorCode)> on_disconnect) {
315 for (const auto event : LeConnectionManagementEvents) {
316 RegisterLeEventHandler(event, event_handler);
317 }
318 disconnect_handlers_.push_back(on_disconnect);
319 return &le_acl_connection_manager_interface_;
320 }
321
GetSecurityInterface(ContextualCallback<void (EventPacketView)> event_handler)322 SecurityInterface* HciLayer::GetSecurityInterface(ContextualCallback<void(EventPacketView)> event_handler) {
323 for (const auto event : SecurityEvents) {
324 RegisterEventHandler(event, event_handler);
325 }
326 return &security_interface;
327 }
328
GetLeSecurityInterface(ContextualCallback<void (LeMetaEventView)> event_handler)329 LeSecurityInterface* HciLayer::GetLeSecurityInterface(ContextualCallback<void(LeMetaEventView)> event_handler) {
330 for (const auto subevent : LeSecurityEvents) {
331 RegisterLeEventHandler(subevent, event_handler);
332 }
333 return &le_security_interface;
334 }
335
GetLeAdvertisingInterface(ContextualCallback<void (LeMetaEventView)> event_handler)336 LeAdvertisingInterface* HciLayer::GetLeAdvertisingInterface(ContextualCallback<void(LeMetaEventView)> event_handler) {
337 for (const auto subevent : LeAdvertisingEvents) {
338 RegisterLeEventHandler(subevent, event_handler);
339 }
340 return &le_advertising_interface;
341 }
342
GetLeScanningInterface(ContextualCallback<void (LeMetaEventView)> event_handler)343 LeScanningInterface* HciLayer::GetLeScanningInterface(ContextualCallback<void(LeMetaEventView)> event_handler) {
344 for (const auto subevent : LeScanningEvents) {
345 RegisterLeEventHandler(subevent, event_handler);
346 }
347 return &le_scanning_interface;
348 }
349
__anond361b4990102() 350 const ModuleFactory HciLayer::Factory = ModuleFactory([]() { return new HciLayer(); });
351
ListDependencies(ModuleList * list)352 void HciLayer::ListDependencies(ModuleList* list) {
353 list->add<hal::HciHal>();
354 }
355
Start()356 void HciLayer::Start() {
357 auto hal = GetDependency<hal::HciHal>();
358 impl_ = new impl(hal, *this);
359 hal_callbacks_ = new hal_callbacks(*this);
360
361 Handler* handler = GetHandler();
362 impl_->acl_queue_.GetDownEnd()->RegisterDequeue(handler, BindOn(impl_, &impl::on_outbound_acl_ready));
363 RegisterEventHandler(EventCode::COMMAND_COMPLETE, handler->BindOn(impl_, &impl::on_command_complete));
364 RegisterEventHandler(EventCode::COMMAND_STATUS, handler->BindOn(impl_, &impl::on_command_status));
365 RegisterEventHandler(EventCode::LE_META_EVENT, handler->BindOn(impl_, &impl::on_le_meta_event));
366 RegisterEventHandler(EventCode::DISCONNECTION_COMPLETE, handler->BindOn(this, &HciLayer::on_disconnection_complete));
367 // TODO find the right place
368 auto drop_packet = handler->BindOn(impl_, &impl::drop);
369 RegisterEventHandler(EventCode::PAGE_SCAN_REPETITION_MODE_CHANGE, drop_packet);
370 RegisterEventHandler(EventCode::MAX_SLOTS_CHANGE, drop_packet);
371 RegisterEventHandler(EventCode::VENDOR_SPECIFIC, drop_packet);
372
373 EnqueueCommand(ResetBuilder::Create(), handler->BindOnce(&fail_if_reset_complete_not_success));
374 hal->registerIncomingPacketCallback(hal_callbacks_);
375 }
376
Stop()377 void HciLayer::Stop() {
378 auto hal = GetDependency<hal::HciHal>();
379 hal->unregisterIncomingPacketCallback();
380 delete hal_callbacks_;
381
382 impl_->acl_queue_.GetDownEnd()->UnregisterDequeue();
383 delete impl_;
384 }
385
386 } // namespace hci
387 } // namespace bluetooth
388