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