Bluetooth 5 AdvertisingSet implementation (3/4)
This patch wires up fist methods of AdvertisingSet, making it possible
to start advertising and stop advertising. It also replaces legacy
implemementation with calls to new implementation.
Bug: 30622771
Test: sl4a ConcurrentBleAdvertisingTest
Change-Id: I843d8fc12ba1928c87e256a0fb6d730c9fa200e6
diff --git a/btif/src/btif_ble_advertiser.cc b/btif/src/btif_ble_advertiser.cc
index f30192e..f274de2 100644
--- a/btif/src/btif_ble_advertiser.cc
+++ b/btif/src/btif_ble_advertiser.cc
@@ -62,17 +62,14 @@
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) {
+ 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(
- base::Callback<void(uint8_t /* advertiser_id */, uint8_t /* status */)>
- cb) override {
+ void RegisterAdvertiser(IdStatusCallback cb) override {
do_in_bta_thread(
FROM_HERE, Bind(&BleAdvertisingManager::RegisterAdvertiser,
base::Unretained(BleAdvertisingManager::Get()),
@@ -87,7 +84,7 @@
base::Unretained(BleAdvertisingManager::Get()), advertiser_id));
}
- void SetParametersCb(Callback cb, uint8_t status) {
+ void SetParametersCb(StatusCallback cb, uint8_t status) {
LOG(INFO) << __func__ << " status: " << +status;
do_in_jni_thread(Bind(cb, status));
}
@@ -97,7 +94,8 @@
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) {
+ uint8_t scan_request_notification_enable,
+ StatusCallback cb) {
tBTM_BLE_ADV_PARAMS* params = new tBTM_BLE_ADV_PARAMS;
params->advertising_event_properties = advertising_event_properties;
@@ -119,7 +117,7 @@
}
void SetData(int advertiser_id, bool set_scan_rsp, vector<uint8_t> data,
- Callback cb) override {
+ StatusCallback cb) override {
do_in_bta_thread(
FROM_HERE,
Bind(&BleAdvertisingManager::SetData,
@@ -127,8 +125,8 @@
set_scan_rsp, std::move(data), jni_thread_wrapper(FROM_HERE, cb)));
}
- void Enable(uint8_t advertiser_id, bool enable, Callback cb, int timeout_s,
- Callback timeout_cb) override {
+ void Enable(uint8_t advertiser_id, bool enable, StatusCallback cb,
+ int timeout_s, StatusCallback timeout_cb) override {
VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id
<< " ,enable: " << enable;
@@ -140,7 +138,7 @@
jni_thread_wrapper(FROM_HERE, timeout_cb)));
}
- void StartAdvertising(uint8_t advertiser_id, Callback 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,
@@ -168,6 +166,44 @@
std::move(advertise_data), std::move(scan_response_data),
timeout_s, jni_thread_wrapper(FROM_HERE, timeout_cb)));
}
+
+ void StartAdvertisingSet(IdStatusCallback 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, int timeout_s,
+ IdStatusCallback timeout_cb) {
+ 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;
+
+ tBLE_PERIODIC_ADV_PARAMS* p_periodic_params = new tBLE_PERIODIC_ADV_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;
+
+ do_in_bta_thread(
+ FROM_HERE,
+ Bind(&BleAdvertisingManager::StartAdvertisingSet,
+ base::Unretained(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),
+ timeout_s, jni_thread_wrapper(FROM_HERE, timeout_cb)));
+ };
};
BleAdvertiserInterface* btLeAdvertiserInstance = nullptr;
diff --git a/service/test/low_energy_advertiser_unittest.cc b/service/test/low_energy_advertiser_unittest.cc
index a985254..eb2211c 100644
--- a/service/test/low_energy_advertiser_unittest.cc
+++ b/service/test/low_energy_advertiser_unittest.cc
@@ -45,9 +45,7 @@
MockAdvertiserHandler() {}
~MockAdvertiserHandler() override = default;
- MOCK_METHOD1(RegisterAdvertiser,
- void(base::Callback<void(uint8_t /* advertiser_id */,
- uint8_t /* status */)>));
+ MOCK_METHOD1(RegisterAdvertiser, void(IdStatusCallback));
MOCK_METHOD1(Unregister, void(uint8_t));
MOCK_METHOD10(SetParameters,
void(uint8_t advertiser_id,
@@ -55,14 +53,25 @@
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));
+ uint8_t scan_request_notification_enable,
+ StatusCallback cb));
MOCK_METHOD4(SetData, void(int advertiser_id, bool set_scan_rsp,
- std::vector<uint8_t> data, Callback cb));
- MOCK_METHOD5(Enable, void(uint8_t advertiser_id, bool enable, Callback cb,
- int timeout_s, Callback timeout_cb));
+ std::vector<uint8_t> data, StatusCallback cb));
+ MOCK_METHOD5(Enable,
+ void(uint8_t advertiser_id, bool enable, StatusCallback cb,
+ int timeout_s, StatusCallback timeout_cb));
MOCK_METHOD7(StartAdvertising,
- void(uint8_t advertiser_id, Callback cb, AdvertiseParameters,
- std::vector<uint8_t>, std::vector<uint8_t>, int, Callback));
+ void(uint8_t advertiser_id, StatusCallback cb,
+ AdvertiseParameters, std::vector<uint8_t>,
+ std::vector<uint8_t>, int, StatusCallback));
+
+ MOCK_METHOD8(StartAdvertisingSet,
+ void(IdStatusCallback 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, int timeout_s,
+ IdStatusCallback timeout_cb));
private:
DISALLOW_COPY_AND_ASSIGN(MockAdvertiserHandler);
diff --git a/stack/btm/btm_ble_multi_adv.cc b/stack/btm/btm_ble_multi_adv.cc
index 0e30bd0..339a82e 100644
--- a/stack/btm/btm_ble_multi_adv.cc
+++ b/stack/btm/btm_ble_multi_adv.cc
@@ -32,6 +32,8 @@
#include "btm_int_types.h"
using base::Bind;
+using RegisterCb =
+ base::Callback<void(uint8_t /* inst_id */, uint8_t /* status */)>;
extern void btm_gen_resolvable_private_addr(
base::Callback<void(uint8_t[8])> cb);
extern fixed_queue_t* btu_general_alarm_queue;
@@ -292,6 +294,120 @@
// clang-format on
}
+ void StartAdvertisingSet(RegisterCb cb, tBTM_BLE_ADV_PARAMS* params,
+ std::vector<uint8_t> advertise_data,
+ std::vector<uint8_t> scan_response_data,
+ tBLE_PERIODIC_ADV_PARAMS* periodic_params,
+ std::vector<uint8_t> periodic_data, int timeout_s,
+ RegisterCb timeout_cb) override {
+ /* a temporary type for holding all the data needed in callbacks below*/
+ struct CreatorParams {
+ uint8_t inst_id;
+ BleAdvertisingManagerImpl* self;
+ RegisterCb cb;
+ tBTM_BLE_ADV_PARAMS params;
+ std::vector<uint8_t> advertise_data;
+ std::vector<uint8_t> scan_response_data;
+ tBLE_PERIODIC_ADV_PARAMS periodic_params;
+ std::vector<uint8_t> periodic_data;
+ int timeout_s;
+ RegisterCb timeout_cb;
+ };
+
+ std::unique_ptr<CreatorParams> c;
+ c.reset(new CreatorParams());
+
+ c->self = this;
+ c->cb = std::move(cb);
+ c->params = *params;
+ c->advertise_data = std::move(advertise_data);
+ c->scan_response_data = std::move(scan_response_data);
+ c->periodic_params = *periodic_params;
+ c->periodic_data = std::move(periodic_data);
+ c->timeout_s = timeout_s;
+ c->timeout_cb = std::move(timeout_cb);
+
+ using c_type = std::unique_ptr<CreatorParams>;
+
+ // this code is intentionally left formatted this way to highlight the
+ // asynchronous flow
+ // clang-format off
+ c->self->RegisterAdvertiser(Bind(
+ [](c_type c, uint8_t advertiser_id, uint8_t status) {
+ if (status != 0) {
+ LOG(ERROR) << "registering advertiser failed, status: " << +status;
+ c->cb.Run(0, status);
+ return;
+ }
+
+ c->inst_id = advertiser_id;
+
+ c->self->SetParameters(c->inst_id, &c->params, Bind(
+ [](c_type c, uint8_t status) {
+ if (status != 0) {
+ c->self->Unregister(c->inst_id);
+ LOG(ERROR) << "setting parameters failed, status: " << +status;
+ c->cb.Run(0, status);
+ return;
+ }
+
+ //TODO(jpawlowski): obtain real tx_power from set parameters
+ // response, to put into adv data
+
+ BD_ADDR *rpa = &c->self->adv_inst[c->inst_id].own_address;
+ c->self->GetHciInterface()->SetRandomAddress(c->inst_id, *rpa, Bind(
+ [](c_type c, uint8_t status) {
+ if (status != 0) {
+ c->self->Unregister(c->inst_id);
+ LOG(ERROR) << "setting random address failed, status: " << +status;
+ c->cb.Run(0, status);
+ return;
+ }
+
+ c->self->SetData(c->inst_id, false, std::move(c->advertise_data), Bind(
+ [](c_type c, uint8_t status) {
+ if (status != 0) {
+ c->self->Unregister(c->inst_id);
+ LOG(ERROR) << "setting advertise data failed, status: " << +status;
+ c->cb.Run(0, status);
+ return;
+ }
+
+ c->self->SetData(c->inst_id, true, std::move(c->scan_response_data), Bind(
+ [](c_type c, uint8_t status) {
+ if (status != 0) {
+ c->self->Unregister(c->inst_id);
+ LOG(ERROR) << "setting scan response data failed, status: " << +status;
+ c->cb.Run(0, status);
+ return;
+ }
+
+ uint8_t inst_id = c->inst_id;
+ int timeout_s = c->timeout_s;
+ RegisterCb timeout_cb = std::move(c->timeout_cb);
+ BleAdvertisingManagerImpl* self = c->self;
+ MultiAdvCb enable_cb = Bind(
+ [](c_type c, uint8_t status) {
+ if (status != 0) {
+ c->self->Unregister(c->inst_id);
+ LOG(ERROR) << "enabling advertiser failed, status: " << +status;
+ c->cb.Run(0, status);
+ return;
+ }
+ c->cb.Run(c->inst_id, status);
+ },
+ base::Passed(&c));
+
+
+ self->Enable(inst_id, true, std::move(enable_cb), timeout_s, Bind(std::move(timeout_cb), inst_id));
+ }, base::Passed(&c)));
+ }, base::Passed(&c)));
+ }, base::Passed(&c)));
+ }, base::Passed(&c)));
+ }, base::Passed(&c)));
+ // clang-format on
+ }
+
void EnableWithTimerCb(uint8_t inst_id, MultiAdvCb enable_cb, int timeout_s,
MultiAdvCb timeout_cb, uint8_t status) {
AdvertisingInstance* p_inst = &adv_inst[inst_id];
@@ -374,8 +490,8 @@
p_params->adv_int_min, p_params->adv_int_max, p_params->channel_map,
p_inst->own_address_type, p_inst->own_address, 0x00, peer_address,
p_params->adv_filter_policy, p_inst->tx_power,
- p_params->primary_advertising_phy, 0x01, 0x01,
- p_params->secondary_advertising_phy,
+ p_params->primary_advertising_phy, 0x01,
+ p_params->secondary_advertising_phy, 0x01 /* TODO: proper SID */,
p_params->scan_request_notification_enable, cb);
// TODO: re-enable only if it was enabled, properly call
diff --git a/stack/include/ble_advertiser.h b/stack/include/ble_advertiser.h
index e4787ae..f50f87b 100644
--- a/stack/include/ble_advertiser.h
+++ b/stack/include/ble_advertiser.h
@@ -51,6 +51,13 @@
uint8_t scan_request_notification_enable;
} tBTM_BLE_ADV_PARAMS;
+typedef struct {
+ uint8_t enable;
+ uint16_t min_interval;
+ uint16_t max_interval;
+ uint16_t periodic_advertising_properties;
+} tBLE_PERIODIC_ADV_PARAMS;
+
class BleAdvertiserHciInterface;
class BleAdvertisingManager {
@@ -65,12 +72,12 @@
static BleAdvertisingManager* Get();
/* Register an advertising instance, status will be returned in |cb|
- * callback, with assigned id, if operation succeeds. Instance is freed when
- * advertising is disabled by calling |BTM_BleDisableAdvInstance|, or when any
- * of the operations fails.
- * The instance will have data set to |advertise_data|, scan response set to
- * |scan_response_data|, and will be enabled.
- */
+ * callback, with assigned id, if operation succeeds. Instance is freed when
+ * advertising is disabled by calling |BTM_BleDisableAdvInstance|, or when any
+ * of the operations fails.
+ * The instance will have data set to |advertise_data|, scan response set to
+ * |scan_response_data|, and will be enabled.
+ */
virtual void StartAdvertising(uint8_t advertiser_id, MultiAdvCb cb,
tBTM_BLE_ADV_PARAMS* params,
std::vector<uint8_t> advertise_data,
@@ -78,6 +85,23 @@
int timeout_s, MultiAdvCb timeout_cb) = 0;
/* Register an advertising instance, status will be returned in |cb|
+ * callback, with assigned id, if operation succeeds. Instance is freed when
+ * advertising is disabled by calling |BTM_BleDisableAdvInstance|, or when any
+ * of the operations fails.
+ * The instance will have data set to |advertise_data|, scan response set to
+ * |scan_response_data|, periodic data set to |periodic_data| and will be
+ * enabled.
+ */
+ virtual void StartAdvertisingSet(
+ base::Callback<void(uint8_t /* inst_id */, uint8_t /* status */)> cb,
+ tBTM_BLE_ADV_PARAMS* params, std::vector<uint8_t> advertise_data,
+ std::vector<uint8_t> scan_response_data,
+ tBLE_PERIODIC_ADV_PARAMS* periodic_params,
+ std::vector<uint8_t> periodic_data, int timeout_s,
+ base::Callback<void(uint8_t /* inst_id */, uint8_t /* status */)>
+ timeout_cb) = 0;
+
+ /* Register an advertising instance, status will be returned in |cb|
* callback, with assigned id, if operation succeeds. Instance is freed when
* advertising is disabled by calling |BTM_BleDisableAdvInstance|, or when any
* of the operations fails. */