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