1/******************************************************************************
2 *
3 *  Copyright (C) 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 "bta_closure_api.h"
29#include "btif_common.h"
30
31using base::Bind;
32using base::Owned;
33using std::vector;
34
35namespace {
36
37template <typename T>
38class OwnedArrayWrapper {
39 public:
40  explicit OwnedArrayWrapper(T* o) : ptr_(o) {}
41  ~OwnedArrayWrapper() { delete[] ptr_; }
42  T* get() const { return ptr_; }
43  OwnedArrayWrapper(OwnedArrayWrapper&& other) {
44    ptr_ = other.ptr_;
45    other.ptr_ = NULL;
46  }
47
48 private:
49  mutable T* ptr_;
50};
51
52template <typename T>
53T* Unwrap(const OwnedArrayWrapper<T>& o) {
54  return o.get();
55}
56
57template <typename T>
58static inline OwnedArrayWrapper<T> OwnedArray(T* o) {
59  return OwnedArrayWrapper<T>(o);
60}
61
62void 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
76void 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
85class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface {
86  ~BleAdvertiserInterfaceImpl(){};
87
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
95  void RegisterAdvertiser(IdStatusCallback cb) override {
96    do_in_bta_thread(
97        FROM_HERE, Bind(&BleAdvertisingManager::RegisterAdvertiser,
98                        base::Unretained(BleAdvertisingManager::Get()),
99                        Bind(&BleAdvertiserInterfaceImpl::RegisterAdvertiserCb,
100                             base::Unretained(this), cb)));
101  }
102
103  void Unregister(uint8_t advertiser_id) override {
104    do_in_bta_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
117  void GetOwnAddress(uint8_t advertiser_id, GetAddressCallback cb) override {
118    do_in_bta_thread(FROM_HERE,
119                     Bind(&BleAdvertisingManager::GetOwnAddress,
120                          base::Unretained(BleAdvertisingManager::Get()),
121                          advertiser_id, jni_thread_wrapper(FROM_HERE, cb)));
122  }
123
124  void SetParameters(uint8_t advertiser_id, AdvertiseParameters params,
125                     ParametersCallback cb) override {
126    VLOG(1) << __func__;
127
128    tBTM_BLE_ADV_PARAMS* p_params = new tBTM_BLE_ADV_PARAMS;
129    parseParams(p_params, params);
130
131    do_in_bta_thread(
132        FROM_HERE,
133        Bind(&BleAdvertisingManager::SetParameters,
134             base::Unretained(BleAdvertisingManager::Get()), advertiser_id,
135             base::Owned(p_params), jni_thread_wrapper(FROM_HERE, cb)));
136  }
137
138  void SetData(int advertiser_id, bool set_scan_rsp, vector<uint8_t> data,
139               StatusCallback cb) override {
140    do_in_bta_thread(
141        FROM_HERE,
142        Bind(&BleAdvertisingManager::SetData,
143             base::Unretained(BleAdvertisingManager::Get()), advertiser_id,
144             set_scan_rsp, std::move(data), jni_thread_wrapper(FROM_HERE, cb)));
145  }
146
147  void Enable(uint8_t advertiser_id, bool enable, StatusCallback cb,
148              uint16_t duration, uint8_t maxExtAdvEvents,
149              StatusCallback timeout_cb) override {
150    VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id
151            << " ,enable: " << enable;
152
153    do_in_bta_thread(
154        FROM_HERE,
155        Bind(&BleAdvertisingManager::Enable,
156             base::Unretained(BleAdvertisingManager::Get()), advertiser_id,
157             enable, jni_thread_wrapper(FROM_HERE, cb), duration,
158             maxExtAdvEvents, jni_thread_wrapper(FROM_HERE, timeout_cb)));
159  }
160
161  void StartAdvertising(uint8_t advertiser_id, StatusCallback cb,
162                        AdvertiseParameters params,
163                        std::vector<uint8_t> advertise_data,
164                        std::vector<uint8_t> scan_response_data, int timeout_s,
165                        MultiAdvCb timeout_cb) override {
166    VLOG(1) << __func__;
167
168    tBTM_BLE_ADV_PARAMS* p_params = new tBTM_BLE_ADV_PARAMS;
169    parseParams(p_params, params);
170
171    do_in_bta_thread(
172        FROM_HERE,
173        Bind(&BleAdvertisingManager::StartAdvertising,
174             base::Unretained(BleAdvertisingManager::Get()), advertiser_id,
175             jni_thread_wrapper(FROM_HERE, cb), base::Owned(p_params),
176             std::move(advertise_data), std::move(scan_response_data),
177             timeout_s * 100, jni_thread_wrapper(FROM_HERE, timeout_cb)));
178  }
179
180  void StartAdvertisingSet(IdTxPowerStatusCallback cb,
181                           AdvertiseParameters params,
182                           std::vector<uint8_t> advertise_data,
183                           std::vector<uint8_t> scan_response_data,
184                           PeriodicAdvertisingParameters periodic_params,
185                           std::vector<uint8_t> periodic_data,
186                           uint16_t duration, uint8_t maxExtAdvEvents,
187                           IdStatusCallback timeout_cb) override {
188    VLOG(1) << __func__;
189
190    tBTM_BLE_ADV_PARAMS* p_params = new tBTM_BLE_ADV_PARAMS;
191    parseParams(p_params, params);
192
193    tBLE_PERIODIC_ADV_PARAMS* p_periodic_params = new tBLE_PERIODIC_ADV_PARAMS;
194    parsePeriodicParams(p_periodic_params, periodic_params);
195
196    do_in_bta_thread(
197        FROM_HERE,
198        Bind(&BleAdvertisingManager::StartAdvertisingSet,
199             base::Unretained(BleAdvertisingManager::Get()),
200             jni_thread_wrapper(FROM_HERE, cb), base::Owned(p_params),
201             std::move(advertise_data), std::move(scan_response_data),
202             base::Owned(p_periodic_params), std::move(periodic_data), duration,
203             maxExtAdvEvents, jni_thread_wrapper(FROM_HERE, timeout_cb)));
204  }
205
206  void SetPeriodicAdvertisingParameters(
207      int advertiser_id, PeriodicAdvertisingParameters periodic_params,
208      StatusCallback cb) override {
209    VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id;
210
211    tBLE_PERIODIC_ADV_PARAMS* p_periodic_params = new tBLE_PERIODIC_ADV_PARAMS;
212    parsePeriodicParams(p_periodic_params, periodic_params);
213
214    do_in_bta_thread(
215        FROM_HERE,
216        Bind(&BleAdvertisingManager::SetPeriodicAdvertisingParameters,
217             base::Unretained(BleAdvertisingManager::Get()), advertiser_id,
218             base::Owned(p_periodic_params),
219             jni_thread_wrapper(FROM_HERE, cb)));
220  }
221
222  void SetPeriodicAdvertisingData(int advertiser_id, std::vector<uint8_t> data,
223                                  StatusCallback cb) override {
224    VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id;
225
226    do_in_bta_thread(
227        FROM_HERE,
228        Bind(&BleAdvertisingManager::SetPeriodicAdvertisingData,
229             base::Unretained(BleAdvertisingManager::Get()), advertiser_id,
230             std::move(data), jni_thread_wrapper(FROM_HERE, cb)));
231  }
232
233  void SetPeriodicAdvertisingEnable(int advertiser_id, bool enable,
234                                    StatusCallback cb) override {
235    VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id
236            << " ,enable: " << enable;
237
238    do_in_bta_thread(
239        FROM_HERE,
240        Bind(&BleAdvertisingManager::SetPeriodicAdvertisingEnable,
241             base::Unretained(BleAdvertisingManager::Get()), advertiser_id,
242             enable, jni_thread_wrapper(FROM_HERE, cb)));
243  }
244};
245
246BleAdvertiserInterface* btLeAdvertiserInstance = nullptr;
247
248}  // namespace
249
250BleAdvertiserInterface* get_ble_advertiser_instance() {
251  if (btLeAdvertiserInstance == nullptr)
252    btLeAdvertiserInstance = new BleAdvertiserInterfaceImpl();
253
254  return btLeAdvertiserInstance;
255}
256