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

Commit edc68495 authored by Jakub Pawlowski's avatar Jakub Pawlowski Committed by Jakub Pawłowski
Browse files

LE Audio: improve LE Audio device detection for Bonding

As per BAP 1.0.1 and CAP 1.0 specs, LE Audio capable device shall/should
put Service data for some services into the Advertisement.
If these are detected, such devices should be treated as LE Audio
capable for bonding.

This is addition to existing mechanisms that was using just CoD field.

Bug: 246560805
Test: pair with dual mode capable devices
Merged-In: Icd6287fecbeadbc853e1ae4146937c85adea9104
Change-Id: Icd6287fecbeadbc853e1ae4146937c85adea9104
parent edf576ff
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -689,3 +689,14 @@ void BTA_DmBleResetId(void) {
  APPL_TRACE_API("BTA_DmBleResetId");
  do_in_main_thread(FROM_HERE, base::Bind(bta_dm_ble_reset_id));
}

bool BTA_DmCheckLeAudioCapable(const RawAddress& address) {
  for (tBTM_INQ_INFO* inq_ent = BTM_InqDbFirst(); inq_ent != nullptr;
       inq_ent = BTM_InqDbNext(inq_ent)) {
    if (inq_ent->results.remote_bd_addr != address) continue;

    LOG_INFO("Device is LE Audio capable based on AD content");
    return inq_ent->results.ble_ad_is_le_audio_capable;
  }
  return false;
}
 No newline at end of file
+10 −0
Original line number Diff line number Diff line
@@ -1224,4 +1224,14 @@ extern void BTA_DmClearEventFilter(void);
 ******************************************************************************/
extern void BTA_DmBleResetId(void);

/*******************************************************************************
 *
 * Function         BTA_DmCheckLeAudioCapable
 *
 * Description      Checks if device should be considered as LE Audio capable
 *
 * Returns          True if Le Audio capable device, false otherwise
 *
 ******************************************************************************/
extern bool BTA_DmCheckLeAudioCapable(const RawAddress& address);
#endif /* BTA_API_H */
+9 −5
Original line number Diff line number Diff line
@@ -680,12 +680,16 @@ static void btif_update_remote_properties(const RawAddress& bdaddr,
 * up LE profile connection, and limits all possible service discovery
 * ordering issues (first Classic, GATT over SDP, etc) */
static bool is_device_le_audio_capable(const RawAddress bd_addr) {
  if (!LeAudioClient::IsLeAudioClientRunning() ||
      !check_cod_le_audio(bd_addr)) {
  if (!LeAudioClient::IsLeAudioClientRunning()) {
    /* If LE Audio profile is not enabled, do nothing. */
    return false;
  }

  if (!check_cod_le_audio(bd_addr) && !BTA_DmCheckLeAudioCapable(bd_addr)) {
    /* LE Audio not present in CoD or in LE Advertisement, do nothing.*/
    return false;
  }

  tBT_DEVICE_TYPE tmp_dev_type;
  tBLE_ADDR_TYPE addr_type = BLE_ADDR_PUBLIC;
  BTM_ReadDevInfo(bd_addr, &tmp_dev_type, &addr_type);
@@ -1517,12 +1521,12 @@ static void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event,
       * before before passing services to upper layers. */
      if ((bd_addr == pairing_cb.bd_addr ||
           bd_addr == pairing_cb.static_bdaddr) &&
          a2dp_sink_capable &&
          LeAudioClient::IsLeAudioClientRunning() &&
          a2dp_sink_capable && LeAudioClient::IsLeAudioClientRunning() &&
          pairing_cb.gatt_over_le !=
              btif_dm_pairing_cb_t::ServiceDiscoveryState::FINISHED &&
          (check_cod_le_audio(bd_addr) ||
           metadata_cb.le_audio_cache.contains(bd_addr))) {
           metadata_cb.le_audio_cache.contains(bd_addr) ||
           BTA_DmCheckLeAudioCapable(bd_addr))) {
        skip_reporting_wait_for_le = true;
      }

+20 −4
Original line number Diff line number Diff line
@@ -2393,9 +2393,7 @@ void btm_ble_update_inq_result(tINQ_DB_ENT* p_i, uint8_t addr_type,
      has_advertising_flags = true;
      p_cur->flag = *p_flag;
    }
  }

  if (!data.empty()) {
    /* Check to see the BLE device has the Appearance UUID in the advertising
     * data.  If it does
     * then try to convert the appearance value to a class of device value
@@ -2425,14 +2423,32 @@ 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);
    }

    const uint8_t* p_service_data = data.data();
    uint16_t remaining_data_len = data.size();
    uint8_t service_data_len = 0;

    while ((p_service_data = AdvertiseDataParser::GetFieldByType(
                p_service_data + service_data_len,
                (remaining_data_len -= service_data_len),
                BTM_BLE_AD_TYPE_SERVICE_DATA_TYPE, &service_data_len))) {
      uint16_t uuid;
      STREAM_TO_UINT16(uuid, p_service_data);

      if (uuid == 0x184E /* Audio Stream Control service */ ||
          uuid == 0x184F /* Broadcast Audio Scan service */ ||
          uuid == 0x1850 /* Published Audio Capabilities service */ ||
          uuid == 0x1853 /* Common Audio service */) {
        p_cur->ble_ad_is_le_audio_capable = true;
        break;
      }
    }
  }

  // Non-connectable packets may omit flags entirely, in which case nothing
+1 −0
Original line number Diff line number Diff line
@@ -117,6 +117,7 @@ typedef struct {
  int8_t ble_tx_power;
  uint16_t ble_periodic_adv_int;
  RawAddress ble_ad_rsi; /* Resolvable Set Identifier from advertising */
  bool ble_ad_is_le_audio_capable;
  uint8_t flag;
  bool include_rsi;
  RawAddress original_bda;