blob: d1923bdd384d208625829b39515944d8d2d502f8 [file] [log] [blame]
/******************************************************************************
*
* Copyright 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 "btif_common.h"
#include "stack/include/btu.h"
using base::Bind;
using base::Owned;
using std::vector;
namespace {
template <typename T>
class OwnedArrayWrapper {
public:
explicit OwnedArrayWrapper(T* o) : ptr_(o) {}
~OwnedArrayWrapper() { delete[] ptr_; }
T* get() const { return ptr_; }
OwnedArrayWrapper(OwnedArrayWrapper&& other) noexcept {
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);
}
void parseParams(tBTM_BLE_ADV_PARAMS* p_params,
const AdvertiseParameters& 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;
}
void parsePeriodicParams(tBLE_PERIODIC_ADV_PARAMS* p_periodic_params,
PeriodicAdvertisingParameters periodic_params) {
p_periodic_params->enable = periodic_params.enable;
p_periodic_params->min_interval = periodic_params.min_interval;
p_periodic_params->max_interval = periodic_params.max_interval;
p_periodic_params->periodic_advertising_properties =
periodic_params.periodic_advertising_properties;
}
class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface {
~BleAdvertiserInterfaceImpl() override{};
void RegisterAdvertiserCb(IdStatusCallback 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(IdStatusCallback cb) override {
do_in_main_thread(
FROM_HERE, Bind(&BleAdvertisingManager::RegisterAdvertiser,
BleAdvertisingManager::Get(),
Bind(&BleAdvertiserInterfaceImpl::RegisterAdvertiserCb,
base::Unretained(this), cb)));
}
void Unregister(uint8_t advertiser_id) override {
do_in_main_thread(
FROM_HERE,
Bind(
[](uint8_t advertiser_id) {
if (!BleAdvertisingManager::IsInitialized()) {
LOG(WARNING) << "Stack already shutdown";
return;
}
BleAdvertisingManager::Get()->Unregister(advertiser_id);
},
advertiser_id));
}
void GetOwnAddress(uint8_t advertiser_id, GetAddressCallback cb) override {
if (!BleAdvertisingManager::IsInitialized()) return;
do_in_main_thread(FROM_HERE,
Bind(&BleAdvertisingManager::GetOwnAddress,
BleAdvertisingManager::Get(), advertiser_id,
jni_thread_wrapper(FROM_HERE, cb)));
}
void SetParameters(uint8_t advertiser_id, AdvertiseParameters params,
ParametersCallback cb) override {
VLOG(1) << __func__;
if (!BleAdvertisingManager::IsInitialized()) return;
tBTM_BLE_ADV_PARAMS* p_params = new tBTM_BLE_ADV_PARAMS;
parseParams(p_params, params);
do_in_main_thread(FROM_HERE, Bind(&BleAdvertisingManager::SetParameters,
BleAdvertisingManager::Get(),
advertiser_id, base::Owned(p_params),
jni_thread_wrapper(FROM_HERE, cb)));
}
void SetData(int advertiser_id, bool set_scan_rsp, vector<uint8_t> data,
StatusCallback cb) override {
if (!BleAdvertisingManager::IsInitialized()) return;
do_in_main_thread(
FROM_HERE,
Bind(&BleAdvertisingManager::SetData, BleAdvertisingManager::Get(),
advertiser_id, set_scan_rsp, std::move(data),
jni_thread_wrapper(FROM_HERE, cb)));
}
void Enable(uint8_t advertiser_id, bool enable, StatusCallback cb,
uint16_t duration, uint8_t maxExtAdvEvents,
StatusCallback timeout_cb) override {
VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id
<< " ,enable: " << enable;
if (!BleAdvertisingManager::IsInitialized()) return;
do_in_main_thread(
FROM_HERE,
Bind(&BleAdvertisingManager::Enable, BleAdvertisingManager::Get(),
advertiser_id, enable, jni_thread_wrapper(FROM_HERE, cb), duration,
maxExtAdvEvents, jni_thread_wrapper(FROM_HERE, timeout_cb)));
}
void 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) override {
VLOG(1) << __func__;
if (!BleAdvertisingManager::IsInitialized()) return;
tBTM_BLE_ADV_PARAMS* p_params = new tBTM_BLE_ADV_PARAMS;
parseParams(p_params, params);
do_in_main_thread(
FROM_HERE,
Bind(&BleAdvertisingManager::StartAdvertising,
BleAdvertisingManager::Get(), advertiser_id,
jni_thread_wrapper(FROM_HERE, cb), base::Owned(p_params),
std::move(advertise_data), std::move(scan_response_data),
timeout_s * 100, jni_thread_wrapper(FROM_HERE, timeout_cb)));
}
void 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) override {
VLOG(1) << __func__;
if (!BleAdvertisingManager::IsInitialized()) return;
tBTM_BLE_ADV_PARAMS* p_params = new tBTM_BLE_ADV_PARAMS;
parseParams(p_params, params);
tBLE_PERIODIC_ADV_PARAMS* p_periodic_params = new tBLE_PERIODIC_ADV_PARAMS;
parsePeriodicParams(p_periodic_params, periodic_params);
do_in_main_thread(
FROM_HERE,
Bind(&BleAdvertisingManager::StartAdvertisingSet,
BleAdvertisingManager::Get(), jni_thread_wrapper(FROM_HERE, cb),
base::Owned(p_params), std::move(advertise_data),
std::move(scan_response_data), base::Owned(p_periodic_params),
std::move(periodic_data), duration, maxExtAdvEvents,
jni_thread_wrapper(FROM_HERE, timeout_cb)));
}
void SetPeriodicAdvertisingParameters(
int advertiser_id, PeriodicAdvertisingParameters periodic_params,
StatusCallback cb) override {
VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id;
if (!BleAdvertisingManager::IsInitialized()) return;
tBLE_PERIODIC_ADV_PARAMS* p_periodic_params = new tBLE_PERIODIC_ADV_PARAMS;
parsePeriodicParams(p_periodic_params, periodic_params);
do_in_main_thread(
FROM_HERE,
Bind(&BleAdvertisingManager::SetPeriodicAdvertisingParameters,
BleAdvertisingManager::Get(), advertiser_id,
base::Owned(p_periodic_params),
jni_thread_wrapper(FROM_HERE, cb)));
}
void SetPeriodicAdvertisingData(int advertiser_id, std::vector<uint8_t> data,
StatusCallback cb) override {
VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id;
if (!BleAdvertisingManager::IsInitialized()) return;
do_in_main_thread(FROM_HERE,
Bind(&BleAdvertisingManager::SetPeriodicAdvertisingData,
BleAdvertisingManager::Get(), advertiser_id,
std::move(data), jni_thread_wrapper(FROM_HERE, cb)));
}
void SetPeriodicAdvertisingEnable(int advertiser_id, bool enable,
StatusCallback cb) override {
VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id
<< " ,enable: " << enable;
if (!BleAdvertisingManager::IsInitialized()) return;
do_in_main_thread(FROM_HERE,
Bind(&BleAdvertisingManager::SetPeriodicAdvertisingEnable,
BleAdvertisingManager::Get(), advertiser_id, enable,
jni_thread_wrapper(FROM_HERE, cb)));
}
};
BleAdvertiserInterface* btLeAdvertiserInstance = nullptr;
} // namespace
BleAdvertiserInterface* get_ble_advertiser_instance() {
if (btLeAdvertiserInstance == nullptr)
btLeAdvertiserInstance = new BleAdvertiserInterfaceImpl();
return btLeAdvertiserInstance;
}