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_advertising_manager_facade.h"
18 
19 #include <bluetooth/log.h>
20 
21 #include <cstdint>
22 #include <unordered_map>
23 #include <utility>
24 
25 #include "blueberry/facade/hci/le_advertising_manager_facade.grpc.pb.h"
26 #include "blueberry/facade/hci/le_advertising_manager_facade.pb.h"
27 #include "common/bidi_queue.h"
28 #include "common/bind.h"
29 #include "grpc/grpc_event_queue.h"
30 #include "hardware/ble_advertiser.h"
31 #include "hci/address.h"
32 #include "hci/address_with_type.h"
33 #include "hci/le_advertising_manager.h"
34 #include "os/log.h"
35 
36 namespace bluetooth {
37 namespace hci {
38 namespace facade {
39 
40 using ::grpc::ServerAsyncResponseWriter;
41 using ::grpc::ServerAsyncWriter;
42 using ::grpc::ServerContext;
43 using ::grpc::ServerWriter;
44 using ::grpc::Status;
45 
46 using ::blueberry::facade::BluetoothAddress;
47 using ::blueberry::facade::BluetoothAddressTypeEnum;
48 using ::blueberry::facade::BluetoothOwnAddressTypeEnum;
49 using ::blueberry::facade::hci::AdvertisingConfig;
50 using ::blueberry::facade::hci::ExtendedAdvertisingConfig;
51 using ::blueberry::facade::hci::GapDataMsg;
52 using ::blueberry::facade::hci::PeriodicAdvertisingParameters;
53 
GapDataFromProto(const GapDataMsg & gap_data_proto)54 hci::GapData GapDataFromProto(const GapDataMsg& gap_data_proto) {
55   hci::GapData gap_data;
56   auto data_copy = std::make_shared<std::vector<uint8_t>>(gap_data_proto.data().begin(), gap_data_proto.data().end());
57   packet::PacketView<packet::kLittleEndian> packet(data_copy);
58   auto after = hci::GapData::Parse(&gap_data, packet.begin());
59   log::assert_that(after != packet.begin(), "assert failed: after != packet.begin()");
60   return gap_data;
61 }
62 
AdvertisingConfigFromProto(const AdvertisingConfig & config_proto,hci::AdvertisingConfig * config)63 bool AdvertisingConfigFromProto(
64     const AdvertisingConfig& config_proto, hci::AdvertisingConfig* config) {
65   for (const auto& elem : config_proto.advertisement()) {
66     config->advertisement.push_back(GapDataFromProto(elem));
67   }
68 
69   for (const auto& elem : config_proto.scan_response()) {
70     config->scan_response.push_back(GapDataFromProto(elem));
71   }
72 
73   if (config_proto.interval_min() > UINT16_MAX || config_proto.interval_min() < 0) {
74     log::warn("Bad interval_min: {}", config_proto.interval_min());
75     return false;
76   }
77   config->interval_min = static_cast<uint16_t>(config_proto.interval_min());
78 
79   if (config_proto.interval_max() > UINT16_MAX || config_proto.interval_max() < 0) {
80     log::warn("Bad interval_max: {}", config_proto.interval_max());
81     return false;
82   }
83   config->interval_max = static_cast<uint16_t>(config_proto.interval_max());
84 
85   config->advertising_type = static_cast<hci::AdvertisingType>(config_proto.advertising_type());
86 
87   config->requested_advertiser_address_type =
88       config_proto.own_address_type() == BluetoothOwnAddressTypeEnum::USE_PUBLIC_DEVICE_ADDRESS
89           ? AdvertiserAddressType::PUBLIC
90           : AdvertiserAddressType::RESOLVABLE_RANDOM;
91 
92   config->peer_address_type = static_cast<::bluetooth::hci::PeerAddressType>(config_proto.peer_address_type());
93 
94   hci::Address::FromString(config_proto.peer_address().address(), config->peer_address);
95 
96   if (config_proto.channel_map() > UINT8_MAX || config_proto.channel_map() < 0) {
97     log::warn("Bad channel_map: {}", config_proto.channel_map());
98     return false;
99   }
100   config->channel_map = static_cast<uint8_t>(config_proto.channel_map());
101 
102   if (config_proto.tx_power() > UINT8_MAX || config_proto.tx_power() < 0) {
103     log::warn("Bad tx_power: {}", config_proto.tx_power());
104     return false;
105   }
106 
107   config->filter_policy = static_cast<hci::AdvertisingFilterPolicy>(config_proto.filter_policy());
108 
109   config->tx_power = static_cast<uint8_t>(config_proto.tx_power());
110 
111   config->legacy_pdus = true;
112 
113   auto advertising_type = static_cast<::bluetooth::hci::AdvertisingType>(config_proto.advertising_type());
114 
115   switch (advertising_type) {
116     case AdvertisingType::ADV_IND: {
117       config->connectable = true;
118       config->scannable = true;
119     } break;
120     case AdvertisingType::ADV_DIRECT_IND_HIGH: {
121       config->connectable = true;
122       config->directed = true;
123       config->high_duty_directed_connectable = true;
124     } break;
125     case AdvertisingType::ADV_SCAN_IND: {
126       config->scannable = true;
127     } break;
128     case AdvertisingType::ADV_NONCONN_IND: {
129     } break;
130     case AdvertisingType::ADV_DIRECT_IND_LOW: {
131       config->directed = true;
132       config->connectable = true;
133     } break;
134   }
135 
136   return true;
137 }
138 
ExtendedAdvertisingConfigFromProto(const ExtendedAdvertisingConfig & config_proto,hci::AdvertisingConfig * config)139 bool ExtendedAdvertisingConfigFromProto(
140     const ExtendedAdvertisingConfig& config_proto, hci::AdvertisingConfig* config) {
141   if (!AdvertisingConfigFromProto(config_proto.advertising_config(), config)) {
142     log::warn("Error parsing advertising config");
143     return false;
144   }
145   config->connectable = config_proto.connectable();
146   config->scannable = config_proto.scannable();
147   config->directed = config_proto.directed();
148   config->high_duty_directed_connectable = config_proto.high_duty_directed_connectable();
149   config->legacy_pdus = config_proto.legacy_pdus();
150   config->anonymous = config_proto.anonymous();
151   config->include_tx_power = config_proto.include_tx_power();
152   config->use_le_coded_phy = config_proto.use_le_coded_phy();
153   config->secondary_max_skip = static_cast<uint8_t>(config_proto.secondary_max_skip());
154   config->secondary_advertising_phy = static_cast<hci::SecondaryPhyType>(config_proto.secondary_advertising_phy());
155   config->sid = static_cast<uint8_t>(config_proto.sid());
156   config->enable_scan_request_notifications =
157       static_cast<hci::Enable>(config_proto.enable_scan_request_notifications());
158   return true;
159 }
160 
PeriodicAdvertisingParametersFromProto(const PeriodicAdvertisingParameters & config_proto,hci::PeriodicAdvertisingParameters * config)161 bool PeriodicAdvertisingParametersFromProto(
162     const PeriodicAdvertisingParameters& config_proto, hci::PeriodicAdvertisingParameters* config) {
163   if (config_proto.min_interval() > UINT16_MAX || config_proto.min_interval() < 0) {
164     log::warn("Bad interval_min: {}", config_proto.min_interval());
165     return false;
166   }
167   config->min_interval = static_cast<uint16_t>(config_proto.min_interval());
168   if (config_proto.max_interval() > UINT16_MAX || config_proto.max_interval() < 0) {
169     log::warn("Bad interval_max: {}", config_proto.max_interval());
170     return false;
171   }
172   config->max_interval = static_cast<uint16_t>(config_proto.max_interval());
173   config->properties =
174       static_cast<hci::PeriodicAdvertisingParameters::AdvertisingProperty>(config_proto.advertising_property());
175   return true;
176 }
177 
178 class LeAdvertiser {
179  public:
LeAdvertiser(hci::AdvertisingConfig config)180   LeAdvertiser(hci::AdvertisingConfig config) : config_(std::move(config)) {}
181 
ScanCallback(Address,AddressType)182   void ScanCallback(Address /* address */, AddressType /* address_type */) {}
183 
TerminatedCallback(ErrorCode,uint8_t,uint8_t)184   void TerminatedCallback(ErrorCode /* error_code */, uint8_t, uint8_t) {}
185 
GetAdvertiserId()186   hci::AdvertiserId GetAdvertiserId() {
187     return id_;
188   }
189 
SetAdvertiserId(hci::AdvertiserId id)190   void SetAdvertiserId(hci::AdvertiserId id) {
191     id_ = id;
192   }
193 
194  private:
195   hci::AdvertiserId id_ = LeAdvertisingManager::kInvalidId;
196   hci::AdvertisingConfig config_;
197 };
198 
199 using ::blueberry::facade::hci::AddressMsg;
200 using ::blueberry::facade::hci::AdvertisingCallbackMsg;
201 using ::blueberry::facade::hci::AdvertisingCallbackMsgType;
202 using ::blueberry::facade::hci::AdvertisingStatus;
203 using ::blueberry::facade::hci::CreateAdvertiserRequest;
204 using ::blueberry::facade::hci::CreateAdvertiserResponse;
205 using ::blueberry::facade::hci::EnableAdvertiserRequest;
206 using ::blueberry::facade::hci::EnablePeriodicAdvertisingRequest;
207 using ::blueberry::facade::hci::ExtendedCreateAdvertiserRequest;
208 using ::blueberry::facade::hci::ExtendedCreateAdvertiserResponse;
209 using ::blueberry::facade::hci::GetNumberOfAdvertisingInstancesResponse;
210 using ::blueberry::facade::hci::GetOwnAddressRequest;
211 using ::blueberry::facade::hci::LeAdvertisingManagerFacade;
212 using ::blueberry::facade::hci::RemoveAdvertiserRequest;
213 using ::blueberry::facade::hci::SetDataRequest;
214 using ::blueberry::facade::hci::SetParametersRequest;
215 using ::blueberry::facade::hci::SetPeriodicDataRequest;
216 using ::blueberry::facade::hci::SetPeriodicParametersRequest;
217 
218 class LeAdvertisingManagerFacadeService : public LeAdvertisingManagerFacade::Service, AdvertisingCallback {
219  public:
LeAdvertisingManagerFacadeService(LeAdvertisingManager * le_advertising_manager,os::Handler * facade_handler)220   LeAdvertisingManagerFacadeService(LeAdvertisingManager* le_advertising_manager, os::Handler* facade_handler)
221       : le_advertising_manager_(le_advertising_manager), facade_handler_(facade_handler) {
222     log::assert_that(
223         le_advertising_manager_ != nullptr, "assert failed: le_advertising_manager_ != nullptr");
224     log::assert_that(facade_handler_ != nullptr, "assert failed: facade_handler_ != nullptr");
225     le_advertising_manager_->RegisterAdvertisingCallback(this);
226   }
227 
CreateAdvertiser(::grpc::ServerContext *,const CreateAdvertiserRequest * request,CreateAdvertiserResponse * response)228   ::grpc::Status CreateAdvertiser(
229       ::grpc::ServerContext* /* context */,
230       const CreateAdvertiserRequest* request,
231       CreateAdvertiserResponse* response) override {
232     hci::AdvertisingConfig config = {};
233     if (!AdvertisingConfigFromProto(request->config(), &config)) {
234       log::warn("Error parsing advertising config {}", request->SerializeAsString());
235       response->set_advertiser_id(LeAdvertisingManager::kInvalidId);
236       return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Error while parsing advertising config");
237     }
238     LeAdvertiser le_advertiser(config);
239 
240     pending_advertiser_id_ = std::promise<AdvertiserId>();
241     auto future = pending_advertiser_id_->get_future();
242     le_advertising_manager_->ExtendedCreateAdvertiser(
243         kAdvertiserClientIdJni,
244         0,
245         config,
246         common::Bind(&LeAdvertiser::ScanCallback, common::Unretained(&le_advertiser)),
247         common::Bind(&LeAdvertiser::TerminatedCallback, common::Unretained(&le_advertiser)),
248         0,
249         0,
250         facade_handler_);
251 
252     auto advertiser_id = future.get();
253     if (advertiser_id != LeAdvertisingManager::kInvalidId) {
254       le_advertiser.SetAdvertiserId(advertiser_id);
255       le_advertisers_.push_back(le_advertiser);
256     } else {
257       log::warn("Failed to create advertiser");
258     }
259     response->set_advertiser_id(advertiser_id);
260     return ::grpc::Status::OK;
261   }
262 
ExtendedCreateAdvertiser(::grpc::ServerContext *,const ExtendedCreateAdvertiserRequest * request,ExtendedCreateAdvertiserResponse * response)263   ::grpc::Status ExtendedCreateAdvertiser(
264       ::grpc::ServerContext* /* context */,
265       const ExtendedCreateAdvertiserRequest* request,
266       ExtendedCreateAdvertiserResponse* response) override {
267     hci::AdvertisingConfig config = {};
268     if (!ExtendedAdvertisingConfigFromProto(request->config(), &config)) {
269       log::warn("Error parsing advertising config {}", request->SerializeAsString());
270       response->set_advertiser_id(LeAdvertisingManager::kInvalidId);
271       return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Error while parsing advertising config");
272     }
273     LeAdvertiser le_advertiser(config);
274     pending_advertiser_id_ = std::promise<AdvertiserId>();
275     auto future = pending_advertiser_id_->get_future();
276     le_advertising_manager_->ExtendedCreateAdvertiser(
277         kAdvertiserClientIdJni,
278         0,
279         config,
280         common::Bind(&LeAdvertiser::ScanCallback, common::Unretained(&le_advertiser)),
281         common::Bind(&LeAdvertiser::TerminatedCallback, common::Unretained(&le_advertiser)),
282         0,
283         0,
284         facade_handler_);
285 
286     auto advertiser_id = future.get();
287     if (advertiser_id != LeAdvertisingManager::kInvalidId) {
288       le_advertiser.SetAdvertiserId(advertiser_id);
289       le_advertisers_.push_back(le_advertiser);
290     } else {
291       log::warn("Failed to create advertiser");
292     }
293     response->set_advertiser_id(advertiser_id);
294     return ::grpc::Status::OK;
295   }
296 
EnableAdvertiser(::grpc::ServerContext *,const EnableAdvertiserRequest * request,::google::protobuf::Empty *)297   ::grpc::Status EnableAdvertiser(
298       ::grpc::ServerContext* /* context */,
299       const EnableAdvertiserRequest* request,
300       ::google::protobuf::Empty* /* response */) override {
301     le_advertising_manager_->EnableAdvertiser(request->advertiser_id(), request->enable(), 0, 0);
302     return ::grpc::Status::OK;
303   }
304 
SetData(::grpc::ServerContext *,const SetDataRequest * request,::google::protobuf::Empty *)305   ::grpc::Status SetData(
306       ::grpc::ServerContext* /* context */,
307       const SetDataRequest* request,
308       ::google::protobuf::Empty* /* response */) override {
309     std::vector<GapData> advertising_data = {};
310     for (const auto& elem : request->data()) {
311       advertising_data.push_back(GapDataFromProto(elem));
312     }
313     le_advertising_manager_->SetData(request->advertiser_id(), request->set_scan_rsp(), advertising_data);
314     return ::grpc::Status::OK;
315   }
316 
SetParameters(::grpc::ServerContext *,const SetParametersRequest * request,::google::protobuf::Empty *)317   ::grpc::Status SetParameters(
318       ::grpc::ServerContext* /* context */,
319       const SetParametersRequest* request,
320       ::google::protobuf::Empty* /* response */) override {
321     hci::AdvertisingConfig config = {};
322     if (!AdvertisingConfigFromProto(request->config(), &config)) {
323       log::warn("Error parsing advertising config {}", request->SerializeAsString());
324       return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Error while parsing advertising config");
325     }
326     le_advertising_manager_->SetParameters(request->advertiser_id(), config);
327     return ::grpc::Status::OK;
328   }
329 
SetPeriodicParameters(::grpc::ServerContext *,const SetPeriodicParametersRequest * request,::google::protobuf::Empty *)330   ::grpc::Status SetPeriodicParameters(
331       ::grpc::ServerContext* /* context */,
332       const SetPeriodicParametersRequest* request,
333       ::google::protobuf::Empty* /* response */) override {
334     hci::PeriodicAdvertisingParameters config = {};
335     if (!PeriodicAdvertisingParametersFromProto(request->config(), &config)) {
336       log::warn("Error parsing periodic advertising parameters {}", request->SerializeAsString());
337       return ::grpc::Status(
338           ::grpc::StatusCode::INVALID_ARGUMENT, "Error while parsing periodic advertising parameters");
339     }
340     le_advertising_manager_->SetPeriodicParameters(request->advertiser_id(), config);
341     return ::grpc::Status::OK;
342   }
343 
SetPeriodicData(::grpc::ServerContext *,const SetPeriodicDataRequest * request,::google::protobuf::Empty *)344   ::grpc::Status SetPeriodicData(
345       ::grpc::ServerContext* /* context */,
346       const SetPeriodicDataRequest* request,
347       ::google::protobuf::Empty* /* response */) override {
348     std::vector<GapData> advertising_data = {};
349     for (const auto& elem : request->data()) {
350       advertising_data.push_back(GapDataFromProto(elem));
351     }
352     le_advertising_manager_->SetPeriodicData(request->advertiser_id(), advertising_data);
353     return ::grpc::Status::OK;
354   }
355 
EnablePeriodicAdvertising(::grpc::ServerContext *,const EnablePeriodicAdvertisingRequest * request,::google::protobuf::Empty *)356   ::grpc::Status EnablePeriodicAdvertising(
357       ::grpc::ServerContext* /* context */,
358       const EnablePeriodicAdvertisingRequest* request,
359       ::google::protobuf::Empty* /* response */) override {
360     le_advertising_manager_->EnablePeriodicAdvertising(
361         request->advertiser_id(), request->enable(), request->include_adi());
362     return ::grpc::Status::OK;
363   }
364 
GetOwnAddress(::grpc::ServerContext *,const GetOwnAddressRequest * request,::google::protobuf::Empty *)365   ::grpc::Status GetOwnAddress(
366       ::grpc::ServerContext* /* context */,
367       const GetOwnAddressRequest* request,
368       ::google::protobuf::Empty* /* response */) override {
369     le_advertising_manager_->GetOwnAddress(request->advertiser_id());
370     return ::grpc::Status::OK;
371   }
372 
GetNumberOfAdvertisingInstances(::grpc::ServerContext *,const::google::protobuf::Empty *,GetNumberOfAdvertisingInstancesResponse * response)373   ::grpc::Status GetNumberOfAdvertisingInstances(
374       ::grpc::ServerContext* /* context */,
375       const ::google::protobuf::Empty* /* request */,
376       GetNumberOfAdvertisingInstancesResponse* response) override {
377     response->set_num_advertising_instances(le_advertising_manager_->GetNumberOfAdvertisingInstances());
378     return ::grpc::Status::OK;
379   }
380 
RemoveAdvertiser(::grpc::ServerContext *,const RemoveAdvertiserRequest * request,::google::protobuf::Empty *)381   ::grpc::Status RemoveAdvertiser(
382       ::grpc::ServerContext* /* context */,
383       const RemoveAdvertiserRequest* request,
384       ::google::protobuf::Empty* /* response */) override {
385     if (request->advertiser_id() == LeAdvertisingManager::kInvalidId) {
386       log::warn("Invalid advertiser ID {}", request->advertiser_id());
387       return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invlid advertiser ID received");
388     }
389     le_advertising_manager_->RemoveAdvertiser(request->advertiser_id());
390     for (auto iter = le_advertisers_.begin(); iter != le_advertisers_.end();) {
391       if (iter->GetAdvertiserId() == request->advertiser_id()) {
392         iter = le_advertisers_.erase(iter);
393       } else {
394         ++iter;
395       }
396     }
397     return ::grpc::Status::OK;
398   }
399 
FetchCallbackEvents(::grpc::ServerContext * context,const::google::protobuf::Empty *,::grpc::ServerWriter<AdvertisingCallbackMsg> * writer)400   ::grpc::Status FetchCallbackEvents(
401       ::grpc::ServerContext* context,
402       const ::google::protobuf::Empty* /* request */,
403       ::grpc::ServerWriter<AdvertisingCallbackMsg>* writer) override {
404     return callback_events_.RunLoop(context, writer);
405   }
406 
FetchAddressEvents(::grpc::ServerContext * context,const::google::protobuf::Empty *,::grpc::ServerWriter<AddressMsg> * writer)407   ::grpc::Status FetchAddressEvents(
408       ::grpc::ServerContext* context,
409       const ::google::protobuf::Empty* /* request */,
410       ::grpc::ServerWriter<AddressMsg>* writer) override {
411     return address_events_.RunLoop(context, writer);
412   }
413 
OnAdvertisingSetStarted(int reg_id,uint8_t advertiser_id,int8_t,AdvertisingStatus status)414   void OnAdvertisingSetStarted(
415       int reg_id, uint8_t advertiser_id, int8_t /* tx_power */, AdvertisingStatus status) {
416     if (pending_advertiser_id_.has_value()) {
417       pending_advertiser_id_->set_value(advertiser_id);
418       pending_advertiser_id_.reset();
419     }
420     AdvertisingCallbackMsg msg;
421     msg.set_message_type(AdvertisingCallbackMsgType::ADVERTISING_SET_STARTED);
422     msg.set_advertiser_id(advertiser_id);
423     msg.set_status(static_cast<facade::AdvertisingStatus>(status));
424     msg.set_data(reg_id);
425     callback_events_.OnIncomingEvent(msg);
426   };
427 
OnAdvertisingEnabled(uint8_t advertiser_id,bool enable,uint8_t status)428   void OnAdvertisingEnabled(uint8_t advertiser_id, bool enable, uint8_t status) {
429     AdvertisingCallbackMsg msg;
430     msg.set_message_type(AdvertisingCallbackMsgType::ADVERTISING_ENABLED);
431     msg.set_advertiser_id(advertiser_id);
432     msg.set_status(static_cast<facade::AdvertisingStatus>(status));
433     msg.set_data(enable ? 1 : 0);
434     callback_events_.OnIncomingEvent(msg);
435   };
436 
OnAdvertisingDataSet(uint8_t advertiser_id,uint8_t status)437   void OnAdvertisingDataSet(uint8_t advertiser_id, uint8_t status) {
438     AdvertisingCallbackMsg msg;
439     msg.set_message_type(AdvertisingCallbackMsgType::ADVERTISING_DATA_SET);
440     msg.set_advertiser_id(advertiser_id);
441     msg.set_status(static_cast<facade::AdvertisingStatus>(status));
442     callback_events_.OnIncomingEvent(msg);
443   };
444 
OnScanResponseDataSet(uint8_t advertiser_id,uint8_t status)445   void OnScanResponseDataSet(uint8_t advertiser_id, uint8_t status) {
446     AdvertisingCallbackMsg msg;
447     msg.set_message_type(AdvertisingCallbackMsgType::SCAN_RESPONSE_DATA_SET);
448     msg.set_advertiser_id(advertiser_id);
449     msg.set_status(static_cast<facade::AdvertisingStatus>(status));
450     callback_events_.OnIncomingEvent(msg);
451   };
452 
OnAdvertisingParametersUpdated(uint8_t advertiser_id,int8_t,uint8_t status)453   void OnAdvertisingParametersUpdated(
454       uint8_t advertiser_id, int8_t /* tx_power */, uint8_t status) {
455     AdvertisingCallbackMsg msg;
456     msg.set_message_type(AdvertisingCallbackMsgType::ADVERTISING_PARAMETERS_UPDATED);
457     msg.set_advertiser_id(advertiser_id);
458     msg.set_status(static_cast<facade::AdvertisingStatus>(status));
459     callback_events_.OnIncomingEvent(msg);
460   };
461 
OnPeriodicAdvertisingParametersUpdated(uint8_t advertiser_id,uint8_t status)462   void OnPeriodicAdvertisingParametersUpdated(uint8_t advertiser_id, uint8_t status) {
463     AdvertisingCallbackMsg msg;
464     msg.set_message_type(AdvertisingCallbackMsgType::PERIODIC_ADVERTISING_PARAMETERS_UPDATED);
465     msg.set_advertiser_id(advertiser_id);
466     msg.set_status(static_cast<facade::AdvertisingStatus>(status));
467     callback_events_.OnIncomingEvent(msg);
468   };
469 
OnPeriodicAdvertisingDataSet(uint8_t advertiser_id,uint8_t status)470   void OnPeriodicAdvertisingDataSet(uint8_t advertiser_id, uint8_t status) {
471     AdvertisingCallbackMsg msg;
472     msg.set_message_type(AdvertisingCallbackMsgType::PERIODIC_ADVERTISING_DATA_SET);
473     msg.set_advertiser_id(advertiser_id);
474     msg.set_status(static_cast<facade::AdvertisingStatus>(status));
475     callback_events_.OnIncomingEvent(msg);
476   };
477 
OnPeriodicAdvertisingEnabled(uint8_t advertiser_id,bool,uint8_t status)478   void OnPeriodicAdvertisingEnabled(uint8_t advertiser_id, bool /* enable */, uint8_t status) {
479     AdvertisingCallbackMsg msg;
480     msg.set_message_type(AdvertisingCallbackMsgType::PERIODIC_ADVERTISING_ENABLED);
481     msg.set_advertiser_id(advertiser_id);
482     msg.set_status(static_cast<facade::AdvertisingStatus>(status));
483     callback_events_.OnIncomingEvent(msg);
484   };
485 
OnOwnAddressRead(uint8_t advertiser_id,uint8_t address_type,Address address)486   void OnOwnAddressRead(uint8_t advertiser_id, uint8_t address_type, Address address) {
487     log::info("OnOwnAddressRead Address:{}, address_type:{}", address, address_type);
488     AddressMsg msg;
489     msg.set_message_type(AdvertisingCallbackMsgType::OWN_ADDRESS_READ);
490     msg.set_advertiser_id(advertiser_id);
491     blueberry::facade::BluetoothAddressWithType facade_address;
492     facade_address.mutable_address()->set_address(address.ToString());
493     facade_address.set_type(static_cast<facade::BluetoothAddressTypeEnum>(address_type));
494     *msg.mutable_address() = facade_address;
495     address_events_.OnIncomingEvent(msg);
496   };
497 
498   std::vector<LeAdvertiser> le_advertisers_;
499   LeAdvertisingManager* le_advertising_manager_;
500   std::optional<std::promise<AdvertiserId>> pending_advertiser_id_;
501   os::Handler* facade_handler_;
502   ::bluetooth::grpc::GrpcEventQueue<AdvertisingCallbackMsg> callback_events_{"callback events"};
503   ::bluetooth::grpc::GrpcEventQueue<AddressMsg> address_events_{"address events"};
504 };
505 
ListDependencies(ModuleList * list) const506 void LeAdvertisingManagerFacadeModule::ListDependencies(ModuleList* list) const {
507   ::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
508   list->add<hci::LeAdvertisingManager>();
509 }
510 
Start()511 void LeAdvertisingManagerFacadeModule::Start() {
512   ::bluetooth::grpc::GrpcFacadeModule::Start();
513   service_ = new LeAdvertisingManagerFacadeService(GetDependency<hci::LeAdvertisingManager>(), GetHandler());
514 }
515 
Stop()516 void LeAdvertisingManagerFacadeModule::Stop() {
517   delete service_;
518   ::bluetooth::grpc::GrpcFacadeModule::Stop();
519 }
520 
GetService() const521 ::grpc::Service* LeAdvertisingManagerFacadeModule::GetService() const {
522   return service_;
523 }
524 
525 const ModuleFactory LeAdvertisingManagerFacadeModule::Factory =
__anonf76faa5f0102() 526     ::bluetooth::ModuleFactory([]() { return new LeAdvertisingManagerFacadeModule(); });
527 
528 }  // namespace facade
529 }  // namespace hci
530 }  // namespace bluetooth
531