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 "stack/include/btu.h"
30
31 using base::Bind;
32 using base::Owned;
33 using std::vector;
34
35 namespace {
36
37 template <typename T>
38 class OwnedArrayWrapper {
39 public:
OwnedArrayWrapper(T * o)40 explicit OwnedArrayWrapper(T* o) : ptr_(o) {}
~OwnedArrayWrapper()41 ~OwnedArrayWrapper() { delete[] ptr_; }
get() const42 T* get() const { return ptr_; }
OwnedArrayWrapper(OwnedArrayWrapper && other)43 OwnedArrayWrapper(OwnedArrayWrapper&& other) noexcept {
44 ptr_ = other.ptr_;
45 other.ptr_ = NULL;
46 }
47
48 private:
49 mutable T* ptr_;
50 };
51
52 template <typename T>
Unwrap(const OwnedArrayWrapper<T> & o)53 T* Unwrap(const OwnedArrayWrapper<T>& o) {
54 return o.get();
55 }
56
57 template <typename T>
OwnedArray(T * o)58 static inline OwnedArrayWrapper<T> OwnedArray(T* o) {
59 return OwnedArrayWrapper<T>(o);
60 }
61
parseParams(tBTM_BLE_ADV_PARAMS * p_params,const AdvertiseParameters & params)62 void parseParams(tBTM_BLE_ADV_PARAMS* p_params,
63 const AdvertiseParameters& params) {
64 p_params->advertising_event_properties = params.advertising_event_properties;
65 p_params->adv_int_min = params.min_interval;
66 p_params->adv_int_max = params.max_interval;
67 p_params->channel_map = params.channel_map;
68 p_params->adv_filter_policy = 0;
69 p_params->tx_power = params.tx_power;
70 p_params->primary_advertising_phy = params.primary_advertising_phy;
71 p_params->secondary_advertising_phy = params.secondary_advertising_phy;
72 p_params->scan_request_notification_enable =
73 params.scan_request_notification_enable;
74 }
75
parsePeriodicParams(tBLE_PERIODIC_ADV_PARAMS * p_periodic_params,PeriodicAdvertisingParameters periodic_params)76 void parsePeriodicParams(tBLE_PERIODIC_ADV_PARAMS* p_periodic_params,
77 PeriodicAdvertisingParameters periodic_params) {
78 p_periodic_params->enable = periodic_params.enable;
79 p_periodic_params->min_interval = periodic_params.min_interval;
80 p_periodic_params->max_interval = periodic_params.max_interval;
81 p_periodic_params->periodic_advertising_properties =
82 periodic_params.periodic_advertising_properties;
83 }
84
85 class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface {
~BleAdvertiserInterfaceImpl()86 ~BleAdvertiserInterfaceImpl(){};
87
RegisterAdvertiserCb(IdStatusCallback cb,uint8_t advertiser_id,uint8_t status)88 void RegisterAdvertiserCb(IdStatusCallback cb, uint8_t advertiser_id,
89 uint8_t status) {
90 LOG(INFO) << __func__ << " status: " << +status
91 << " , adveriser_id: " << +advertiser_id;
92 do_in_jni_thread(Bind(cb, advertiser_id, status));
93 }
94
RegisterAdvertiser(IdStatusCallback cb)95 void RegisterAdvertiser(IdStatusCallback cb) override {
96 do_in_main_thread(
97 FROM_HERE, Bind(&BleAdvertisingManager::RegisterAdvertiser,
98 BleAdvertisingManager::Get(),
99 Bind(&BleAdvertiserInterfaceImpl::RegisterAdvertiserCb,
100 base::Unretained(this), cb)));
101 }
102
Unregister(uint8_t advertiser_id)103 void Unregister(uint8_t advertiser_id) override {
104 do_in_main_thread(
105 FROM_HERE,
106 Bind(
107 [](uint8_t advertiser_id) {
108 if (!BleAdvertisingManager::IsInitialized()) {
109 LOG(WARNING) << "Stack already shutdown";
110 return;
111 }
112 BleAdvertisingManager::Get()->Unregister(advertiser_id);
113 },
114 advertiser_id));
115 }
116
GetOwnAddress(uint8_t advertiser_id,GetAddressCallback cb)117 void GetOwnAddress(uint8_t advertiser_id, GetAddressCallback cb) override {
118 if (!BleAdvertisingManager::IsInitialized()) return;
119 do_in_main_thread(FROM_HERE,
120 Bind(&BleAdvertisingManager::GetOwnAddress,
121 BleAdvertisingManager::Get(), advertiser_id,
122 jni_thread_wrapper(FROM_HERE, cb)));
123 }
124
SetParameters(uint8_t advertiser_id,AdvertiseParameters params,ParametersCallback cb)125 void SetParameters(uint8_t advertiser_id, AdvertiseParameters params,
126 ParametersCallback cb) override {
127 VLOG(1) << __func__;
128
129 if (!BleAdvertisingManager::IsInitialized()) return;
130 tBTM_BLE_ADV_PARAMS* p_params = new tBTM_BLE_ADV_PARAMS;
131 parseParams(p_params, params);
132
133 do_in_main_thread(FROM_HERE, Bind(&BleAdvertisingManager::SetParameters,
134 BleAdvertisingManager::Get(),
135 advertiser_id, base::Owned(p_params),
136 jni_thread_wrapper(FROM_HERE, cb)));
137 }
138
SetData(int advertiser_id,bool set_scan_rsp,vector<uint8_t> data,StatusCallback cb)139 void SetData(int advertiser_id, bool set_scan_rsp, vector<uint8_t> data,
140 StatusCallback cb) override {
141 if (!BleAdvertisingManager::IsInitialized()) return;
142 do_in_main_thread(
143 FROM_HERE,
144 Bind(&BleAdvertisingManager::SetData, BleAdvertisingManager::Get(),
145 advertiser_id, set_scan_rsp, std::move(data),
146 jni_thread_wrapper(FROM_HERE, cb)));
147 }
148
Enable(uint8_t advertiser_id,bool enable,StatusCallback cb,uint16_t duration,uint8_t maxExtAdvEvents,StatusCallback timeout_cb)149 void Enable(uint8_t advertiser_id, bool enable, StatusCallback cb,
150 uint16_t duration, uint8_t maxExtAdvEvents,
151 StatusCallback timeout_cb) override {
152 VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id
153 << " ,enable: " << enable;
154
155 if (!BleAdvertisingManager::IsInitialized()) return;
156 do_in_main_thread(
157 FROM_HERE,
158 Bind(&BleAdvertisingManager::Enable, BleAdvertisingManager::Get(),
159 advertiser_id, enable, jni_thread_wrapper(FROM_HERE, cb), duration,
160 maxExtAdvEvents, jni_thread_wrapper(FROM_HERE, timeout_cb)));
161 }
162
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)163 void StartAdvertising(uint8_t advertiser_id, StatusCallback cb,
164 AdvertiseParameters params,
165 std::vector<uint8_t> advertise_data,
166 std::vector<uint8_t> scan_response_data, int timeout_s,
167 MultiAdvCb timeout_cb) override {
168 VLOG(1) << __func__;
169
170 if (!BleAdvertisingManager::IsInitialized()) return;
171 tBTM_BLE_ADV_PARAMS* p_params = new tBTM_BLE_ADV_PARAMS;
172 parseParams(p_params, params);
173
174 do_in_main_thread(
175 FROM_HERE,
176 Bind(&BleAdvertisingManager::StartAdvertising,
177 BleAdvertisingManager::Get(), advertiser_id,
178 jni_thread_wrapper(FROM_HERE, cb), base::Owned(p_params),
179 std::move(advertise_data), std::move(scan_response_data),
180 timeout_s * 100, jni_thread_wrapper(FROM_HERE, timeout_cb)));
181 }
182
StartAdvertisingSet(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)183 void StartAdvertisingSet(IdTxPowerStatusCallback cb,
184 AdvertiseParameters params,
185 std::vector<uint8_t> advertise_data,
186 std::vector<uint8_t> scan_response_data,
187 PeriodicAdvertisingParameters periodic_params,
188 std::vector<uint8_t> periodic_data,
189 uint16_t duration, uint8_t maxExtAdvEvents,
190 IdStatusCallback timeout_cb) override {
191 VLOG(1) << __func__;
192
193 if (!BleAdvertisingManager::IsInitialized()) return;
194 tBTM_BLE_ADV_PARAMS* p_params = new tBTM_BLE_ADV_PARAMS;
195 parseParams(p_params, params);
196
197 tBLE_PERIODIC_ADV_PARAMS* p_periodic_params = new tBLE_PERIODIC_ADV_PARAMS;
198 parsePeriodicParams(p_periodic_params, periodic_params);
199
200 do_in_main_thread(
201 FROM_HERE,
202 Bind(&BleAdvertisingManager::StartAdvertisingSet,
203 BleAdvertisingManager::Get(), jni_thread_wrapper(FROM_HERE, cb),
204 base::Owned(p_params), std::move(advertise_data),
205 std::move(scan_response_data), base::Owned(p_periodic_params),
206 std::move(periodic_data), duration, maxExtAdvEvents,
207 jni_thread_wrapper(FROM_HERE, timeout_cb)));
208 }
209
SetPeriodicAdvertisingParameters(int advertiser_id,PeriodicAdvertisingParameters periodic_params,StatusCallback cb)210 void SetPeriodicAdvertisingParameters(
211 int advertiser_id, PeriodicAdvertisingParameters periodic_params,
212 StatusCallback cb) override {
213 VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id;
214
215 if (!BleAdvertisingManager::IsInitialized()) return;
216 tBLE_PERIODIC_ADV_PARAMS* p_periodic_params = new tBLE_PERIODIC_ADV_PARAMS;
217 parsePeriodicParams(p_periodic_params, periodic_params);
218
219 do_in_main_thread(
220 FROM_HERE,
221 Bind(&BleAdvertisingManager::SetPeriodicAdvertisingParameters,
222 BleAdvertisingManager::Get(), advertiser_id,
223 base::Owned(p_periodic_params),
224 jni_thread_wrapper(FROM_HERE, cb)));
225 }
226
SetPeriodicAdvertisingData(int advertiser_id,std::vector<uint8_t> data,StatusCallback cb)227 void SetPeriodicAdvertisingData(int advertiser_id, std::vector<uint8_t> data,
228 StatusCallback cb) override {
229 VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id;
230
231 if (!BleAdvertisingManager::IsInitialized()) return;
232 do_in_main_thread(FROM_HERE,
233 Bind(&BleAdvertisingManager::SetPeriodicAdvertisingData,
234 BleAdvertisingManager::Get(), advertiser_id,
235 std::move(data), jni_thread_wrapper(FROM_HERE, cb)));
236 }
237
SetPeriodicAdvertisingEnable(int advertiser_id,bool enable,StatusCallback cb)238 void SetPeriodicAdvertisingEnable(int advertiser_id, bool enable,
239 StatusCallback cb) override {
240 VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id
241 << " ,enable: " << enable;
242
243 if (!BleAdvertisingManager::IsInitialized()) return;
244 do_in_main_thread(FROM_HERE,
245 Bind(&BleAdvertisingManager::SetPeriodicAdvertisingEnable,
246 BleAdvertisingManager::Get(), advertiser_id, enable,
247 jni_thread_wrapper(FROM_HERE, cb)));
248 }
249 };
250
251 BleAdvertiserInterface* btLeAdvertiserInstance = nullptr;
252
253 } // namespace
254
get_ble_advertiser_instance()255 BleAdvertiserInterface* get_ble_advertiser_instance() {
256 if (btLeAdvertiserInstance == nullptr)
257 btLeAdvertiserInstance = new BleAdvertiserInterfaceImpl();
258
259 return btLeAdvertiserInstance;
260 }
261