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