• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 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 #define LOG_TAG "bt_shim_advertiser"
18 
19 #include "le_advertising_manager.h"
20 
21 #include <hardware/bluetooth.h>
22 #include <hardware/bt_gatt.h>
23 
24 #include <vector>
25 #include "gd/common/init_flags.h"
26 #include "gd/hci/acl_manager.h"
27 #include "gd/hci/controller.h"
28 #include "gd/hci/le_advertising_manager.h"
29 #include "gd/packet/packet_view.h"
30 #include "gd/storage/storage_module.h"
31 #include "main/shim/entry.h"
32 
33 #include "btif/include/btif_common.h"
34 #include "stack/include/ble_advertiser.h"
35 #include "stack/include/btm_api.h"
36 #include "stack/include/btu.h"
37 
38 using bluetooth::hci::Address;
39 using bluetooth::hci::AddressType;
40 using bluetooth::hci::ErrorCode;
41 using bluetooth::hci::GapData;
42 using bluetooth::hci::OwnAddressType;
43 using std::vector;
44 
45 class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface,
46                                    public bluetooth::hci::AdvertisingCallback {
47  public:
~BleAdvertiserInterfaceImpl()48   ~BleAdvertiserInterfaceImpl() override{};
49 
Init()50   void Init() {
51     // Register callback
52     bluetooth::shim::GetAdvertising()->RegisterAdvertisingCallback(this);
53   }
54 
55   // nobody use this function
RegisterAdvertiser(IdStatusCallback cb)56   void RegisterAdvertiser(IdStatusCallback cb) override {
57     LOG(INFO) << __func__ << " in shim layer";
58   }
59 
Unregister(uint8_t advertiser_id)60   void Unregister(uint8_t advertiser_id) override {
61     LOG(INFO) << __func__ << " in shim layer";
62     bluetooth::shim::GetAdvertising()->RemoveAdvertiser(advertiser_id);
63   }
64 
65   // only for PTS test
GetOwnAddress(uint8_t advertiser_id,GetAddressCallback cb)66   void GetOwnAddress(uint8_t advertiser_id, GetAddressCallback cb) override {
67     LOG(INFO) << __func__ << " in shim layer";
68   }
69 
SetParameters(uint8_t advertiser_id,AdvertiseParameters params,ParametersCallback cb)70   void SetParameters(uint8_t advertiser_id, AdvertiseParameters params,
71                      ParametersCallback cb) override {
72     LOG(INFO) << __func__ << " in shim layer";
73     bluetooth::hci::ExtendedAdvertisingConfig config{};
74     parse_parameter(config, params);
75     bluetooth::shim::GetAdvertising()->SetParameters(advertiser_id, config);
76   }
77 
SetData(int advertiser_id,bool set_scan_rsp,vector<uint8_t> data,StatusCallback cb)78   void SetData(int advertiser_id, bool set_scan_rsp, vector<uint8_t> data,
79                StatusCallback cb) override {
80     LOG(INFO) << __func__ << " in shim layer";
81 
82     size_t offset = 0;
83     std::vector<GapData> advertising_data = {};
84 
85     while (offset < data.size()) {
86       GapData gap_data;
87       uint8_t len = data[offset];
88       auto begin = data.begin() + offset;
89       auto end = begin + len + 1;  // 1 byte for len
90       auto data_copy = std::make_shared<std::vector<uint8_t>>(begin, end);
91       bluetooth::packet::PacketView<bluetooth::packet::kLittleEndian> packet(
92           data_copy);
93       GapData::Parse(&gap_data, packet.begin());
94       advertising_data.push_back(gap_data);
95       offset += len + 1;  // 1 byte for len
96     }
97 
98     bluetooth::shim::GetAdvertising()->SetData(advertiser_id, set_scan_rsp,
99                                                advertising_data);
100   }
101 
Enable(uint8_t advertiser_id,bool enable,StatusCallback cb,uint16_t duration,uint8_t maxExtAdvEvents,StatusCallback timeout_cb)102   void Enable(uint8_t advertiser_id, bool enable, StatusCallback cb,
103               uint16_t duration, uint8_t maxExtAdvEvents,
104               StatusCallback timeout_cb) override {
105     LOG(INFO) << __func__ << " in shim layer";
106     bluetooth::shim::GetAdvertising()->EnableAdvertiser(
107         advertiser_id, enable, duration, maxExtAdvEvents);
108   }
109 
110   // nobody use this function
StartAdvertising(uint8_t advertiser_id,StatusCallback cb,AdvertiseParameters params,std::vector<uint8_t> advertise_data,std::vector<uint8_t> scan_response_data,int timeout_s,MultiAdvCb timeout_cb)111   void StartAdvertising(uint8_t advertiser_id, StatusCallback cb,
112                         AdvertiseParameters params,
113                         std::vector<uint8_t> advertise_data,
114                         std::vector<uint8_t> scan_response_data, int timeout_s,
115                         MultiAdvCb timeout_cb) override {
116     LOG(INFO) << __func__ << " in shim layer";
117   }
118 
StartAdvertisingSet(int reg_id,IdTxPowerStatusCallback register_cb,AdvertiseParameters params,std::vector<uint8_t> advertise_data,std::vector<uint8_t> scan_response_data,PeriodicAdvertisingParameters periodic_params,std::vector<uint8_t> periodic_data,uint16_t duration,uint8_t maxExtAdvEvents,IdStatusCallback timeout_cb)119   void StartAdvertisingSet(int reg_id, IdTxPowerStatusCallback register_cb,
120                            AdvertiseParameters params,
121                            std::vector<uint8_t> advertise_data,
122                            std::vector<uint8_t> scan_response_data,
123                            PeriodicAdvertisingParameters periodic_params,
124                            std::vector<uint8_t> periodic_data,
125                            uint16_t duration, uint8_t maxExtAdvEvents,
126                            IdStatusCallback timeout_cb) {
127     LOG(INFO) << __func__ << " in shim layer";
128 
129     bluetooth::hci::ExtendedAdvertisingConfig config{};
130     parse_parameter(config, params);
131     bluetooth::hci::PeriodicAdvertisingParameters periodic_parameters;
132     periodic_parameters.max_interval = periodic_params.max_interval;
133     periodic_parameters.min_interval = periodic_params.min_interval;
134     periodic_parameters.properties =
135         periodic_params.periodic_advertising_properties;
136     config.periodic_advertising_parameters = periodic_parameters;
137 
138     size_t offset = 0;
139     while (offset < advertise_data.size()) {
140       GapData gap_data;
141       uint8_t len = advertise_data[offset];
142       auto begin = advertise_data.begin() + offset;
143       auto end = begin + len + 1;  // 1 byte for len
144       auto data_copy = std::make_shared<std::vector<uint8_t>>(begin, end);
145       bluetooth::packet::PacketView<bluetooth::packet::kLittleEndian> packet(
146           data_copy);
147       GapData::Parse(&gap_data, packet.begin());
148       config.advertisement.push_back(gap_data);
149       offset += len + 1;  // 1 byte for len
150     }
151 
152     offset = 0;
153     while (offset < scan_response_data.size()) {
154       GapData gap_data;
155       uint8_t len = scan_response_data[offset];
156       auto begin = scan_response_data.begin() + offset;
157       auto end = begin + len + 1;  // 1 byte for len
158       auto data_copy = std::make_shared<std::vector<uint8_t>>(begin, end);
159       bluetooth::packet::PacketView<bluetooth::packet::kLittleEndian> packet(
160           data_copy);
161       GapData::Parse(&gap_data, packet.begin());
162       config.scan_response.push_back(gap_data);
163       offset += len + 1;  // 1 byte for len
164     }
165 
166     offset = 0;
167     while (offset < periodic_data.size()) {
168       GapData gap_data;
169       uint8_t len = periodic_data[offset];
170       auto begin = periodic_data.begin() + offset;
171       auto end = begin + len + 1;  // 1 byte for len
172       auto data_copy = std::make_shared<std::vector<uint8_t>>(begin, end);
173       bluetooth::packet::PacketView<bluetooth::packet::kLittleEndian> packet(
174           data_copy);
175       GapData::Parse(&gap_data, packet.begin());
176       config.periodic_data.push_back(gap_data);
177       offset += len + 1;  // 1 byte for len
178     }
179 
180     bluetooth::hci::AdvertiserId id =
181         bluetooth::shim::GetAdvertising()->ExtendedCreateAdvertiser(
182             reg_id, config, scan_callback, set_terminated_callback, duration,
183             maxExtAdvEvents, bluetooth::shim::GetGdShimHandler());
184 
185     LOG(INFO) << "create advertising set, reg_id:" << reg_id
186               << ", id:" << (uint16_t)id;
187   }
188 
SetPeriodicAdvertisingParameters(int advertiser_id,PeriodicAdvertisingParameters periodic_params,StatusCallback cb)189   void SetPeriodicAdvertisingParameters(
190       int advertiser_id, PeriodicAdvertisingParameters periodic_params,
191       StatusCallback cb) override {
192     LOG(INFO) << __func__ << " in shim layer";
193     bluetooth::hci::PeriodicAdvertisingParameters parameters;
194     parameters.max_interval = periodic_params.max_interval;
195     parameters.min_interval = periodic_params.min_interval;
196     parameters.properties = periodic_params.periodic_advertising_properties;
197     bluetooth::shim::GetAdvertising()->SetPeriodicParameters(advertiser_id,
198                                                              parameters);
199   }
200 
SetPeriodicAdvertisingData(int advertiser_id,std::vector<uint8_t> data,StatusCallback cb)201   void SetPeriodicAdvertisingData(int advertiser_id, std::vector<uint8_t> data,
202                                   StatusCallback cb) override {
203     LOG(INFO) << __func__ << " in shim layer";
204 
205     size_t offset = 0;
206     std::vector<GapData> advertising_data = {};
207 
208     while (offset < data.size()) {
209       GapData gap_data;
210       uint8_t len = data[offset];
211       auto begin = data.begin() + offset;
212       auto end = begin + len + 1;  // 1 byte for len
213       auto data_copy = std::make_shared<std::vector<uint8_t>>(begin, end);
214       bluetooth::packet::PacketView<bluetooth::packet::kLittleEndian> packet(
215           data_copy);
216       GapData::Parse(&gap_data, packet.begin());
217       advertising_data.push_back(gap_data);
218       offset += len + 1;  // 1 byte for len
219     }
220 
221     bluetooth::shim::GetAdvertising()->SetPeriodicData(advertiser_id,
222                                                        advertising_data);
223   }
224 
SetPeriodicAdvertisingEnable(int advertiser_id,bool enable,StatusCallback cb)225   void SetPeriodicAdvertisingEnable(int advertiser_id, bool enable,
226                                     StatusCallback cb) override {
227     LOG(INFO) << __func__ << " in shim layer";
228     bluetooth::shim::GetAdvertising()->EnablePeriodicAdvertising(advertiser_id,
229                                                                  enable);
230   }
231 
RegisterCallbacks(AdvertisingCallbacks * callbacks)232   void RegisterCallbacks(AdvertisingCallbacks* callbacks) {
233     advertising_callbacks_ = callbacks;
234   }
235 
on_scan(Address address,AddressType address_type)236   void on_scan(Address address, AddressType address_type) {
237     LOG(INFO) << __func__ << " in shim layer";
238   }
239 
on_set_terminated(ErrorCode error_code,uint8_t,uint8_t)240   void on_set_terminated(ErrorCode error_code, uint8_t, uint8_t) {
241     LOG(INFO) << __func__ << " in shim layer";
242   }
243 
244   const bluetooth::common::Callback<void(Address, AddressType)> scan_callback =
245       bluetooth::common::Bind(&BleAdvertiserInterfaceImpl::on_scan,
246                               bluetooth::common::Unretained(this));
247 
248   const bluetooth::common::Callback<void(ErrorCode, uint8_t, uint8_t)>
249       set_terminated_callback = bluetooth::common::Bind(
250           &BleAdvertiserInterfaceImpl::on_set_terminated,
251           bluetooth::common::Unretained(this));
252 
253   // AdvertisingCallback
OnAdvertisingSetStarted(int reg_id,uint8_t advertiser_id,int8_t tx_power,AdvertisingStatus status)254   void OnAdvertisingSetStarted(int reg_id, uint8_t advertiser_id,
255                                int8_t tx_power,
256                                AdvertisingStatus status) override {
257     do_in_jni_thread(
258         FROM_HERE, base::Bind(&AdvertisingCallbacks::OnAdvertisingSetStarted,
259                               base::Unretained(advertising_callbacks_), reg_id,
260                               advertiser_id, tx_power, status));
261   }
262 
OnAdvertisingEnabled(uint8_t advertiser_id,bool enable,uint8_t status)263   void OnAdvertisingEnabled(uint8_t advertiser_id, bool enable,
264                             uint8_t status) {
265     do_in_jni_thread(FROM_HERE,
266                      base::Bind(&AdvertisingCallbacks::OnAdvertisingEnabled,
267                                 base::Unretained(advertising_callbacks_),
268                                 advertiser_id, enable, status));
269   }
270 
OnAdvertisingDataSet(uint8_t advertiser_id,uint8_t status)271   void OnAdvertisingDataSet(uint8_t advertiser_id, uint8_t status) {
272     do_in_jni_thread(FROM_HERE,
273                      base::Bind(&AdvertisingCallbacks::OnAdvertisingDataSet,
274                                 base::Unretained(advertising_callbacks_),
275                                 advertiser_id, status));
276   }
OnScanResponseDataSet(uint8_t advertiser_id,uint8_t status)277   void OnScanResponseDataSet(uint8_t advertiser_id, uint8_t status) {
278     do_in_jni_thread(FROM_HERE,
279                      base::Bind(&AdvertisingCallbacks::OnScanResponseDataSet,
280                                 base::Unretained(advertising_callbacks_),
281                                 advertiser_id, status));
282   }
283 
OnAdvertisingParametersUpdated(uint8_t advertiser_id,int8_t tx_power,uint8_t status)284   void OnAdvertisingParametersUpdated(uint8_t advertiser_id, int8_t tx_power,
285                                       uint8_t status) {
286     do_in_jni_thread(
287         FROM_HERE,
288         base::Bind(&AdvertisingCallbacks::OnAdvertisingParametersUpdated,
289                    base::Unretained(advertising_callbacks_), advertiser_id,
290                    tx_power, status));
291   }
292 
OnPeriodicAdvertisingParametersUpdated(uint8_t advertiser_id,uint8_t status)293   void OnPeriodicAdvertisingParametersUpdated(uint8_t advertiser_id,
294                                               uint8_t status) {
295     do_in_jni_thread(
296         FROM_HERE,
297         base::Bind(
298             &AdvertisingCallbacks::OnPeriodicAdvertisingParametersUpdated,
299             base::Unretained(advertising_callbacks_), advertiser_id, status));
300   }
301 
OnPeriodicAdvertisingDataSet(uint8_t advertiser_id,uint8_t status)302   void OnPeriodicAdvertisingDataSet(uint8_t advertiser_id, uint8_t status) {
303     do_in_jni_thread(
304         FROM_HERE,
305         base::Bind(&AdvertisingCallbacks::OnPeriodicAdvertisingDataSet,
306                    base::Unretained(advertising_callbacks_), advertiser_id,
307                    status));
308   }
309 
OnPeriodicAdvertisingEnabled(uint8_t advertiser_id,bool enable,uint8_t status)310   void OnPeriodicAdvertisingEnabled(uint8_t advertiser_id, bool enable,
311                                     uint8_t status) {
312     do_in_jni_thread(
313         FROM_HERE,
314         base::Bind(&AdvertisingCallbacks::OnPeriodicAdvertisingEnabled,
315                    base::Unretained(advertising_callbacks_), advertiser_id,
316                    enable, status));
317   }
318 
OnOwnAddressRead(uint8_t advertiser_id,uint8_t address_type,RawAddress address)319   void OnOwnAddressRead(uint8_t advertiser_id, uint8_t address_type,
320                         RawAddress address) {
321     do_in_jni_thread(FROM_HERE,
322                      base::Bind(&AdvertisingCallbacks::OnOwnAddressRead,
323                                 base::Unretained(advertising_callbacks_),
324                                 advertiser_id, address_type, address));
325   }
326 
327   AdvertisingCallbacks* advertising_callbacks_;
328 
329  private:
parse_parameter(bluetooth::hci::ExtendedAdvertisingConfig & config,AdvertiseParameters params)330   void parse_parameter(bluetooth::hci::ExtendedAdvertisingConfig& config,
331                        AdvertiseParameters params) {
332     config.connectable = params.advertising_event_properties & 0x01;
333     config.scannable = params.advertising_event_properties & 0x02;
334     config.legacy_pdus = params.advertising_event_properties & 0x10;
335     config.anonymous = params.advertising_event_properties & 0x20;
336     config.include_tx_power = params.advertising_event_properties & 0x40;
337     config.interval_min = params.min_interval;
338     config.interval_max = params.max_interval;
339     config.channel_map = params.channel_map;
340     config.tx_power = params.tx_power;
341     config.use_le_coded_phy = params.primary_advertising_phy == 0x03;
342     config.secondary_advertising_phy =
343         static_cast<bluetooth::hci::SecondaryPhyType>(
344             params.secondary_advertising_phy);
345     config.enable_scan_request_notifications =
346         static_cast<bluetooth::hci::Enable>(
347             params.scan_request_notification_enable);
348 
349     // TODO set own_address_type based on address policy
350     config.own_address_type = OwnAddressType::RANDOM_DEVICE_ADDRESS;
351   }
352 };
353 
354 BleAdvertiserInterfaceImpl* bt_le_advertiser_instance = nullptr;
355 
get_ble_advertiser_instance()356 BleAdvertiserInterface* bluetooth::shim::get_ble_advertiser_instance() {
357   if (bt_le_advertiser_instance == nullptr) {
358     bt_le_advertiser_instance = new BleAdvertiserInterfaceImpl();
359   }
360   return bt_le_advertiser_instance;
361 };
362 
init_advertising_manager()363 void bluetooth::shim::init_advertising_manager() {
364   bt_le_advertiser_instance->Init();
365 }
366