blob: ec79dd5a3a5ba30dba3bdc9681e6ab35a676cd28 [file] [log] [blame]
/******************************************************************************
*
* Copyright (C) 2016 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#define LOG_TAG "bt_btif_ble_advertiser"
#include <hardware/bluetooth.h>
#include <hardware/bt_gatt.h>
#include <base/bind.h>
#include <vector>
#include "ble_advertiser.h"
#include "bta_closure_api.h"
#include "btif_common.h"
using base::Bind;
using base::Owned;
using std::vector;
extern bt_status_t do_in_jni_thread(const base::Closure& task);
namespace {
template <typename T>
class OwnedArrayWrapper {
public:
explicit OwnedArrayWrapper(T* o) : ptr_(o) {}
~OwnedArrayWrapper() { delete[] ptr_; }
T* get() const { return ptr_; }
OwnedArrayWrapper(OwnedArrayWrapper&& other) {
ptr_ = other.ptr_;
other.ptr_ = NULL;
}
private:
mutable T* ptr_;
};
template <typename T>
T* Unwrap(const OwnedArrayWrapper<T>& o) {
return o.get();
}
template <typename T>
static inline OwnedArrayWrapper<T> OwnedArray(T* o) {
return OwnedArrayWrapper<T>(o);
}
class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface {
~BleAdvertiserInterfaceImpl(){};
void RegisterAdvertiserCb(
base::Callback<void(uint8_t /* adv_id */, uint8_t /* status */)> cb,
uint8_t advertiser_id, uint8_t status) {
LOG(INFO) << __func__ << " status: " << +status
<< " , adveriser_id: " << +advertiser_id;
do_in_jni_thread(Bind(cb, advertiser_id, status));
}
void RegisterAdvertiser(
base::Callback<void(uint8_t /* advertiser_id */, uint8_t /* status */)>
cb) override {
do_in_bta_thread(
FROM_HERE, Bind(&BleAdvertisingManager::RegisterAdvertiser,
base::Unretained(BleAdvertisingManager::Get()),
Bind(&BleAdvertiserInterfaceImpl::RegisterAdvertiserCb,
base::Unretained(this), cb)));
}
void Unregister(uint8_t advertiser_id) override {
do_in_bta_thread(
FROM_HERE,
Bind(&BleAdvertisingManager::Unregister,
base::Unretained(BleAdvertisingManager::Get()), advertiser_id));
}
void SetParametersCb(Callback cb, uint8_t status) {
LOG(INFO) << __func__ << " status: " << +status;
do_in_jni_thread(Bind(cb, status));
}
void SetParameters(uint8_t advertiser_id,
uint16_t advertising_event_properties,
uint32_t min_interval, uint32_t max_interval, int chnl_map,
int tx_power, uint8_t primary_advertising_phy,
uint8_t secondary_advertising_phy,
uint8_t scan_request_notification_enable, Callback cb) {
tBTM_BLE_ADV_PARAMS* params = new tBTM_BLE_ADV_PARAMS;
params->advertising_event_properties = advertising_event_properties;
params->adv_int_min = min_interval;
params->adv_int_max = max_interval;
params->channel_map = chnl_map;
params->adv_filter_policy = 0;
params->tx_power = tx_power;
params->primary_advertising_phy = primary_advertising_phy;
params->secondary_advertising_phy = secondary_advertising_phy;
params->scan_request_notification_enable = scan_request_notification_enable;
do_in_bta_thread(FROM_HERE,
Bind(&BleAdvertisingManager::SetParameters,
base::Unretained(BleAdvertisingManager::Get()),
advertiser_id, base::Owned(params),
Bind(&BleAdvertiserInterfaceImpl::SetParametersCb,
base::Unretained(this), cb)));
}
void SetDataCb(Callback cb, uint8_t advertiser_id, uint8_t status) {
do_in_jni_thread(Bind(cb, status));
}
void SetData(int advertiser_id, bool set_scan_rsp, vector<uint8_t> data,
Callback cb) override {
do_in_bta_thread(FROM_HERE,
Bind(&BleAdvertisingManager::SetData,
base::Unretained(BleAdvertisingManager::Get()),
advertiser_id, set_scan_rsp, std::move(data),
Bind(&BleAdvertiserInterfaceImpl::SetDataCb,
base::Unretained(this), cb, advertiser_id)));
}
void EnableTimeoutCb(Callback cb, uint8_t status) {
do_in_jni_thread(Bind(cb, status));
}
void EnableCb(Callback cb, uint8_t status) {
do_in_jni_thread(Bind(cb, status));
}
void Enable(uint8_t advertiser_id, bool enable, Callback cb, int timeout_s,
Callback timeout_cb) override {
VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id
<< " ,enable: " << enable;
do_in_bta_thread(
FROM_HERE,
Bind(&BleAdvertisingManager::Enable,
base::Unretained(BleAdvertisingManager::Get()), advertiser_id,
enable, Bind(&BleAdvertiserInterfaceImpl::EnableCb,
base::Unretained(this), cb),
timeout_s, Bind(&BleAdvertiserInterfaceImpl::EnableTimeoutCb,
base::Unretained(this), timeout_cb)));
}
void StartAdvertising(uint8_t advertiser_id, Callback cb,
AdvertiseParameters params,
std::vector<uint8_t> advertise_data,
std::vector<uint8_t> scan_response_data, int timeout_s,
MultiAdvCb timeout_cb) override {
VLOG(1) << __func__;
tBTM_BLE_ADV_PARAMS* p_params = new tBTM_BLE_ADV_PARAMS;
p_params->advertising_event_properties =
params.advertising_event_properties;
p_params->adv_int_min = params.min_interval;
p_params->adv_int_max = params.max_interval;
p_params->channel_map = params.channel_map;
p_params->adv_filter_policy = 0;
p_params->tx_power = params.tx_power;
p_params->primary_advertising_phy = params.primary_advertising_phy;
p_params->secondary_advertising_phy = params.secondary_advertising_phy;
p_params->scan_request_notification_enable =
params.scan_request_notification_enable;
do_in_bta_thread(
FROM_HERE, Bind(&BleAdvertisingManager::StartAdvertising,
base::Unretained(BleAdvertisingManager::Get()),
advertiser_id, base::Bind(
[](Callback cb, uint8_t status) {
do_in_jni_thread(Bind(cb, status));
},
cb),
base::Owned(p_params), std::move(advertise_data),
std::move(scan_response_data), timeout_s, timeout_cb));
}
};
BleAdvertiserInterface* btLeAdvertiserInstance = nullptr;
} // namespace
BleAdvertiserInterface* get_ble_advertiser_instance() {
if (btLeAdvertiserInstance == nullptr)
btLeAdvertiserInstance = new BleAdvertiserInterfaceImpl();
return btLeAdvertiserInstance;
}