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() override{};
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