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

Commit 620a6171 authored by Jakub Pawlowski's avatar Jakub Pawlowski
Browse files

LE Audio: speed up connection to CSIS devices

When scanning, we can discover multiple devices belonging to same set,
but would trigger pairing to just one of them. We can keep the RSI in
inquiry database, and reuse it after pairing to first device is done, to
speed up pairing with other devices in the set.

It looks like some devices might decide to leave discoverable mode, and
stop advertising RSI when first device in set is bonded, or some short
time after that, while we are still doing service discovery. Without
this patch, we would fail to conenct to other devices in such set.

Test: Pair with LE Audio device, ensure both earbuds are Bonded
Bug: 247504761
Bug: 248340112
Merged-In: I7022bb0dc3422dcdbb141b1c347d43b48d424def
Change-Id: I7022bb0dc3422dcdbb141b1c347d43b48d424def
parent 6c5a76e5
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -1210,7 +1210,31 @@ class CsisClientImpl : public CsisClient {
    }
  }

  void CheckForGroupInInqDb(const std::shared_ptr<CsisGroup>& csis_group) {
    // Check if last inquiry already found devices with RSI matching this group
    for (tBTM_INQ_INFO* inq_ent = BTM_InqDbFirst(); inq_ent != nullptr;
         inq_ent = BTM_InqDbNext(inq_ent)) {
      RawAddress rsi = inq_ent->results.ble_ad_rsi;
      if (!csis_group->IsRsiMatching(rsi)) continue;

      RawAddress address = inq_ent->results.remote_bd_addr;
      auto device = FindDeviceByAddress(address);
      if (device && csis_group->IsDeviceInTheGroup(device)) {
        // InqDb will also contain existing devices, already in group - skip
        // them
        continue;
      }

      LOG_INFO("Device %s from inquiry cache match to group id %d",
               address.ToString().c_str(), csis_group->GetGroupId());
      callbacks_->OnSetMemberAvailable(address, csis_group->GetGroupId());
      break;
    }
  }

  void CsisActiveDiscovery(std::shared_ptr<CsisGroup> csis_group) {
    CheckForGroupInInqDb(csis_group);

    if ((csis_group->GetDiscoveryState() !=
         CsisDiscoveryState::CSIS_DISCOVERY_IDLE)) {
      LOG(ERROR) << __func__
+9 −0
Original line number Diff line number Diff line
@@ -100,3 +100,12 @@ void btm_configure_data_path(uint8_t direction, uint8_t path_id,
  LOG_ASSERT(btm_interface) << "Mock btm interface not set!";
  return btm_interface->ConfigureDataPath(direction, path_id, vendor_config);
}

tBTM_INQ_INFO* BTM_InqDbFirst(void) {
  LOG_ASSERT(btm_interface) << "Mock btm interface not set!";
  return btm_interface->BTM_InqDbFirst();
}
tBTM_INQ_INFO* BTM_InqDbNext(tBTM_INQ_INFO* p_cur) {
  LOG_ASSERT(btm_interface) << "Mock btm interface not set!";
  return btm_interface->BTM_InqDbNext(p_cur);
}
 No newline at end of file
+5 −0
Original line number Diff line number Diff line
@@ -54,6 +54,8 @@ class BtmInterface {
  virtual void AclDisconnectFromHandle(uint16_t handle, tHCI_STATUS reason) = 0;
  virtual void ConfigureDataPath(uint8_t direction, uint8_t path_id,
                                 std::vector<uint8_t> vendor_config) = 0;
  virtual tBTM_INQ_INFO* BTM_InqDbFirst() = 0;
  virtual tBTM_INQ_INFO* BTM_InqDbNext(tBTM_INQ_INFO* p_cur) = 0;
  virtual ~BtmInterface() = default;
};

@@ -96,6 +98,9 @@ class MockBtmInterface : public BtmInterface {
              (uint8_t direction, uint8_t path_id,
               std::vector<uint8_t> vendor_config),
              (override));
  MOCK_METHOD((tBTM_INQ_INFO*), BTM_InqDbFirst, (), (override));
  MOCK_METHOD((tBTM_INQ_INFO*), BTM_InqDbNext, (tBTM_INQ_INFO * p_cur),
              (override));
};

/**
+8 −0
Original line number Diff line number Diff line
@@ -2412,6 +2412,14 @@ void btm_ble_update_inq_result(tINQ_DB_ENT* p_i, uint8_t addr_type,
    }
  }

  if (!data.empty()) {
    const uint8_t* p_rsi =
        AdvertiseDataParser::GetFieldByType(data, BTM_BLE_AD_TYPE_RSI, &len);
    if (p_rsi != nullptr && len == 6) {
      STREAM_TO_BDADDR(p_cur->ble_ad_rsi, p_rsi);
    }
  }

  // Non-connectable packets may omit flags entirely, in which case nothing
  // should be assumed about their values (CSSv10, 1.3.1). Thus, do not
  // interpret the device type unless this packet has the flags set or is
+1 −0
Original line number Diff line number Diff line
@@ -116,6 +116,7 @@ typedef struct {
  uint8_t ble_advertising_sid;
  int8_t ble_tx_power;
  uint16_t ble_periodic_adv_int;
  RawAddress ble_ad_rsi; /* Resolvable Set Identifier from advertising */
  uint8_t flag;
  bool include_rsi;
  RawAddress original_bda;