1 /******************************************************************************
2 *
3 * Copyright 2016 Google Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 #define LOG_TAG "bt_btif_ble_advertiser"
20
21 #include <hardware/bluetooth.h>
22 #include <hardware/bt_gatt.h>
23
24 #include <base/bind.h>
25 #include <vector>
26
27 #include "ble_advertiser.h"
28 #include "btif_common.h"
29 #include "main/shim/le_advertising_manager.h"
30 #include "main/shim/shim.h"
31 #include "stack/include/btu.h"
32
33 using base::Bind;
34 using base::Owned;
35 using std::vector;
36
37 namespace {
38
39 template <typename T>
40 class OwnedArrayWrapper {
41 public:
OwnedArrayWrapper(T * o)42 explicit OwnedArrayWrapper(T* o) : ptr_(o) {}
~OwnedArrayWrapper()43 ~OwnedArrayWrapper() { delete[] ptr_; }
get() const44 T* get() const { return ptr_; }
OwnedArrayWrapper(OwnedArrayWrapper && other)45 OwnedArrayWrapper(OwnedArrayWrapper&& other) noexcept {
46 ptr_ = other.ptr_;
47 other.ptr_ = NULL;
48 }
49
50 private:
51 mutable T* ptr_;
52 };
53
54 template <typename T>
Unwrap(const OwnedArrayWrapper<T> & o)55 T* Unwrap(const OwnedArrayWrapper<T>& o) {
56 return o.get();
57 }
58
59 template <typename T>
OwnedArray(T * o)60 static inline OwnedArrayWrapper<T> OwnedArray(T* o) {
61 return OwnedArrayWrapper<T>(o);
62 }
63
parseParams(tBTM_BLE_ADV_PARAMS * p_params,const AdvertiseParameters & params)64 void parseParams(tBTM_BLE_ADV_PARAMS* p_params,
65 const AdvertiseParameters& params) {
66 p_params->advertising_event_properties = params.advertising_event_properties;
67 p_params->adv_int_min = params.min_interval;
68 p_params->adv_int_max = params.max_interval;
69 p_params->channel_map = params.channel_map;
70 p_params->adv_filter_policy = 0;
71 p_params->tx_power = params.tx_power;
72 p_params->primary_advertising_phy = params.primary_advertising_phy;
73 p_params->secondary_advertising_phy = params.secondary_advertising_phy;
74 p_params->scan_request_notification_enable =
75 params.scan_request_notification_enable;
76 }
77
parsePeriodicParams(tBLE_PERIODIC_ADV_PARAMS * p_periodic_params,PeriodicAdvertisingParameters periodic_params)78 void parsePeriodicParams(tBLE_PERIODIC_ADV_PARAMS* p_periodic_params,
79 PeriodicAdvertisingParameters periodic_params) {
80 p_periodic_params->enable = periodic_params.enable;
81 p_periodic_params->min_interval = periodic_params.min_interval;
82 p_periodic_params->max_interval = periodic_params.max_interval;
83 p_periodic_params->periodic_advertising_properties =
84 periodic_params.periodic_advertising_properties;
85 }
86
87 class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface {
~BleAdvertiserInterfaceImpl()88 ~BleAdvertiserInterfaceImpl() override{};
89
RegisterAdvertiserCb(IdStatusCallback cb,uint8_t advertiser_id,uint8_t status)90 void RegisterAdvertiserCb(IdStatusCallback cb, uint8_t advertiser_id,
91 uint8_t status) {
92 LOG(INFO) << __func__ << " status: " << +status
93 << " , adveriser_id: " << +advertiser_id;
94 do_in_jni_thread(Bind(cb, advertiser_id, status));
95 }
96
RegisterAdvertiser(IdStatusCallback cb)97 void RegisterAdvertiser(IdStatusCallback cb) override {
98 do_in_main_thread(
99 FROM_HERE, Bind(&BleAdvertisingManager::RegisterAdvertiser,
100 BleAdvertisingManager::Get(),
101 Bind(&BleAdvertiserInterfaceImpl::RegisterAdvertiserCb,
102 base::Unretained(this), cb)));
103 }
104
Unregister(uint8_t advertiser_id)105 void Unregister(uint8_t advertiser_id) override {
106 do_in_main_thread(
107 FROM_HERE,
108 Bind(
109 [](uint8_t advertiser_id) {
110 if (!BleAdvertisingManager::IsInitialized()) {
111 LOG(WARNING) << "Stack already shutdown";
112 return;
113 }
114 BleAdvertisingManager::Get()->Unregister(advertiser_id);
115 },
116 advertiser_id));
117 }
118
GetOwnAddress(uint8_t advertiser_id,GetAddressCallback cb)119 void GetOwnAddress(uint8_t advertiser_id, GetAddressCallback cb) override {
120 if (!BleAdvertisingManager::IsInitialized()) return;
121 do_in_main_thread(FROM_HERE,
122 Bind(&BleAdvertisingManager::GetOwnAddress,
123 BleAdvertisingManager::Get(), advertiser_id,
124 jni_thread_wrapper(FROM_HERE, cb)));
125 }
126
SetParameters(uint8_t advertiser_id,AdvertiseParameters params,ParametersCallback cb)127 void SetParameters(uint8_t advertiser_id, AdvertiseParameters params,
128 ParametersCallback cb) override {
129 VLOG(1) << __func__;
130
131 if (!BleAdvertisingManager::IsInitialized()) return;
132 tBTM_BLE_ADV_PARAMS* p_params = new tBTM_BLE_ADV_PARAMS;
133 parseParams(p_params, params);
134
135 do_in_main_thread(FROM_HERE, Bind(&BleAdvertisingManager::SetParameters,
136 BleAdvertisingManager::Get(),
137 advertiser_id, base::Owned(p_params),
138 jni_thread_wrapper(FROM_HERE, cb)));
139 }
140
SetData(int advertiser_id,bool set_scan_rsp,vector<uint8_t> data,StatusCallback cb)141 void SetData(int advertiser_id, bool set_scan_rsp, vector<uint8_t> data,
142 StatusCallback cb) override {
143 if (!BleAdvertisingManager::IsInitialized()) return;
144 do_in_main_thread(
145 FROM_HERE,
146 Bind(&BleAdvertisingManager::SetData, BleAdvertisingManager::Get(),
147 advertiser_id, set_scan_rsp, std::move(data),
148 jni_thread_wrapper(FROM_HERE, cb)));
149 }
150
Enable(uint8_t advertiser_id,bool enable,StatusCallback cb,uint16_t duration,uint8_t maxExtAdvEvents,StatusCallback timeout_cb)151 void Enable(uint8_t advertiser_id, bool enable, StatusCallback cb,
152 uint16_t duration, uint8_t maxExtAdvEvents,
153 StatusCallback timeout_cb) override {
154 VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id
155 << " ,enable: " << enable;
156
157 if (!BleAdvertisingManager::IsInitialized()) return;
158 do_in_main_thread(
159 FROM_HERE,
160 Bind(&BleAdvertisingManager::Enable, BleAdvertisingManager::Get(),
161 advertiser_id, enable, jni_thread_wrapper(FROM_HERE, cb), duration,
162 maxExtAdvEvents, jni_thread_wrapper(FROM_HERE, timeout_cb)));
163 }
164
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)165 void StartAdvertising(uint8_t advertiser_id, StatusCallback cb,
166 AdvertiseParameters params,
167 std::vector<uint8_t> advertise_data,
168 std::vector<uint8_t> scan_response_data, int timeout_s,
169 MultiAdvCb timeout_cb) override {
170 VLOG(1) << __func__;
171
172 if (!BleAdvertisingManager::IsInitialized()) return;
173 tBTM_BLE_ADV_PARAMS* p_params = new tBTM_BLE_ADV_PARAMS;
174 parseParams(p_params, params);
175
176 do_in_main_thread(
177 FROM_HERE,
178 Bind(&BleAdvertisingManager::StartAdvertising,
179 BleAdvertisingManager::Get(), advertiser_id,
180 jni_thread_wrapper(FROM_HERE, cb), base::Owned(p_params),
181 std::move(advertise_data), std::move(scan_response_data),
182 timeout_s * 100, jni_thread_wrapper(FROM_HERE, timeout_cb)));
183 }
184
StartAdvertisingSet(int reg_id,IdTxPowerStatusCallback 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)185 void StartAdvertisingSet(int reg_id, IdTxPowerStatusCallback cb,
186 AdvertiseParameters params,
187 std::vector<uint8_t> advertise_data,
188 std::vector<uint8_t> scan_response_data,
189 PeriodicAdvertisingParameters periodic_params,
190 std::vector<uint8_t> periodic_data,
191 uint16_t duration, uint8_t maxExtAdvEvents,
192 IdStatusCallback timeout_cb) override {
193 VLOG(1) << __func__;
194
195 if (!BleAdvertisingManager::IsInitialized()) return;
196 tBTM_BLE_ADV_PARAMS* p_params = new tBTM_BLE_ADV_PARAMS;
197 parseParams(p_params, params);
198
199 tBLE_PERIODIC_ADV_PARAMS* p_periodic_params = new tBLE_PERIODIC_ADV_PARAMS;
200 parsePeriodicParams(p_periodic_params, periodic_params);
201
202 do_in_main_thread(
203 FROM_HERE,
204 Bind(&BleAdvertisingManager::StartAdvertisingSet,
205 BleAdvertisingManager::Get(), jni_thread_wrapper(FROM_HERE, cb),
206 base::Owned(p_params), std::move(advertise_data),
207 std::move(scan_response_data), base::Owned(p_periodic_params),
208 std::move(periodic_data), duration, maxExtAdvEvents,
209 jni_thread_wrapper(FROM_HERE, timeout_cb)));
210 }
211
SetPeriodicAdvertisingParameters(int advertiser_id,PeriodicAdvertisingParameters periodic_params,StatusCallback cb)212 void SetPeriodicAdvertisingParameters(
213 int advertiser_id, PeriodicAdvertisingParameters periodic_params,
214 StatusCallback cb) override {
215 VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id;
216
217 if (!BleAdvertisingManager::IsInitialized()) return;
218 tBLE_PERIODIC_ADV_PARAMS* p_periodic_params = new tBLE_PERIODIC_ADV_PARAMS;
219 parsePeriodicParams(p_periodic_params, periodic_params);
220
221 do_in_main_thread(
222 FROM_HERE,
223 Bind(&BleAdvertisingManager::SetPeriodicAdvertisingParameters,
224 BleAdvertisingManager::Get(), advertiser_id,
225 base::Owned(p_periodic_params),
226 jni_thread_wrapper(FROM_HERE, cb)));
227 }
228
SetPeriodicAdvertisingData(int advertiser_id,std::vector<uint8_t> data,StatusCallback cb)229 void SetPeriodicAdvertisingData(int advertiser_id, std::vector<uint8_t> data,
230 StatusCallback cb) override {
231 VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id;
232
233 if (!BleAdvertisingManager::IsInitialized()) return;
234 do_in_main_thread(FROM_HERE,
235 Bind(&BleAdvertisingManager::SetPeriodicAdvertisingData,
236 BleAdvertisingManager::Get(), advertiser_id,
237 std::move(data), jni_thread_wrapper(FROM_HERE, cb)));
238 }
239
SetPeriodicAdvertisingEnable(int advertiser_id,bool enable,StatusCallback cb)240 void SetPeriodicAdvertisingEnable(int advertiser_id, bool enable,
241 StatusCallback cb) override {
242 VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id
243 << " ,enable: " << enable;
244
245 if (!BleAdvertisingManager::IsInitialized()) return;
246 do_in_main_thread(FROM_HERE,
247 Bind(&BleAdvertisingManager::SetPeriodicAdvertisingEnable,
248 BleAdvertisingManager::Get(), advertiser_id, enable,
249 jni_thread_wrapper(FROM_HERE, cb)));
250 }
251
RegisterCallbacks(AdvertisingCallbacks * callbacks)252 void RegisterCallbacks(AdvertisingCallbacks* callbacks) {
253 // For GD only
254 }
255 };
256
257 BleAdvertiserInterface* btLeAdvertiserInstance = nullptr;
258
259 } // namespace
260
get_ble_advertiser_instance()261 BleAdvertiserInterface* get_ble_advertiser_instance() {
262 if (bluetooth::shim::is_gd_advertising_enabled()) {
263 LOG(INFO) << __func__ << " use gd le advertiser";
264 return bluetooth::shim::get_ble_advertiser_instance();
265 } else if (btLeAdvertiserInstance == nullptr) {
266 btLeAdvertiserInstance = new BleAdvertiserInterfaceImpl();
267 }
268
269 return btLeAdvertiserInstance;
270 }
271