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

Commit 7c14d52c authored by Jakub Pawlowski's avatar Jakub Pawlowski Committed by Gerrit Code Review
Browse files

Merge "Add tracking of periodic_enable in adv_inst"

parents 621d73be 023cdf99
Loading
Loading
Loading
Loading
+29 −1
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ struct AdvertisingInstance {
  BD_ADDR own_address;
  MultiAdvCb timeout_cb;
  bool address_update_required;
  bool periodic_enabled;

  /* When true, advertising set is enabled, or last scheduled call to "LE Set
   * Extended Advertising Set Enable" is to enable this advertising set. Any
@@ -88,6 +89,7 @@ struct AdvertisingInstance {
        own_address_type(0),
        own_address{0},
        address_update_required(false),
        periodic_enabled(false),
        enable_status(false) {
    adv_raddr_timer = alarm_new_periodic("btm_ble.adv_raddr_timer");
  }
@@ -758,7 +760,27 @@ class BleAdvertisingManagerImpl
                                    MultiAdvCb cb) override {
    VLOG(1) << __func__ << " inst_id: " << +inst_id << ", enable: " << +enable;

    GetHciInterface()->SetPeriodicAdvertisingEnable(enable, inst_id, cb);
    AdvertisingInstance* p_inst = &adv_inst[inst_id];
    if (!p_inst->in_use) {
      LOG(ERROR) << "Invalid or not active instance";
      cb.Run(BTM_BLE_MULTI_ADV_FAILURE);
      return;
    }

    MultiAdvCb enable_cb = Bind(
        [](AdvertisingInstance* p_inst, uint8_t enable, MultiAdvCb cb,
           uint8_t status) {
          VLOG(1) << "periodc adv enable cb: inst_id: " << +p_inst->inst_id
                  << ", enable: " << +enable << ", status: " << std::hex
                  << +status;
          if (!status) p_inst->periodic_enabled = enable;

          cb.Run(status);
        },
        p_inst, enable, std::move(cb));

    GetHciInterface()->SetPeriodicAdvertisingEnable(enable, inst_id,
                                                    std::move(enable_cb));
  }

  void Unregister(uint8_t inst_id) override {
@@ -775,6 +797,12 @@ class BleAdvertisingManagerImpl
      GetHciInterface()->Enable(false, inst_id, 0x00, 0x00, Bind(DoNothing));
    }

    if (p_inst->periodic_enabled) {
      p_inst->periodic_enabled = false;
      GetHciInterface()->SetPeriodicAdvertisingEnable(false, inst_id,
                                                      Bind(DoNothing));
    }

    alarm_cancel(p_inst->adv_raddr_timer);
    p_inst->in_use = false;
    GetHciInterface()->RemoveAdvertisingSet(inst_id, Bind(DoNothing));
+90 −0
Original line number Diff line number Diff line
@@ -741,3 +741,93 @@ TEST_F(BleAdvertisingManagerTest,
  disable_cb.Run(0);
  remove_cb.Run(0);
}

/* This test makes sure that periodic advertising is stopped before
 * unregistering the advertiser, if it was enabled. */
TEST_F(BleAdvertisingManagerTest, test_periodic_adv_disable_on_unregister) {
  std::vector<uint8_t> adv_data;
  std::vector<uint8_t> scan_resp;
  tBTM_BLE_ADV_PARAMS params;
  params.advertising_event_properties = 0x1 /* connectable */;
  tBLE_PERIODIC_ADV_PARAMS periodic_params;
  periodic_params.enable = true;  // enable periodic advertising
  std::vector<uint8_t> periodic_data;

  parameters_cb set_params_cb;
  status_cb set_address_cb;
  status_cb set_data_cb;
  status_cb set_scan_resp_data_cb;
  status_cb enable_cb;
  status_cb set_periodic_params_cb;
  status_cb set_periodic_data_cb;
  status_cb set_periodic_enable_cb;
  EXPECT_CALL(*hci_mock, SetParameters1(_, _, _, _, _, _, _, _, _)).Times(1);
  EXPECT_CALL(*hci_mock, SetParameters2(_, _, _, _, _, _, _, _))
      .Times(1)
      .WillOnce(SaveArg<7>(&set_params_cb));
  EXPECT_CALL(*hci_mock, SetRandomAddress(_, _, _))
      .Times(1)
      .WillOnce(SaveArg<2>(&set_address_cb));
  EXPECT_CALL(*hci_mock, SetAdvertisingData(_, _, _, _, _, _))
      .Times(1)
      .WillOnce(SaveArg<5>(&set_data_cb));
  EXPECT_CALL(*hci_mock, SetScanResponseData(_, _, _, _, _, _))
      .Times(1)
      .WillOnce(SaveArg<5>(&set_scan_resp_data_cb));
  EXPECT_CALL(*hci_mock, SetPeriodicAdvertisingParameters(_, _, _, _, _))
      .Times(1)
      .WillOnce(SaveArg<4>(&set_periodic_params_cb));
  EXPECT_CALL(*hci_mock, SetPeriodicAdvertisingData(_, _, _, _, _))
      .Times(1)
      .WillOnce(SaveArg<4>(&set_periodic_data_cb));
  EXPECT_CALL(*hci_mock, SetPeriodicAdvertisingEnable(0x01 /* enable */, _, _))
      .Times(1)
      .WillOnce(SaveArg<2>(&set_periodic_enable_cb));
  EXPECT_CALL(*hci_mock, Enable(0x01 /* enable */, _, _, _, _))
      .Times(1)
      .WillOnce(SaveArg<4>(&enable_cb));

  BleAdvertisingManager::Get()->StartAdvertisingSet(
      Bind(&BleAdvertisingManagerTest::StartAdvertisingSetCb,
           base::Unretained(this)),
      &params, adv_data, scan_resp, &periodic_params, periodic_data,
      0 /* duration */, 0 /* maxExtAdvEvents */, Bind(DoNothing2));

  // we are a truly gracious fake controller, let the commands succeed!
  int selected_tx_power = -15;
  set_params_cb.Run(0, selected_tx_power);
  set_address_cb.Run(0);
  set_data_cb.Run(0);
  set_scan_resp_data_cb.Run(0);
  set_periodic_params_cb.Run(0);
  set_periodic_data_cb.Run(0);
  set_periodic_enable_cb.Run(0);
  enable_cb.Run(0);
  EXPECT_EQ(BTM_BLE_MULTI_ADV_SUCCESS, start_advertising_set_status);
  EXPECT_EQ(selected_tx_power, start_advertising_set_tx_power);
  int advertiser_id = start_advertising_set_advertiser_id;
  ::testing::Mock::VerifyAndClearExpectations(hci_mock.get());

  // ... advertising ...

  // Unregister advertiser - should disable periodic advertising
  status_cb disable_cb;
  EXPECT_CALL(*hci_mock, Enable(0x00 /* disable */, advertiser_id, _, _, _))
      .Times(1)
      .WillOnce(SaveArg<4>(&disable_cb));
  status_cb disable_periodic_cb;
  EXPECT_CALL(*hci_mock, SetPeriodicAdvertisingEnable(0x00 /* disable */,
                                                      advertiser_id, _))
      .Times(1)
      .WillOnce(SaveArg<2>(&disable_periodic_cb));
  status_cb remove_cb;
  EXPECT_CALL(*hci_mock, RemoveAdvertisingSet(advertiser_id, _))
      .Times(1)
      .WillOnce(SaveArg<1>(&remove_cb));
  BleAdvertisingManager::Get()->Unregister(advertiser_id);
  ::testing::Mock::VerifyAndClearExpectations(hci_mock.get());

  disable_cb.Run(0);
  disable_periodic_cb.Run(0);
  remove_cb.Run(0);
}