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