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

Commit bfd8de08 authored by Łukasz Rymanowski's avatar Łukasz Rymanowski
Browse files

csis: Allow to connect profile only when device is bonded

Fixing a race, when profile Connect message reach the native stack just
after device got unbonded.

Bug: 329781005
Test: atest bluetooth_csis_test
Flag: Exempt, Fixing race which will happen only on the stress tests
Change-Id: Iec2b5dd78fe11c1705d50f3f92d29686e45dfaac
parent db35cef7
Loading
Loading
Loading
Loading
+23 −4
Original line number Diff line number Diff line
@@ -246,10 +246,16 @@ class CsisClientImpl : public CsisClient {
  }

  void Connect(const RawAddress& address) override {
    log::debug("{}", ADDRESS_TO_LOGGABLE_CSTR(address));
    log::info("{}", ADDRESS_TO_LOGGABLE_CSTR(address));

    auto device = FindDeviceByAddress(address);
    if (device == nullptr) {
      if (!BTM_IsLinkKeyKnown(address, BT_TRANSPORT_LE)) {
        log::error("Connecting  {} when not bonded",
                   ADDRESS_TO_LOGGABLE_CSTR(address));
        callbacks_->OnConnectionState(address, ConnectionState::DISCONNECTED);
        return;
      }
      devices_.emplace_back(std::make_shared<CsisDevice>(address, true));
    } else {
      device->connecting_actively = true;
@@ -280,13 +286,19 @@ class CsisClientImpl : public CsisClient {
  }

  void RemoveDevice(const RawAddress& addr) override {
    log::debug("{}", ADDRESS_TO_LOGGABLE_CSTR(addr));
    log::info("{}", ADDRESS_TO_LOGGABLE_CSTR(addr));

    auto device = FindDeviceByAddress(addr);
    if (!device) return;
    if (device == nullptr) {
      log::warn("{} not found", ADDRESS_TO_LOGGABLE_CSTR(addr));
      return;
    }

    Disconnect(addr);

    if (device->GetNumberOfCsisInstances() == 0) {
      RemoveCsisDevice(device);
    }
    dev_groups_->RemoveDevice(addr);
  }

@@ -772,7 +784,14 @@ class CsisClientImpl : public CsisClient {
    return nullptr;
  }

  void RemoveCsisDevice(std::shared_ptr<CsisDevice>& device) {
    auto it = find_if(devices_.begin(), devices_.end(),
                      CsisDevice::MatchAddress(device->addr));
    devices_.erase(it);
  }

  void RemoveCsisDevice(std::shared_ptr<CsisDevice>& device, int group_id) {
    log::info("");
    auto it = find_if(devices_.begin(), devices_.end(),
                      CsisDevice::MatchAddress(device->addr));
    if (it == devices_.end()) return;
@@ -782,7 +801,7 @@ class CsisClientImpl : public CsisClient {
      if (!csis_group) {
        /* This could happen when remove device is called when bonding is
         * removed */
        log::debug("group not found {}", group_id);
        log::info("group not found {}", group_id);
        return;
      }

+18 −0
Original line number Diff line number Diff line
@@ -434,6 +434,9 @@ class CsisClientTest : public ::testing::Test {
    SetMockCsisLockCallback(&csis_lock_cb);
    callbacks.reset(new MockCsisCallbacks());

    ON_CALL(btm_interface, IsLinkKeyKnown(_, _))
        .WillByDefault(DoAll(Return(true)));

    ON_CALL(btm_interface, BTM_IsEncrypted(_, _))
        .WillByDefault(DoAll(Return(true)));

@@ -784,6 +787,21 @@ TEST_F(CsisClientTest, test_disconnected) {
  TestAppUnregister();
}

TEST_F(CsisClientTest, test_connect_after_remove) {
  TestAppRegister();
  TestConnect(test_address);
  InjectConnectedEvent(test_address, 1);
  CsisClient::Get()->RemoveDevice(test_address);

  EXPECT_CALL(*callbacks,
              OnConnectionState(test_address, ConnectionState::DISCONNECTED));
  ON_CALL(btm_interface, IsLinkKeyKnown(_, _)).WillByDefault(Return(false));
  CsisClient::Get()->Connect(test_address);
  Mock::VerifyAndClearExpectations(callbacks.get());

  TestAppUnregister();
}

TEST_F(CsisClientTest, test_discovery_csis_found) {
  SetSampleDatabaseCsis(1, 1);
  TestAppRegister();