Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0cdb403c authored by Jakub Pawlowski's avatar Jakub Pawlowski
Browse files

Bluetooth 5 advertising duration refactoring (1/4)

Expose both duration and maximum extended advertising events to limit
advertising time.

Test: manual
Bug: 30622771
Change-Id: I4475c322347899946b39e65026d8009e02c93759
(cherry picked from commit 5204c62f137de9b6c2834391fd329457d3fdbc84)
parent abfa24e0
Loading
Loading
Loading
Loading
+9 −7
Original line number Diff line number Diff line
@@ -131,7 +131,8 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface {
  }

  void Enable(uint8_t advertiser_id, bool enable, StatusCallback cb,
              int timeout_s, StatusCallback timeout_cb) override {
              uint16_t duration, uint8_t maxExtAdvEvents,
              StatusCallback timeout_cb) override {
    VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id
            << " ,enable: " << enable;

@@ -139,8 +140,8 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface {
        FROM_HERE,
        Bind(&BleAdvertisingManager::Enable,
             base::Unretained(BleAdvertisingManager::Get()), advertiser_id,
             enable, jni_thread_wrapper(FROM_HERE, cb), timeout_s,
             jni_thread_wrapper(FROM_HERE, timeout_cb)));
             enable, jni_thread_wrapper(FROM_HERE, cb), duration,
             maxExtAdvEvents, jni_thread_wrapper(FROM_HERE, timeout_cb)));
  }

  void StartAdvertising(uint8_t advertiser_id, StatusCallback cb,
@@ -159,7 +160,7 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface {
             base::Unretained(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, jni_thread_wrapper(FROM_HERE, timeout_cb)));
             timeout_s * 100, jni_thread_wrapper(FROM_HERE, timeout_cb)));
  }

  void StartAdvertisingSet(IdTxPowerStatusCallback cb,
@@ -167,7 +168,8 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface {
                           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,
                           std::vector<uint8_t> periodic_data,
                           uint16_t duration, uint8_t maxExtAdvEvents,
                           IdStatusCallback timeout_cb) override {
    VLOG(1) << __func__;

@@ -183,8 +185,8 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface {
             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)));
             base::Owned(p_periodic_params), std::move(periodic_data), duration,
             maxExtAdvEvents, jni_thread_wrapper(FROM_HERE, timeout_cb)));
  }

  void SetPeriodicAdvertisingParameters(
+1 −1
Original line number Diff line number Diff line
@@ -357,7 +357,7 @@ void RegisterClientCallback(int status, int client_if, bt_uuid_t* app_uuid) {

  g_internal->gatt->advertiser->Enable(
      0 /* std_inst */, true, base::Bind(&EnableAdvertisingCallback),
      0 /* no timeout */, base::Bind(&DoNothing));
      0 /* no duration */, 0 /* no maxExtAdvEvent*/, base::Bind(&DoNothing));
}

void ServiceStoppedCallback(int status, int server_if, int srvc_handle) {
+4 −3
Original line number Diff line number Diff line
@@ -134,7 +134,8 @@ LowEnergyAdvertiser::~LowEnergyAdvertiser() {

  // Stop advertising and ignore the result.
  hal::BluetoothGattInterface::Get()->GetAdvertiserHALInterface()->Enable(
      advertiser_id_, false, base::Bind(&DoNothing), 0, base::Bind(&DoNothing));
      advertiser_id_, false, base::Bind(&DoNothing), 0, 0,
      base::Bind(&DoNothing));
  hal::BluetoothGattInterface::Get()->GetAdvertiserHALInterface()->Unregister(
      advertiser_id_);
}
@@ -205,7 +206,7 @@ bool LowEnergyAdvertiser::StopAdvertising(const StatusCallback& callback) {
      advertiser_id_, false,
      base::Bind(&LowEnergyAdvertiser::EnableCallback, base::Unretained(this),
                 false, advertiser_id_),
      0, base::Bind(&LowEnergyAdvertiser::EnableCallback,
      0, 0, base::Bind(&LowEnergyAdvertiser::EnableCallback,
                       base::Unretained(this), false, advertiser_id_));

  // OK to set this at the end since we're still holding |adv_fields_lock_|.
+9 −9
Original line number Diff line number Diff line
@@ -50,19 +50,19 @@ class MockAdvertiserHandler : public BleAdvertiserInterface {
  MOCK_METHOD3(SetParameters,
               void(uint8_t, AdvertiseParameters, ParametersCallback));
  MOCK_METHOD4(SetData, void(int, bool, std::vector<uint8_t>, StatusCallback));
  MOCK_METHOD5(Enable,
               void(uint8_t, bool, StatusCallback, int, StatusCallback));
  MOCK_METHOD6(Enable, void(uint8_t, bool, StatusCallback, uint16_t, uint8_t,
                            StatusCallback));
  MOCK_METHOD7(StartAdvertising,
               void(uint8_t advertiser_id, StatusCallback cb,
                    AdvertiseParameters, std::vector<uint8_t>,
                    std::vector<uint8_t>, int, StatusCallback));
  MOCK_METHOD8(StartAdvertisingSet,
  MOCK_METHOD9(StartAdvertisingSet,
               void(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, int timeout_s,
                    IdStatusCallback timeout_cb));
                    std::vector<uint8_t> periodic_data, uint16_t duration,
                    uint8_t maxExtAdvEvents, IdStatusCallback timeout_cb));
  MOCK_METHOD3(SetPeriodicAdvertisingParameters,
               void(int, PeriodicAdvertisingParameters, StatusCallback));
  MOCK_METHOD3(SetPeriodicAdvertisingData,
@@ -116,7 +116,7 @@ class LowEnergyAdvertiserPostRegisterTest : public LowEnergyAdvertiserTest {
  }

  void TearDown() override {
    EXPECT_CALL(*mock_handler_, Enable(_, false, _, _, _)).Times(1);
    EXPECT_CALL(*mock_handler_, Enable(_, false, _, _, _, _)).Times(1);
    EXPECT_CALL(*mock_handler_, Unregister(_)).Times(1);
    le_advertiser_.reset();
    LowEnergyAdvertiserTest::TearDown();
@@ -184,7 +184,7 @@ class LowEnergyAdvertiserPostRegisterTest : public LowEnergyAdvertiserTest {
    set_data_cb->Run(BT_STATUS_SUCCESS);

    status_cb disable_cb;
    EXPECT_CALL(*mock_handler_, Enable(_, false, _, _, _))
    EXPECT_CALL(*mock_handler_, Enable(_, false, _, _, _, _))
        .Times(1)
        .WillOnce(SaveArg<2>(&disable_cb));

@@ -257,7 +257,7 @@ TEST_F(LowEnergyAdvertiserTest, RegisterInstance) {
  EXPECT_EQ(uuid0, cb_uuid);

  // The advertiser should unregister itself when deleted.
  EXPECT_CALL(*mock_handler_, Enable(client_if0, false, _, _, _)).Times(1);
  EXPECT_CALL(*mock_handler_, Enable(client_if0, false, _, _, _, _)).Times(1);
  EXPECT_CALL(*mock_handler_, Unregister(client_if0)).Times(1);
  advertiser.reset();
  ::testing::Mock::VerifyAndClearExpectations(mock_handler_.get());
@@ -355,7 +355,7 @@ TEST_F(LowEnergyAdvertiserPostRegisterTest, StopAdvertisingBasic) {
  };

  status_cb enable_cb;
  EXPECT_CALL(*mock_handler_, Enable(_, false, _, _, _))
  EXPECT_CALL(*mock_handler_, Enable(_, false, _, _, _, _))
      .Times(2)
      .WillRepeatedly(SaveArg<2>(&enable_cb));

+47 −25
Original line number Diff line number Diff line
@@ -48,17 +48,18 @@ struct AdvertisingInstance {
  uint8_t advertising_event_properties;
  alarm_t* adv_raddr_timer;
  int8_t tx_power;
  int timeout_s;
  int duration;
  alarm_t* timeout_timer;
  uint8_t own_address_type;
  BD_ADDR own_address;
  MultiAdvCb timeout_cb;

  AdvertisingInstance(int inst_id)
      : inst_id(inst_id),
        in_use(false),
        advertising_event_properties(0),
        tx_power(0),
        timeout_s(0),
        duration(0),
        timeout_timer(nullptr),
        own_address_type(0),
        own_address{0} {
@@ -120,7 +121,8 @@ struct CreatorParams {
  std::vector<uint8_t> scan_response_data;
  tBLE_PERIODIC_ADV_PARAMS periodic_params;
  std::vector<uint8_t> periodic_data;
  int timeout_s;
  uint16_t duration;
  uint8_t maxExtAdvEvents;
  RegisterCb timeout_cb;
};

@@ -240,7 +242,7 @@ class BleAdvertisingManagerImpl
  void StartAdvertising(uint8_t advertiser_id, MultiAdvCb cb,
                        tBTM_BLE_ADV_PARAMS* params,
                        std::vector<uint8_t> advertise_data,
                        std::vector<uint8_t> scan_response_data, int timeout_s,
                        std::vector<uint8_t> scan_response_data, int duration,
                        MultiAdvCb timeout_cb) override {
    /* a temporary type for holding all the data needed in callbacks below*/
    struct CreatorParams {
@@ -250,7 +252,7 @@ class BleAdvertisingManagerImpl
      tBTM_BLE_ADV_PARAMS params;
      std::vector<uint8_t> advertise_data;
      std::vector<uint8_t> scan_response_data;
      int timeout_s;
      int duration;
      MultiAdvCb timeout_cb;
    };

@@ -262,7 +264,7 @@ class BleAdvertisingManagerImpl
    c->params = *params;
    c->advertise_data = std::move(advertise_data);
    c->scan_response_data = std::move(scan_response_data);
    c->timeout_s = timeout_s;
    c->duration = duration;
    c->timeout_cb = std::move(timeout_cb);
    c->inst_id = advertiser_id;

@@ -306,7 +308,7 @@ class BleAdvertisingManagerImpl
                      return;
                    }

                    c->self->Enable(c->inst_id, true, c->cb, c->timeout_s, std::move(c->timeout_cb));
                    c->self->Enable(c->inst_id, true, c->cb, c->duration, 0, std::move(c->timeout_cb));

                }, base::Passed(&c)));
            }, base::Passed(&c)));
@@ -319,7 +321,8 @@ class BleAdvertisingManagerImpl
                           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,
                           std::vector<uint8_t> periodic_data,
                           uint16_t duration, uint8_t maxExtAdvEvents,
                           RegisterCb timeout_cb) override {
    std::unique_ptr<CreatorParams> c;
    c.reset(new CreatorParams());
@@ -331,7 +334,8 @@ class BleAdvertisingManagerImpl
    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->duration = duration;
    c->maxExtAdvEvents = maxExtAdvEvents;
    c->timeout_cb = std::move(timeout_cb);


@@ -441,7 +445,8 @@ class BleAdvertisingManagerImpl

  void StartAdvertisingSetFinish(c_type c) {
    uint8_t inst_id = c->inst_id;
    int timeout_s = c->timeout_s;
    uint16_t duration = c->duration;
    uint8_t maxExtAdvEvents = c->maxExtAdvEvents;
    RegisterCb timeout_cb = std::move(c->timeout_cb);
    BleAdvertisingManagerImpl* self = c->self;
    MultiAdvCb enable_cb = Bind(
@@ -457,11 +462,11 @@ class BleAdvertisingManagerImpl
        },
        base::Passed(&c));

    self->Enable(inst_id, true, std::move(enable_cb), timeout_s,
    self->Enable(inst_id, true, std::move(enable_cb), duration, maxExtAdvEvents,
                 Bind(std::move(timeout_cb), inst_id));
  }

  void EnableWithTimerCb(uint8_t inst_id, MultiAdvCb enable_cb, int timeout_s,
  void EnableWithTimerCb(uint8_t inst_id, MultiAdvCb enable_cb, int duration,
                         MultiAdvCb timeout_cb, uint8_t status) {
    VLOG(1) << __func__ << " inst_id: " << +inst_id;
    AdvertisingInstance* p_inst = &adv_inst[inst_id];
@@ -469,21 +474,20 @@ class BleAdvertisingManagerImpl
    // Run the regular enable callback
    enable_cb.Run(status);

    p_inst->timeout_s = timeout_s;
    p_inst->duration = duration;
    p_inst->timeout_timer = alarm_new("btm_ble.adv_timeout");

    base::Closure cb = Bind(&BleAdvertisingManagerImpl::Enable,
                            base::Unretained(this), inst_id, 0 /* disable */,
                            std::move(timeout_cb), 0, base::Bind(DoNothing));
                            std::move(timeout_cb), 0, 0, base::Bind(DoNothing));

    // schedule disable when the timeout passes
    alarm_set_closure_on_queue(FROM_HERE, p_inst->timeout_timer,
                               timeout_s * 1000, std::move(cb),
                               btu_general_alarm_queue);
    alarm_set_closure_on_queue(FROM_HERE, p_inst->timeout_timer, duration * 100,
                               std::move(cb), btu_general_alarm_queue);
  }

  void Enable(uint8_t inst_id, bool enable, MultiAdvCb cb, int timeout_s,
              MultiAdvCb timeout_cb) {
  void Enable(uint8_t inst_id, bool enable, MultiAdvCb cb, uint16_t duration,
              uint8_t maxExtAdvEvents, MultiAdvCb timeout_cb) override {
    VLOG(1) << __func__ << " inst_id: " << +inst_id;
    if (inst_id >= inst_count) {
      LOG(ERROR) << "bad instance id " << +inst_id;
@@ -491,18 +495,24 @@ class BleAdvertisingManagerImpl
    }

    AdvertisingInstance* p_inst = &adv_inst[inst_id];
    VLOG(1) << __func__ << " enable: " << enable << ", timeout: " << +timeout_s;
    VLOG(1) << __func__ << " enable: " << enable << ", duration: " << +duration;
    if (!p_inst->in_use) {
      LOG(ERROR) << "Invalid or no active instance";
      cb.Run(BTM_BLE_MULTI_ADV_FAILURE);
      return;
    }

    if (enable && timeout_s) {
    if (enable && (duration || maxExtAdvEvents)) {
      p_inst->timeout_cb = timeout_cb;
    }

    if (enable && duration) {
      // TODO(jpawlowski): HCI implementation that can't do duration should
      // emulate it, not EnableWithTimerCb.
      GetHciInterface()->Enable(
          enable, p_inst->inst_id, 0x0000, 0x00,
          enable, p_inst->inst_id, duration, maxExtAdvEvents,
          Bind(&BleAdvertisingManagerImpl::EnableWithTimerCb,
               base::Unretained(this), inst_id, std::move(cb), timeout_s,
               base::Unretained(this), inst_id, std::move(cb), duration,
               std::move(timeout_cb)));

    } else {
@@ -512,7 +522,8 @@ class BleAdvertisingManagerImpl
        p_inst->timeout_timer = nullptr;
      }

      GetHciInterface()->Enable(enable, p_inst->inst_id, 0x0000, 0x00, cb);
      GetHciInterface()->Enable(enable, p_inst->inst_id, duration,
                                maxExtAdvEvents, cb);
    }
  }

@@ -568,7 +579,7 @@ class BleAdvertisingManagerImpl
    if (!is_scan_rsp && is_connectable(p_inst->advertising_event_properties)) {
      uint8_t flags_val = BTM_GENERAL_DISCOVERABLE;

      if (p_inst->timeout_s) flags_val = BTM_LIMITED_DISCOVERABLE;
      if (p_inst->duration) flags_val = BTM_LIMITED_DISCOVERABLE;

      std::vector<uint8_t> flags;
      flags.push_back(2);  // length
@@ -700,6 +711,17 @@ class BleAdvertisingManagerImpl
            << ", advertising_handle: 0x" << std::hex << +advertising_handle
            << ", connection_handle: 0x" << std::hex << +connection_handle;

    if (status == 0x43 || status == 0x3C) {
      // either duration elapsed, or maxExtAdvEvents reached
      if (p_inst->timeout_cb.is_null()) {
        LOG(INFO) << __func__ << "No timeout callback";
        return;
      }

      p_inst->timeout_cb.Run(status);
      return;
    }

#if (BLE_PRIVACY_SPT == TRUE)
    if (BTM_BleLocalPrivacyEnabled() &&
        advertising_handle <= BTM_BLE_MULTI_ADV_MAX) {
Loading