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/facade/le_acl_manager_facade.h"
18 
19 #include <bluetooth/log.h>
20 
21 #include <memory>
22 #include <mutex>
23 
24 #include "blueberry/facade/hci/le_acl_manager_facade.grpc.pb.h"
25 #include "blueberry/facade/hci/le_acl_manager_facade.pb.h"
26 #include "common/bind.h"
27 #include "grpc/grpc_event_queue.h"
28 #include "hci/acl_manager.h"
29 #include "hci/hci_packets.h"
30 #include "hci/octets.h"
31 #include "packet/raw_builder.h"
32 
33 using ::grpc::ServerAsyncResponseWriter;
34 using ::grpc::ServerAsyncWriter;
35 using ::grpc::ServerContext;
36 
37 using ::bluetooth::packet::RawBuilder;
38 
39 namespace std {
40 template <>
41 struct formatter<blueberry::facade::BluetoothAddressTypeEnum>
42     : enum_formatter<blueberry::facade::BluetoothAddressTypeEnum> {};
43 }  // namespace std
44 
45 namespace bluetooth {
46 namespace hci {
47 namespace facade {
48 
49 using acl_manager::LeAclConnection;
50 using acl_manager::LeConnectionCallbacks;
51 using acl_manager::LeConnectionManagementCallbacks;
52 
53 using namespace blueberry::facade::hci;
54 
55 class LeAclManagerFacadeService : public LeAclManagerFacade::Service, public LeConnectionCallbacks {
56 public:
LeAclManagerFacadeService(AclManager * acl_manager,::bluetooth::os::Handler * facade_handler)57   LeAclManagerFacadeService(AclManager* acl_manager, ::bluetooth::os::Handler* facade_handler)
58       : acl_manager_(acl_manager), facade_handler_(facade_handler) {
59     acl_manager_->RegisterLeCallbacks(this, facade_handler_);
60   }
61 
~LeAclManagerFacadeService()62   ~LeAclManagerFacadeService() {
63     std::unique_lock<std::mutex> lock(acl_connections_mutex_);
64     for (auto& conn : acl_connections_) {
65       if (conn.second.connection_ != nullptr) {
66         conn.second.connection_->GetAclQueueEnd()->UnregisterDequeue();
67         conn.second.connection_.reset();
68       }
69     }
70   }
71 
CreateConnection(::grpc::ServerContext * context,const CreateConnectionMsg * request,::grpc::ServerWriter<LeConnectionEvent> * writer)72   ::grpc::Status CreateConnection(::grpc::ServerContext* context,
73                                   const CreateConnectionMsg* request,
74                                   ::grpc::ServerWriter<LeConnectionEvent>* writer) override {
75     log::info("peer={}, type={}, id_direct={}", request->peer_address().address().address(),
76               request->peer_address().type(), request->is_direct());
77     Address peer_address;
78     log::assert_that(
79             Address::FromString(request->peer_address().address().address(), peer_address),
80             "assert failed: Address::FromString(request->peer_address().address().address(), "
81             "peer_address)");
82     AddressWithType peer(peer_address, static_cast<AddressType>(request->peer_address().type()));
83     bool is_direct = request->is_direct();
84     acl_manager_->CreateLeConnection(peer, is_direct);
85 
86     if (is_direct) {
87       if (direct_connection_events_ != nullptr) {
88         return ::grpc::Status(::grpc::StatusCode::RESOURCE_EXHAUSTED,
89                               "Only one outstanding direct request is supported");
90       }
91       direct_connection_events_ =
92               std::make_shared<::bluetooth::grpc::GrpcEventQueue<LeConnectionEvent>>(
93                       std::string("direct connection attempt ") + peer.ToString());
94       direct_connection_address_ = peer;
95       return direct_connection_events_->RunLoop(context, writer);
96     }
97     per_connection_events_.emplace(
98             peer, std::make_unique<::bluetooth::grpc::GrpcEventQueue<LeConnectionEvent>>(
99                           std::string("connection attempt ") + peer.ToString()));
100     return per_connection_events_[peer]->RunLoop(context, writer);
101   }
102 
CancelConnection(::grpc::ServerContext *,const::blueberry::facade::BluetoothAddressWithType * request,google::protobuf::Empty *)103   ::grpc::Status CancelConnection(::grpc::ServerContext* /* context */,
104                                   const ::blueberry::facade::BluetoothAddressWithType* request,
105                                   google::protobuf::Empty* /* response */) override {
106     log::info("peer={}, type={}", request->address().address(), request->type());
107     Address peer_address;
108     log::assert_that(
109             Address::FromString(request->address().address(), peer_address),
110             "assert failed: Address::FromString(request->address().address(), peer_address)");
111     AddressWithType peer(peer_address, static_cast<AddressType>(request->type()));
112     if (peer == direct_connection_address_) {
113       direct_connection_address_ = AddressWithType();
114       direct_connection_events_.reset();
115     } else {
116       if (per_connection_events_.count(peer) == 0) {
117         return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT,
118                               "No matching outstanding connection");
119       }
120     }
121     acl_manager_->CancelLeConnect(peer);
122     return ::grpc::Status::OK;
123   }
124 
Disconnect(::grpc::ServerContext *,const LeHandleMsg * request,::google::protobuf::Empty *)125   ::grpc::Status Disconnect(::grpc::ServerContext* /* context */, const LeHandleMsg* request,
126                             ::google::protobuf::Empty* /* response */) override {
127     log::info("handle={}", request->handle());
128     std::unique_lock<std::mutex> lock(acl_connections_mutex_);
129     auto connection = acl_connections_.find(request->handle());
130     if (connection == acl_connections_.end()) {
131       log::error("Invalid handle");
132       return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid handle");
133     } else {
134       connection->second.connection_->Disconnect(
135               DisconnectReason::REMOTE_USER_TERMINATED_CONNECTION);
136       return ::grpc::Status::OK;
137     }
138   }
139 
140 #define GET_CONNECTION(view)                                                         \
141   std::map<uint16_t, Connection>::iterator connection;                               \
142   do {                                                                               \
143     if (!view.IsValid()) {                                                           \
144       return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid handle"); \
145     }                                                                                \
146     std::unique_lock<std::mutex> lock(acl_connections_mutex_);                       \
147     connection = acl_connections_.find(view.GetConnectionHandle());                  \
148     if (connection == acl_connections_.end()) {                                      \
149       return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid handle"); \
150     }                                                                                \
151   } while (0)
152 
ConnectionCommand(::grpc::ServerContext *,const LeConnectionCommandMsg * request,::google::protobuf::Empty *)153   ::grpc::Status ConnectionCommand(::grpc::ServerContext* /* context */,
154                                    const LeConnectionCommandMsg* request,
155                                    ::google::protobuf::Empty* /* response */) override {
156     log::info("size={}", request->packet().size());
157     auto command_view = ConnectionManagementCommandView::Create(AclCommandView::Create(
158             CommandView::Create(PacketView<kLittleEndian>(std::make_shared<std::vector<uint8_t>>(
159                     request->packet().begin(), request->packet().end())))));
160     if (!command_view.IsValid()) {
161       return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid command packet");
162     }
163     log::info("opcode={}", OpCodeText(command_view.GetOpCode()));
164     switch (command_view.GetOpCode()) {
165       case OpCode::DISCONNECT: {
166         auto view = DisconnectView::Create(command_view);
167         GET_CONNECTION(view);
168         connection->second.connection_->Disconnect(view.GetReason());
169         return ::grpc::Status::OK;
170       }
171       default:
172         return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid command packet");
173     }
174   }
175 #undef GET_CONNECTION
176 
FetchIncomingConnection(::grpc::ServerContext * context,const google::protobuf::Empty *,::grpc::ServerWriter<LeConnectionEvent> * writer)177   ::grpc::Status FetchIncomingConnection(::grpc::ServerContext* context,
178                                          const google::protobuf::Empty* /* request */,
179                                          ::grpc::ServerWriter<LeConnectionEvent>* writer) override {
180     log::info("wait for one incoming connection");
181     if (incoming_connection_events_ != nullptr) {
182       return ::grpc::Status(::grpc::StatusCode::RESOURCE_EXHAUSTED,
183                             "Only one outstanding incoming connection is supported");
184     }
185     incoming_connection_events_ =
186             std::make_unique<::bluetooth::grpc::GrpcEventQueue<LeConnectionEvent>>(
187                     std::string("incoming connection "));
188     return incoming_connection_events_->RunLoop(context, writer);
189   }
190 
AddDeviceToResolvingList(::grpc::ServerContext *,const IrkMsg * request,::google::protobuf::Empty *)191   ::grpc::Status AddDeviceToResolvingList(::grpc::ServerContext* /* context */,
192                                           const IrkMsg* request,
193                                           ::google::protobuf::Empty* /* response */) override {
194     log::info("peer={}, type={}", request->peer().address().address(), request->peer().type());
195     Address peer_address;
196     log::assert_that(Address::FromString(request->peer().address().address(), peer_address),
197                      "assert failed: Address::FromString(request->peer().address().address(), "
198                      "peer_address)");
199     AddressWithType peer(peer_address, static_cast<AddressType>(request->peer().type()));
200 
201     auto request_peer_irk_length = request->peer_irk().end() - request->peer_irk().begin();
202 
203     if (request_peer_irk_length != kOctet16Length) {
204       return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid Peer IRK");
205     }
206 
207     auto request_local_irk_length = request->local_irk().end() - request->local_irk().begin();
208     if (request_local_irk_length != kOctet16Length) {
209       return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid Local IRK");
210     }
211 
212     Octet16 peer_irk = {};
213     Octet16 local_irk = {};
214 
215     std::vector<uint8_t> peer_irk_data(request->peer_irk().begin(), request->peer_irk().end());
216     std::copy_n(peer_irk_data.begin(), kOctet16Length, peer_irk.begin());
217 
218     std::vector<uint8_t> local_irk_data(request->local_irk().begin(), request->local_irk().end());
219     std::copy_n(local_irk_data.begin(), kOctet16Length, local_irk.begin());
220 
221     acl_manager_->AddDeviceToResolvingList(peer, peer_irk, local_irk);
222     return ::grpc::Status::OK;
223   }
224 
SendAclData(::grpc::ServerContext *,const LeAclData * request,::google::protobuf::Empty *)225   ::grpc::Status SendAclData(::grpc::ServerContext* /* context */, const LeAclData* request,
226                              ::google::protobuf::Empty* /* response */) override {
227     log::info("handle={}, size={}", request->handle(), request->payload().size());
228     std::promise<void> promise;
229     auto future = promise.get_future();
230     {
231       std::unique_lock<std::mutex> lock(acl_connections_mutex_);
232       auto connection = acl_connections_.find(request->handle());
233       if (connection == acl_connections_.end()) {
234         return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid handle");
235       }
236       connection->second.connection_->GetAclQueueEnd()->RegisterEnqueue(
237               facade_handler_,
238               common::Bind(&LeAclManagerFacadeService::enqueue_packet, common::Unretained(this),
239                            common::Unretained(request), common::Passed(std::move(promise))));
240       auto status = future.wait_for(std::chrono::milliseconds(1000));
241       if (status != std::future_status::ready) {
242         return ::grpc::Status(::grpc::StatusCode::RESOURCE_EXHAUSTED, "Can't send packet");
243       }
244     }
245     return ::grpc::Status::OK;
246   }
247 
enqueue_packet(const LeAclData * request,std::promise<void> promise)248   std::unique_ptr<BasePacketBuilder> enqueue_packet(const LeAclData* request,
249                                                     std::promise<void> promise) {
250     auto connection = acl_connections_.find(request->handle());
251     log::assert_that(connection != acl_connections_.end(), "handle {}", request->handle());
252     connection->second.connection_->GetAclQueueEnd()->UnregisterEnqueue();
253     std::unique_ptr<RawBuilder> packet = std::make_unique<RawBuilder>(
254             std::vector<uint8_t>(request->payload().begin(), request->payload().end()));
255     promise.set_value();
256     return packet;
257   }
258 
FetchAclData(::grpc::ServerContext * context,const LeHandleMsg * request,::grpc::ServerWriter<LeAclData> * writer)259   ::grpc::Status FetchAclData(::grpc::ServerContext* context, const LeHandleMsg* request,
260                               ::grpc::ServerWriter<LeAclData>* writer) override {
261     log::info("handle={}", request->handle());
262     auto connection = acl_connections_.find(request->handle());
263     if (connection == acl_connections_.end()) {
264       return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid handle");
265     }
266     return connection->second.pending_acl_data_.RunLoop(context, writer);
267   }
268 
builder_to_string(std::unique_ptr<BasePacketBuilder> builder)269   static inline std::string builder_to_string(std::unique_ptr<BasePacketBuilder> builder) {
270     std::vector<uint8_t> bytes;
271     BitInserter bit_inserter(bytes);
272     builder->Serialize(bit_inserter);
273     return std::string(bytes.begin(), bytes.end());
274   }
275 
on_incoming_acl(std::shared_ptr<LeAclConnection> connection,uint16_t handle)276   void on_incoming_acl(std::shared_ptr<LeAclConnection> connection, uint16_t handle) {
277     log::info("handle={}, addr={}", connection->GetHandle(), connection->GetRemoteAddress());
278     auto packet = connection->GetAclQueueEnd()->TryDequeue();
279     auto connection_tracker = acl_connections_.find(handle);
280     log::assert_that(connection_tracker != acl_connections_.end(), "handle {}", handle);
281     LeAclData acl_data;
282     acl_data.set_handle(handle);
283     acl_data.set_payload(std::string(packet->begin(), packet->end()));
284     connection_tracker->second.pending_acl_data_.OnIncomingEvent(acl_data);
285   }
286 
OnLeConnectSuccess(AddressWithType peer,std::unique_ptr<LeAclConnection> connection)287   void OnLeConnectSuccess(AddressWithType peer,
288                           std::unique_ptr<LeAclConnection> connection) override {
289     log::info("handle={}, addr={}", connection->GetHandle(), peer);
290     std::unique_lock<std::mutex> lock(acl_connections_mutex_);
291     std::shared_ptr<LeAclConnection> shared_connection = std::move(connection);
292     uint16_t handle = shared_connection->GetHandle();
293     auto role = shared_connection->GetRole();
294     if (role == Role::PERIPHERAL) {
295       log::assert_that(incoming_connection_events_ != nullptr,
296                        "assert failed: incoming_connection_events_ != nullptr");
297       if (per_connection_events_.find(peer) == per_connection_events_.end()) {
298         per_connection_events_.emplace(peer, incoming_connection_events_);
299       } else {
300         per_connection_events_[peer] = incoming_connection_events_;
301       }
302       incoming_connection_events_.reset();
303     } else if (direct_connection_address_ == peer) {
304       direct_connection_address_ = AddressWithType();
305       per_connection_events_.emplace(peer, direct_connection_events_);
306       direct_connection_events_.reset();
307     } else {
308       log::assert_that(per_connection_events_.count(peer) > 0, "No connection request for {}",
309                        ADDRESS_TO_LOGGABLE_CSTR(peer));
310     }
311     acl_connections_.erase(handle);
312     acl_connections_.emplace(
313             std::piecewise_construct, std::forward_as_tuple(handle),
314             std::forward_as_tuple(handle, shared_connection, per_connection_events_[peer]));
315     shared_connection->GetAclQueueEnd()->RegisterDequeue(
316             facade_handler_, common::Bind(&LeAclManagerFacadeService::on_incoming_acl,
317                                           common::Unretained(this), shared_connection, handle));
318     auto callbacks = acl_connections_.find(handle)->second.GetCallbacks();
319     shared_connection->RegisterCallbacks(callbacks, facade_handler_);
320     {
321       std::unique_ptr<BasePacketBuilder> builder = LeConnectionCompleteBuilder::Create(
322               ErrorCode::SUCCESS, handle, role, peer.GetAddressType(), peer.GetAddress(), 1, 2, 3,
323               ClockAccuracy::PPM_20);
324       LeConnectionEvent success;
325       success.set_payload(builder_to_string(std::move(builder)));
326       per_connection_events_[peer]->OnIncomingEvent(success);
327     }
328   }
329 
OnLeConnectFail(AddressWithType address,ErrorCode reason)330   void OnLeConnectFail(AddressWithType address, ErrorCode reason) override {
331     log::info("addr={}, reason={}", address, ErrorCodeText(reason));
332     std::unique_ptr<BasePacketBuilder> builder = LeConnectionCompleteBuilder::Create(
333             reason, 0, Role::CENTRAL, address.GetAddressType(), address.GetAddress(), 0, 0, 0,
334             ClockAccuracy::PPM_20);
335     LeConnectionEvent fail;
336     fail.set_payload(builder_to_string(std::move(builder)));
337     if (address == direct_connection_address_) {
338       direct_connection_address_ = AddressWithType();
339       direct_connection_events_->OnIncomingEvent(fail);
340     } else {
341       per_connection_events_[address]->OnIncomingEvent(fail);
342     }
343   }
344 
345   class Connection : public LeConnectionManagementCallbacks {
346   public:
Connection(uint16_t handle,std::shared_ptr<LeAclConnection> connection,std::shared_ptr<::bluetooth::grpc::GrpcEventQueue<LeConnectionEvent>> event_stream)347     Connection(uint16_t handle, std::shared_ptr<LeAclConnection> connection,
348                std::shared_ptr<::bluetooth::grpc::GrpcEventQueue<LeConnectionEvent>> event_stream)
349         : handle_(handle),
350           connection_(std::move(connection)),
351           event_stream_(std::move(event_stream)) {}
OnConnectionUpdate(hci::ErrorCode,uint16_t connection_interval,uint16_t connection_latency,uint16_t supervision_timeout)352     void OnConnectionUpdate(hci::ErrorCode /* hci_status */, uint16_t connection_interval,
353                             uint16_t connection_latency, uint16_t supervision_timeout) override {
354       log::info("interval: 0x{:x}, latency: 0x{:x}, timeout 0x{:x}", connection_interval,
355                 connection_latency, supervision_timeout);
356     }
357 
OnParameterUpdateRequest(uint16_t interval_min,uint16_t interval_max,uint16_t latency,uint16_t supervision_timeout)358     void OnParameterUpdateRequest(uint16_t interval_min, uint16_t interval_max, uint16_t latency,
359                                   uint16_t supervision_timeout) override {
360       log::info("interval_min: 0x{:x}, interval_max: 0x{:x}, latency: 0x{:x}, timeout 0x{:x}",
361                 interval_min, interval_max, latency, supervision_timeout);
362     }
363 
OnDataLengthChange(uint16_t tx_octets,uint16_t tx_time,uint16_t rx_octets,uint16_t rx_time)364     void OnDataLengthChange(uint16_t tx_octets, uint16_t tx_time, uint16_t rx_octets,
365                             uint16_t rx_time) override {
366       log::info("tx_octets: 0x{:x}, tx_time: 0x{:x}, rx_octets 0x{:x}, rx_time 0x{:x}", tx_octets,
367                 tx_time, rx_octets, rx_time);
368     }
369 
OnPhyUpdate(hci::ErrorCode,uint8_t,uint8_t)370     void OnPhyUpdate(hci::ErrorCode /* hci_status */, uint8_t /* tx_phy */,
371                      uint8_t /* rx_phy */) override {}
OnDisconnection(ErrorCode reason)372     void OnDisconnection(ErrorCode reason) override {
373       log::info("reason: {}", ErrorCodeText(reason));
374       std::unique_ptr<BasePacketBuilder> builder =
375               DisconnectionCompleteBuilder::Create(ErrorCode::SUCCESS, handle_, reason);
376       LeConnectionEvent disconnection;
377       disconnection.set_payload(builder_to_string(std::move(builder)));
378       event_stream_->OnIncomingEvent(disconnection);
379     }
380 
OnReadRemoteVersionInformationComplete(hci::ErrorCode,uint8_t,uint16_t,uint16_t)381     void OnReadRemoteVersionInformationComplete(hci::ErrorCode /* hci_status */,
382                                                 uint8_t /* lmp_version */,
383                                                 uint16_t /* manufacturer_name */,
384                                                 uint16_t /* sub_version */) override {}
OnLeReadRemoteFeaturesComplete(hci::ErrorCode,uint64_t)385     void OnLeReadRemoteFeaturesComplete(hci::ErrorCode /* hci_status */,
386                                         uint64_t /* features */) override {}
387 
GetCallbacks()388     LeConnectionManagementCallbacks* GetCallbacks() { return this; }
OnLeSubrateChange(hci::ErrorCode hci_status,uint16_t subrate_factor,uint16_t peripheral_latency,uint16_t continuation_number,uint16_t supervision_timeout)389     void OnLeSubrateChange(hci::ErrorCode hci_status, uint16_t subrate_factor,
390                            uint16_t peripheral_latency, uint16_t continuation_number,
391                            uint16_t supervision_timeout) override {
392       log::info(
393               "hci_status: {}, subrate_factor: {:#x}, peripheral_latency: {:#x}, "
394               "continuation_number: "
395               "{:#x}, supervision_timeout: {:#x}",
396               ErrorCodeText(hci_status), subrate_factor, peripheral_latency, continuation_number,
397               supervision_timeout);
398     }
399 
400     uint16_t handle_;
401     std::shared_ptr<LeAclConnection> connection_;
402     std::shared_ptr<::bluetooth::grpc::GrpcEventQueue<LeConnectionEvent>> event_stream_;
403     ::bluetooth::grpc::GrpcEventQueue<LeAclData> pending_acl_data_{std::string("PendingAclData") +
404                                                                    std::to_string(handle_)};
405   };
406 
IsOnBackgroundList(::grpc::ServerContext *,const::blueberry::facade::hci::BackgroundRequestMsg * request,::blueberry::facade::hci::BackgroundResultMsg * msg)407   ::grpc::Status IsOnBackgroundList(::grpc::ServerContext* /* context */,
408                                     const ::blueberry::facade::hci::BackgroundRequestMsg* request,
409                                     ::blueberry::facade::hci::BackgroundResultMsg* msg) {
410     Address peer_address;
411     log::assert_that(
412             Address::FromString(request->peer_address().address().address(), peer_address),
413             "assert failed: Address::FromString(request->peer_address().address().address(), "
414             "peer_address)");
415     AddressWithType peer(peer_address, static_cast<AddressType>(request->peer_address().type()));
416     std::promise<bool> promise;
417     auto future = promise.get_future();
418     acl_manager_->IsOnBackgroundList(peer, std::move(promise));
419     msg->set_is_on_background_list(future.get());
420     return ::grpc::Status::OK;
421   }
422 
RemoveFromBackgroundList(::grpc::ServerContext *,const::blueberry::facade::hci::BackgroundRequestMsg * request,::google::protobuf::Empty *)423   ::grpc::Status RemoveFromBackgroundList(
424           ::grpc::ServerContext* /* context */,
425           const ::blueberry::facade::hci::BackgroundRequestMsg* request,
426           ::google::protobuf::Empty* /* response */) {
427     Address peer_address;
428     log::assert_that(
429             Address::FromString(request->peer_address().address().address(), peer_address),
430             "assert failed: Address::FromString(request->peer_address().address().address(), "
431             "peer_address)");
432     AddressWithType peer(peer_address, static_cast<AddressType>(request->peer_address().type()));
433     acl_manager_->RemoveFromBackgroundList(peer);
434     return ::grpc::Status::OK;
435   }
436 
437 private:
438   AclManager* acl_manager_;
439   ::bluetooth::os::Handler* facade_handler_;
440   mutable std::mutex acl_connections_mutex_;
441   std::map<bluetooth::hci::AddressWithType,
442            std::shared_ptr<::bluetooth::grpc::GrpcEventQueue<LeConnectionEvent>>>
443           per_connection_events_;
444   std::shared_ptr<::bluetooth::grpc::GrpcEventQueue<LeConnectionEvent>> direct_connection_events_;
445   bluetooth::hci::AddressWithType direct_connection_address_;
446   std::shared_ptr<::bluetooth::grpc::GrpcEventQueue<LeConnectionEvent>> incoming_connection_events_;
447   std::map<uint16_t, Connection> acl_connections_;
448 };
449 
ListDependencies(ModuleList * list) const450 void LeAclManagerFacadeModule::ListDependencies(ModuleList* list) const {
451   ::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
452   list->add<AclManager>();
453 }
454 
Start()455 void LeAclManagerFacadeModule::Start() {
456   ::bluetooth::grpc::GrpcFacadeModule::Start();
457   service_ = new LeAclManagerFacadeService(GetDependency<AclManager>(), GetHandler());
458 }
459 
Stop()460 void LeAclManagerFacadeModule::Stop() {
461   delete service_;
462   ::bluetooth::grpc::GrpcFacadeModule::Stop();
463 }
464 
GetService() const465 ::grpc::Service* LeAclManagerFacadeModule::GetService() const { return service_; }
466 
467 const ModuleFactory LeAclManagerFacadeModule::Factory =
__anon12dd41050102() 468         ::bluetooth::ModuleFactory([]() { return new LeAclManagerFacadeModule(); });
469 
470 }  // namespace facade
471 }  // namespace hci
472 }  // namespace bluetooth
473