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