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

Commit 37b7e883 authored by Łukasz Rymanowski's avatar Łukasz Rymanowski Committed by Automerger Merge Worker
Browse files

csis: Make CSIS opportunistic when connecting from autoconnect am: 3edec369

parents 946c8af0 3edec369
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include "bta_gatt_api.h"
#include "bta_gatt_queue.h"
#include "bta_groups.h"
#include "bta_le_audio_uuids.h"
#include "bta_sec_api.h"
#include "btif_storage.h"
#include "crypto_toolbox/crypto_toolbox.h"
@@ -664,6 +665,7 @@ class CsisClientImpl : public CsisClient {
      devices_.push_back(device);
    }

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

@@ -677,11 +679,20 @@ class CsisClientImpl : public CsisClient {
        callbacks_->OnDeviceAvailable(device->addr, group_id,
                                      csis_group->GetDesiredSize(), rank,
                                      csis_group->GetUuid());

        if (csis_group->GetUuid() ==
            bluetooth::Uuid::From16Bit(UUID_COMMON_AUDIO_SERVICE)) {
          is_le_audio_device = true;
        }
      }
    }

    /* For now, if this is LeAudio device, CSIP is opportunistic profile. */
    bool is_opportunistic = is_le_audio_device;

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

@@ -695,6 +706,7 @@ class CsisClientImpl : public CsisClient {
    }

    devices_.clear();
    csis_groups_.clear();

    CsisObserverSetBackground(false);
    dev_groups_->CleanUp(device_group_callbacks);
+139 −18
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include "bta_dm_api_mock.h"
#include "bta_gatt_api_mock.h"
#include "bta_gatt_queue_mock.h"
#include "bta_le_audio_uuids.h"
#include "btif_profile_storage.h"
#include "btm_api_mock.h"
#include "csis_types.h"
@@ -57,6 +58,7 @@ using bluetooth::csis::CsisGroupLockStatus;
using bluetooth::groups::DeviceGroups;

using testing::_;
using testing::AtLeast;
using testing::DoAll;
using testing::DoDefault;
using testing::Invoke;
@@ -125,6 +127,92 @@ class MockCsisCallbacks : public CsisClientCallbacks {

class CsisClientTest : public ::testing::Test {
 private:
  void set_sample_cap_included_database(uint16_t conn_id, bool csis,
                                        bool csis_broken, uint8_t rank,
                                        uint8_t sirk_msb = 1) {
    gatt::DatabaseBuilder builder;
    builder.AddService(0x0001, 0x0003, Uuid::From16Bit(0x1800), true);
    builder.AddCharacteristic(0x0002, 0x0003, Uuid::From16Bit(0x2a00),
                              GATT_CHAR_PROP_BIT_READ);
    if (csis) {
      builder.AddService(0x0005, 0x0009,
                         bluetooth::Uuid::From16Bit(UUID_COMMON_AUDIO_SERVICE),
                         true);
      builder.AddIncludedService(0x0006, kCsisServiceUuid, 0x0010, 0x0030);

      builder.AddService(0x0010, 0x0030, kCsisServiceUuid, true);
      builder.AddCharacteristic(
          0x0020, 0x0021, kCsisSirkUuid,
          GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);

      builder.AddDescriptor(0x0022,
                            Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
      builder.AddCharacteristic(
          0x0023, 0x0024, kCsisSizeUuid,
          GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
      builder.AddDescriptor(0x0025,
                            Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
      builder.AddCharacteristic(0x0026, 0x0027, kCsisLockUuid,
                                GATT_CHAR_PROP_BIT_READ |
                                    GATT_CHAR_PROP_BIT_NOTIFY |
                                    GATT_CHAR_PROP_BIT_WRITE);
      builder.AddDescriptor(0x0028,
                            Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
      builder.AddCharacteristic(0x0029, 0x0030, kCsisRankUuid,
                                GATT_CHAR_PROP_BIT_READ);
    }
    if (csis_broken) {
      builder.AddCharacteristic(
          0x0020, 0x0021, kCsisSirkUuid,
          GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);

      builder.AddDescriptor(0x0022,
                            Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
    }
    builder.AddService(0x0090, 0x0093,
                       Uuid::From16Bit(UUID_SERVCLASS_GATT_SERVER), true);
    builder.AddCharacteristic(0x0091, 0x0092,
                              Uuid::From16Bit(GATT_UUID_GATT_SRV_CHGD),
                              GATT_CHAR_PROP_BIT_NOTIFY);
    builder.AddDescriptor(0x0093,
                          Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
    services_map[conn_id] = builder.Build().Services();

    ON_CALL(gatt_queue, ReadCharacteristic(conn_id, _, _, _))
        .WillByDefault(
            Invoke([rank, sirk_msb](uint16_t conn_id, uint16_t handle,
                                    GATT_READ_OP_CB cb, void* cb_data) -> void {
              std::vector<uint8_t> value;

              switch (handle) {
                case 0x0003:
                  /* device name */
                  value.resize(20);
                  break;
                case 0x0021:
                  value.assign(17, 1);
                  value[16] = sirk_msb;
                  break;
                case 0x0024:
                  value.resize(1);
                  break;
                case 0x0027:
                  value.resize(1);
                  break;
                case 0x0030:
                  value.resize(1);
                  value.assign(1, rank);
                  break;
                default:
                  FAIL();
                  return;
              }

              cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(),
                 cb_data);
            }));
  }

  void set_sample_database(uint16_t conn_id, bool csis, bool csis_broken,
                           uint8_t rank, uint8_t sirk_msb = 1) {
    gatt::DatabaseBuilder builder;
@@ -456,19 +544,28 @@ class CsisClientTest : public ::testing::Test {
  }

  void TestAddFromStorage(const RawAddress& address, uint16_t conn_id,
                          std::vector<uint8_t>& storage_group_buf,
                          std::vector<uint8_t>& storage_buf) {
    EXPECT_CALL(*callbacks,
                OnConnectionState(address, ConnectionState::CONNECTED))
        .Times(1);
    EXPECT_CALL(*callbacks, OnDeviceAvailable(address, _, _, _, _)).Times(1);
    EXPECT_CALL(*callbacks, OnDeviceAvailable(address, _, _, _, _))
        .Times(AtLeast(1));

    /* In testing only whe set info is empty, there is no CAP context. */
    bool is_opportunistic = (storage_buf.size() != 0);

    EXPECT_CALL(gatt_interface,
                Open(gatt_if, address, BTM_BLE_BKG_CONNECT_ALLOW_LIST, _))
                Open(gatt_if, address, BTM_BLE_BKG_CONNECT_ALLOW_LIST,
                     is_opportunistic))
        .WillOnce(Invoke([this, conn_id](tGATT_IF client_if,
                                         const RawAddress& remote_bda,
                                         bool is_direct, bool opportunistic) {
          InjectConnectedEvent(remote_bda, conn_id);
          GetSearchCompleteEvent(conn_id);
        }));

    DeviceGroups::AddFromStorage(address, storage_group_buf);
    CsisClient::AddFromStorage(address, storage_buf, true);
  }

@@ -583,6 +680,10 @@ class CsisClientTest : public ::testing::Test {
    gatt_callback(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC*)&event_data);
  }

  void SetSampleCapIncludedDatabaseCsis(uint16_t conn_id, uint8_t rank,
                                        uint8_t sirk_msb = 1) {
    set_sample_cap_included_database(conn_id, true, false, rank, sirk_msb);
  }
  void SetSampleDatabaseCsis(uint16_t conn_id, uint8_t rank,
                             uint8_t sirk_msb = 1) {
    set_sample_database(conn_id, true, false, rank, sirk_msb);
@@ -1207,30 +1308,33 @@ TEST_F(CsisClientTest, test_storage_calls) {

TEST_F(CsisClientTest, test_storage_content) {
  // Two devices in one set
  SetSampleDatabaseCsis(1, 1);
  SetSampleDatabaseCsis(2, 2);
  SetSampleCapIncludedDatabaseCsis(1, 1);
  SetSampleCapIncludedDatabaseCsis(2, 2);
  // Devices in the other set
  SetSampleDatabaseCsis(3, 1, 2);
  SetSampleDatabaseCsis(4, 1, 2);
  SetSampleCapIncludedDatabaseCsis(3, 1, 2);
  SetSampleCapIncludedDatabaseCsis(4, 1, 3);

  TestAppRegister();
  TestConnect(GetTestAddress(1));
  InjectConnectedEvent(GetTestAddress(1), 1);
  GetSearchCompleteEvent(1);
  ASSERT_EQ(1, CsisClient::Get()->GetGroupId(
                   GetTestAddress(1), bluetooth::Uuid::From16Bit(0x0000)));
                   GetTestAddress(1),
                   bluetooth::Uuid::From16Bit(UUID_COMMON_AUDIO_SERVICE)));

  TestConnect(GetTestAddress(2));
  InjectConnectedEvent(GetTestAddress(2), 2);
  GetSearchCompleteEvent(2);
  ASSERT_EQ(1, CsisClient::Get()->GetGroupId(
                   GetTestAddress(2), bluetooth::Uuid::From16Bit(0x0000)));
                   GetTestAddress(2),
                   bluetooth::Uuid::From16Bit(UUID_COMMON_AUDIO_SERVICE)));

  TestConnect(GetTestAddress(3));
  InjectConnectedEvent(GetTestAddress(3), 3);
  GetSearchCompleteEvent(3);
  ASSERT_EQ(2, CsisClient::Get()->GetGroupId(
                   GetTestAddress(3), bluetooth::Uuid::From16Bit(0x0000)));
                   GetTestAddress(3),
                   bluetooth::Uuid::From16Bit(UUID_COMMON_AUDIO_SERVICE)));

  std::vector<uint8_t> dev1_storage;
  std::vector<uint8_t> dev2_storage;
@@ -1240,10 +1344,23 @@ TEST_F(CsisClientTest, test_storage_content) {
  CsisClient::GetForStorage(GetTestAddress(1), dev1_storage);
  CsisClient::GetForStorage(GetTestAddress(2), dev2_storage);
  CsisClient::GetForStorage(GetTestAddress(3), dev3_storage);

  ASSERT_NE(0u, dev1_storage.size());
  ASSERT_NE(0u, dev2_storage.size());
  ASSERT_NE(0u, dev3_storage.size());

  std::vector<uint8_t> dev1_group_storage;
  std::vector<uint8_t> dev2_group_storage;
  std::vector<uint8_t> dev3_group_storage;

  DeviceGroups::GetForStorage(GetTestAddress(1), dev1_group_storage);
  DeviceGroups::GetForStorage(GetTestAddress(2), dev2_group_storage);
  DeviceGroups::GetForStorage(GetTestAddress(3), dev3_group_storage);

  ASSERT_NE(0u, dev1_group_storage.size());
  ASSERT_NE(0u, dev2_group_storage.size());
  ASSERT_NE(0u, dev3_group_storage.size());

  // Clean it up
  TestAppUnregister();

@@ -1251,25 +1368,29 @@ TEST_F(CsisClientTest, test_storage_content) {
  TestAppRegister();

  // Restore dev1 from the byte buffer
  TestAddFromStorage(GetTestAddress(1), 1, dev1_storage);
  TestAddFromStorage(GetTestAddress(1), 1, dev1_group_storage, dev1_storage);
  ASSERT_EQ(1, CsisClient::Get()->GetGroupId(
                   GetTestAddress(1), bluetooth::Uuid::From16Bit(0x0000)));
                   GetTestAddress(1),
                   bluetooth::Uuid::From16Bit(UUID_COMMON_AUDIO_SERVICE)));

  // Restore dev2 from the byte buffer
  TestAddFromStorage(GetTestAddress(2), 2, dev2_storage);
  TestAddFromStorage(GetTestAddress(2), 2, dev2_group_storage, dev2_storage);
  ASSERT_EQ(1, CsisClient::Get()->GetGroupId(
                   GetTestAddress(2), bluetooth::Uuid::From16Bit(0x0000)));
                   GetTestAddress(2),
                   bluetooth::Uuid::From16Bit(UUID_COMMON_AUDIO_SERVICE)));

  // Restore dev3 from the byte buffer
  TestAddFromStorage(GetTestAddress(3), 3, dev3_storage);
  TestAddFromStorage(GetTestAddress(3), 3, dev3_group_storage, dev3_storage);
  ASSERT_EQ(2, CsisClient::Get()->GetGroupId(
                   GetTestAddress(3), bluetooth::Uuid::From16Bit(0x0000)));
                   GetTestAddress(3),
                   bluetooth::Uuid::From16Bit(UUID_COMMON_AUDIO_SERVICE)));

  // Restore not inerrogated dev4 - empty buffer but valid sirk for group 2
  std::vector<uint8_t> no_set_info;
  TestAddFromStorage(GetTestAddress(4), 4, no_set_info);
  ASSERT_EQ(2, CsisClient::Get()->GetGroupId(
                   GetTestAddress(4), bluetooth::Uuid::From16Bit(0x0000)));
  TestAddFromStorage(GetTestAddress(4), 4, no_set_info, no_set_info);
  ASSERT_EQ(3, CsisClient::Get()->GetGroupId(
                   GetTestAddress(4),
                   bluetooth::Uuid::From16Bit(UUID_COMMON_AUDIO_SERVICE)));

  TestAppUnregister();
}