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

Commit 70c2210f authored by Alice Kuo's avatar Alice Kuo
Browse files

csip: update the csip group information from the storage

As bluetooth turn on, Setting UI need the csip group information
including group id, uuid, desired size to update the UI to update the
member devices to be one entry. Bt stack add the information from
storage and callback, onDeviceAvailable, to upper layer. The mechnism is
similar with hearing aid.

Bug: 150670922
Bug: 178981521
Test: bonded with a coordinated set. Check the UI only have one entry as Bluetooth turn on and device reboot.
Test: atest bluetooth_groups_test; atest bluetooth_csis_test
Change-Id: I8d7dbef4f5872fadd26e068a05bcd3d2c71349bd
parent 042b7a35
Loading
Loading
Loading
Loading
+58 −10
Original line number Diff line number Diff line
@@ -101,7 +101,8 @@ class CsisClientImpl : public CsisClient {
      sizeof(CSIS_STORAGE_CURRENT_LAYOUT_MAGIC) +
      sizeof(uint8_t); /* num_of_sets */
  static constexpr size_t CSIS_STORAGE_ENTRY_SZ =
      sizeof(uint8_t) /* set_id */ + Octet16().size();
      sizeof(uint8_t) /* set_id */ + sizeof(uint8_t) /* desired_size */ +
      Octet16().size();

 public:
  CsisClientImpl(bluetooth::csis::CsisClientCallbacks* callbacks,
@@ -135,12 +136,12 @@ class CsisClientImpl : public CsisClient {

  std::shared_ptr<bluetooth::csis::CsisGroup> AssignCsisGroup(
      const RawAddress& address, int group_id,
      bool create_group_if_non_existing) {
      bool create_group_if_non_existing, const bluetooth::Uuid& uuid) {
    auto csis_group = FindCsisGroup(group_id);
    if (!csis_group) {
      if (create_group_if_non_existing) {
        /* Let's create a group */
        auto g = std::make_shared<CsisGroup>(group_id);
        auto g = std::make_shared<CsisGroup>(group_id, uuid);
        csis_groups_.push_back(g);
        csis_group = FindCsisGroup(group_id);
      } else {
@@ -166,14 +167,14 @@ class CsisClientImpl : public CsisClient {
    DLOG(INFO) << __func__ << " address: " << address << " uuid: " << uuid
               << " group_id: " << group_id;

    AssignCsisGroup(address, group_id, true);
    AssignCsisGroup(address, group_id, true, uuid);
  }

  void OnGroupMemberAddedCb(const RawAddress& address, int group_id) {
    DLOG(INFO) << __func__ << " address: " << address
               << " group_id: " << group_id;

    AssignCsisGroup(address, group_id, false);
    AssignCsisGroup(address, group_id, false, Uuid::kEmpty);
  }

  void OnGroupRemovedCb(const bluetooth::Uuid& uuid, int group_id) {
@@ -187,6 +188,32 @@ class CsisClientImpl : public CsisClient {
    if (device) RemoveCsisDevice(device, group_id);
  }

  void onGroupAddFromStorageCb(const RawAddress& address,
                               const bluetooth::Uuid& uuid, int group_id) {
    auto device = FindDeviceByAddress(address);
    if (device == nullptr) return;

    auto csis_group = FindCsisGroup(group_id);
    if (csis_group == nullptr) {
      LOG(ERROR) << __func__ << "the csis group (id: " << group_id
                 << ") does not exist";
      return;
    }

    if (!csis_group->IsDeviceInTheGroup(device)) {
      LOG(ERROR) << __func__ << "the csis group (id: " << group_id
                 << ") does contain the device: " << address;
      return;
    }

    if (csis_group->GetUuid() == Uuid::kEmpty) {
      csis_group->SetUuid(uuid);
    }

    callbacks_->OnDeviceAvailable(device->addr, csis_group->GetGroupId(),
                                  csis_group->GetDesiredSize(), uuid);
  }

  void Connect(const RawAddress& address) override {
    DLOG(INFO) << __func__ << ": " << address;

@@ -495,6 +522,7 @@ class CsisClientImpl : public CsisClient {
          }

          UINT8_TO_STREAM(ptr, gid);
          UINT8_TO_STREAM(ptr, csis_group->GetDesiredSize());
          Octet16 sirk = csis_group->GetSirk();
          memcpy(ptr, sirk.data(), sirk.size());
          ptr += sirk.size();
@@ -524,12 +552,15 @@ class CsisClientImpl : public CsisClient {
      while (num_sets--) {
        uint8_t gid;
        Octet16 sirk;
        uint8_t size;

        STREAM_TO_UINT8(gid, ptr);
        STREAM_TO_UINT8(size, ptr);
        STREAM_TO_ARRAY(sirk.data(), ptr, (int)sirk.size());

        // Set grouping and SIRK
        auto csis_group = AssignCsisGroup(addr, gid, true);
        auto csis_group = AssignCsisGroup(addr, gid, true, Uuid::kEmpty);
        csis_group->SetDesiredSize(size);
        csis_group->SetSirk(sirk);
      }
    }
@@ -539,16 +570,26 @@ class CsisClientImpl : public CsisClient {
                      bool autoconnect) {
    DeserializeSets(addr, in);

    if (!autoconnect) return;

    auto device = FindDeviceByAddress(addr);
    if (device == nullptr) {
      auto dev = std::make_shared<CsisDevice>(addr, false);
      devices_.push_back(dev);
    }

    for (const auto& csis_group : csis_groups_) {
      if (!csis_group->IsDeviceInTheGroup(device)) continue;

      if (csis_group->GetUuid() != Uuid::kEmpty) {
        callbacks_->OnDeviceAvailable(device->addr, csis_group->GetGroupId(),
                                      csis_group->GetDesiredSize(),
                                      csis_group->GetUuid());
      }
    }

    if (autoconnect) {
        BTA_GATTC_Open(gatt_if_, addr, false, false);
    }
  }

  void CleanUp() {
    DLOG(INFO) << __func__;
@@ -1221,7 +1262,8 @@ class CsisClientImpl : public CsisClient {
        LOG_ASSERT(group_id != -1);

        /* Create new group */
        auto g = std::make_shared<CsisGroup>(group_id);
        auto g =
            std::make_shared<CsisGroup>(group_id, csis_instance->GetUuid());
        csis_groups_.push_back(g);
      } else {
        dev_groups_->AddDevice(device->addr, csis_instance->GetUuid(),
@@ -1763,6 +1805,12 @@ class DeviceGroupsCallbacksImpl : public DeviceGroupsCallbacks {
  void OnGroupMemberRemoved(const RawAddress& address, int group_id) override {
    if (instance) instance->OnGroupMemberRemovedCb(address, group_id);
  }

  void onGroupAddFromStorage(const RawAddress& address,
                             const bluetooth::Uuid& uuid,
                             int group_id) override {
    if (instance) instance->onGroupAddFromStorageCb(address, uuid, group_id);
  }
};

class DeviceGroupsCallbacksImpl;
+16 −16
Original line number Diff line number Diff line
@@ -741,14 +741,14 @@ TEST_F(CsisClientTest, test_get_group_id) {

TEST_F(CsisClientTest, test_is_group_empty) {
  std::list<std::shared_ptr<CsisGroup>> csis_groups_;
  auto g_1 = std::make_shared<CsisGroup>(666);
  auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
  csis_groups_.push_back(g_1);

  ASSERT_TRUE(g_1->IsEmpty());
}

TEST_F(CsisClientTest, test_add_device_to_group) {
  auto g_1 = std::make_shared<CsisGroup>(666);
  auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
  auto d_1 = std::make_shared<CsisDevice>();

  ASSERT_TRUE(g_1->IsEmpty());
@@ -757,19 +757,19 @@ TEST_F(CsisClientTest, test_add_device_to_group) {
}

TEST_F(CsisClientTest, test_set_desired_size) {
  auto g_1 = std::make_shared<CsisGroup>(666);
  auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
  g_1->SetDesiredSize(10);
  ASSERT_EQ((int)sizeof(g_1), 16);
}

TEST_F(CsisClientTest, test_get_desired_size) {
  auto g_1 = std::make_shared<CsisGroup>(666);
  auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
  g_1->SetDesiredSize(10);
  ASSERT_EQ(g_1->GetDesiredSize(), 10);
}

TEST_F(CsisClientTest, test_is_device_in_the_group) {
  auto g_1 = std::make_shared<CsisGroup>(666);
  auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
  auto d_1 = std::make_shared<CsisDevice>();
  g_1->AddDevice(d_1);
  g_1->IsDeviceInTheGroup(d_1);
@@ -779,7 +779,7 @@ TEST_F(CsisClientTest, test_get_current_size) {
  const RawAddress test_address_1 = GetTestAddress(0);
  const RawAddress test_address_2 = GetTestAddress(1);
  const RawAddress test_address_3 = GetTestAddress(2);
  auto g_1 = std::make_shared<CsisGroup>(666);
  auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
  auto d_1 = std::make_shared<CsisDevice>(test_address_1, true);
  auto d_2 = std::make_shared<CsisDevice>(test_address_2, true);
  auto d_3 = std::make_shared<CsisDevice>(test_address_3, true);
@@ -790,25 +790,25 @@ TEST_F(CsisClientTest, test_get_current_size) {
}

TEST_F(CsisClientTest, test_set_current_lock_state_unset) {
  auto g_1 = std::make_shared<CsisGroup>(666);
  auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
  g_1->SetCurrentLockState(CsisLockState::CSIS_STATE_UNSET);
  ASSERT_EQ(g_1->GetCurrentLockState(), CsisLockState::CSIS_STATE_UNSET);
}

TEST_F(CsisClientTest, test_set_current_lock_state_locked) {
  auto g_1 = std::make_shared<CsisGroup>(666);
  auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
  g_1->SetCurrentLockState(CsisLockState::CSIS_STATE_LOCKED);
  ASSERT_EQ(g_1->GetCurrentLockState(), CsisLockState::CSIS_STATE_LOCKED);
}

TEST_F(CsisClientTest, test_set_current_lock_state_unlocked) {
  auto g_1 = std::make_shared<CsisGroup>(666);
  auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
  g_1->SetCurrentLockState(CsisLockState::CSIS_STATE_UNLOCKED);
  ASSERT_EQ(g_1->GetCurrentLockState(), CsisLockState::CSIS_STATE_UNLOCKED);
}

TEST_F(CsisClientTest, test_set_various_lock_states) {
  auto g_1 = std::make_shared<CsisGroup>(666);
  auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
  g_1->SetCurrentLockState(CsisLockState::CSIS_STATE_UNLOCKED);
  ASSERT_EQ(g_1->GetCurrentLockState(), CsisLockState::CSIS_STATE_UNLOCKED);
  g_1->SetCurrentLockState(CsisLockState::CSIS_STATE_LOCKED);
@@ -818,27 +818,27 @@ TEST_F(CsisClientTest, test_set_various_lock_states) {
}

TEST_F(CsisClientTest, test_set_discovery_state_completed) {
  auto g_1 = std::make_shared<CsisGroup>(666);
  auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
  g_1->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_COMPLETED);
  ASSERT_EQ(g_1->GetDiscoveryState(),
            CsisDiscoveryState::CSIS_DISCOVERY_COMPLETED);
}

TEST_F(CsisClientTest, test_set_discovery_state_idle) {
  auto g_1 = std::make_shared<CsisGroup>(666);
  auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
  g_1->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_IDLE);
  ASSERT_EQ(g_1->GetDiscoveryState(), CsisDiscoveryState::CSIS_DISCOVERY_IDLE);
}

TEST_F(CsisClientTest, test_set_discovery_state_ongoing) {
  auto g_1 = std::make_shared<CsisGroup>(666);
  auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
  g_1->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_ONGOING);
  ASSERT_EQ(g_1->GetDiscoveryState(),
            CsisDiscoveryState::CSIS_DISCOVERY_ONGOING);
}

TEST_F(CsisClientTest, test_set_various_discovery_states) {
  auto g_1 = std::make_shared<CsisGroup>(666);
  auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
  g_1->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_COMPLETED);
  ASSERT_EQ(g_1->GetDiscoveryState(),
            CsisDiscoveryState::CSIS_DISCOVERY_COMPLETED);
@@ -853,7 +853,7 @@ TEST_F(CsisClientTest, test_get_first_last_device) {
  const RawAddress test_address_3 = GetTestAddress(3);
  const RawAddress test_address_4 = GetTestAddress(4);
  const RawAddress test_address_5 = GetTestAddress(5);
  auto g_1 = std::make_shared<CsisGroup>(666);
  auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
  auto d_1 = std::make_shared<CsisDevice>(test_address_3, true);
  auto d_2 = std::make_shared<CsisDevice>(test_address_4, true);
  auto d_3 = std::make_shared<CsisDevice>(test_address_5, true);
@@ -865,7 +865,7 @@ TEST_F(CsisClientTest, test_get_first_last_device) {
}

TEST_F(CsisClientTest, test_get_set_sirk) {
  auto g_1 = std::make_shared<CsisGroup>(666);
  auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
  Octet16 sirk = {1};
  g_1->SetSirk(sirk);
  ASSERT_EQ(g_1->GetSirk(), sirk);
+5 −1
Original line number Diff line number Diff line
@@ -279,9 +279,10 @@ class CsisDevice : public GattServiceDevice {
 */
class CsisGroup {
 public:
  CsisGroup(int group_id)
  CsisGroup(int group_id, const bluetooth::Uuid& uuid)
      : group_id_(group_id),
        size_(kDefaultCsisSetSize),
        uuid_(uuid),
        member_discovery_state_(CsisDiscoveryState::CSIS_DISCOVERY_IDLE),
        lock_state_(CsisLockState::CSIS_STATE_UNSET),
        target_lock_state_(CsisLockState::CSIS_STATE_UNSET),
@@ -303,6 +304,8 @@ class CsisGroup {
  }

  int GetCurrentSize(void) const { return devices_.size(); }
  bluetooth::Uuid GetUuid() const { return uuid_; }
  void SetUuid(const bluetooth::Uuid& uuid) { uuid_ = uuid; }
  int GetGroupId(void) const { return group_id_; }
  int GetDesiredSize(void) const { return size_; }
  void SetDesiredSize(int size) { size_ = size; }
@@ -455,6 +458,7 @@ class CsisGroup {
  Octet16 sirk_ = {0};
  bool sirk_available_ = false;
  int size_;
  bluetooth::Uuid uuid_;

  std::vector<std::shared_ptr<CsisDevice>> devices_;
  CsisDiscoveryState member_discovery_state_;
+4 −0
Original line number Diff line number Diff line
@@ -224,6 +224,10 @@ class DeviceGroupsImpl : public DeviceGroups {
        auto* group =
            get_or_create_group_with_id(id, Uuid::From128BitLE(uuid128));
        if (group) add_to_group(addr, group);

        for (auto c : callbacks_) {
          c->onGroupAddFromStorage(addr, Uuid::From128BitLE(uuid128), id);
        }
      }
    }
  }
+4 −0
Original line number Diff line number Diff line
@@ -65,6 +65,10 @@ class MockGroupsCallbacks : public DeviceGroupsCallbacks {
              (const bluetooth::Uuid& uuid, int group_id), (override));
  MOCK_METHOD((void), OnGroupMemberRemoved,
              (const RawAddress& address, int group_id), (override));
  MOCK_METHOD((void), onGroupAddFromStorage,
              (const RawAddress& address, const bluetooth::Uuid& uuid,
               int group_id),
              (override));

 private:
  DISALLOW_COPY_AND_ASSIGN(MockGroupsCallbacks);
Loading