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

Commit e86055ad authored by Pavlin Radoslavov's avatar Pavlin Radoslavov
Browse files

Handle properly AVDTP SetConfig from the A2DP Sink device

If the remote device is proactive and sends AVDTP SetConfig after
re-connection before the local device gets the chance to do it, the
internal codec setup state might be inconsistent.

* Fix the internal logic when the local device is Acceptor inside
  file bta_av_co.cc, and simplify some of the code.
* Fix the handling of p_scb->sep_info_idx inside bta_av_save_caps()
  when receiving capabilities from the remote device.
* Add new A2dpCodecConfig::setPeerCodecCapabilities() method that is
  implemented by each codec.

Bug: 77525584
Test: Manual - initiate connection by Momentum 2.0 Wireless Headset.
      Connect/disconnect/reconnect multiple headsets.

Change-Id: I456df7c8a2fa0758c0908a4628c4dfae3259dbdb
parent 82eb6b35
Loading
Loading
Loading
Loading
+15 −9
Original line number Diff line number Diff line
@@ -1523,24 +1523,30 @@ void bta_av_save_caps(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {

  cfg = p_scb->peer_cap;
  /* let application know the capability of the SNK */
  p_scb->p_cos->getcfg(p_scb->hndl, p_scb->peer_addr, cfg.codec_info,
  if (p_scb->p_cos->getcfg(p_scb->hndl, p_scb->peer_addr, cfg.codec_info,
                           &p_scb->sep_info_idx, p_info->seid, &cfg.num_protect,
                       cfg.protect_info);

                           cfg.protect_info) != A2DP_SUCCESS) {
    p_scb->sep_info_idx++;
  APPL_TRACE_DEBUG("%s: result: sep_info_idx:%d", __func__,
    APPL_TRACE_DEBUG("%s: result: next sep_info_idx:%d", __func__,
                     p_scb->sep_info_idx);
  } else {
    // All capabilities found
    getcap_done = true;
    APPL_TRACE_DEBUG("%s: result: done sep_info_idx:%d", __func__,
                     p_scb->sep_info_idx);
  }
  APPL_TRACE_DEBUG("%s: codec: %s", __func__,
                   A2DP_CodecInfoString(cfg.codec_info).c_str());

  if (p_scb->num_seps > p_scb->sep_info_idx) {
  if (p_scb->num_seps > p_scb->sep_info_idx && !getcap_done) {
    /* Some devices have seps at the end of the discover list, which is not */
    /* matching media type(video not audio).                                */
    /* In this case, we are done with getcap without sending another        */
    /* request to AVDT.                                                     */
    if (!bta_av_next_getcap(p_scb, p_data)) getcap_done = true;
  } else
  } else {
    getcap_done = true;
  }

  if (getcap_done) {
    APPL_TRACE_DEBUG("%s: getcap_done: num_seps:%d sep_info_idx:%d wait:0x%x",
+218 −150

File changed.

Preview size limit exceeded, changes collapsed.

+71 −1

File changed.

Preview size limit exceeded, changes collapsed.

+22 −0
Original line number Diff line number Diff line
@@ -908,6 +908,28 @@ fail:
  return false;
}

bool A2dpCodecs::setPeerSinkCodecCapabilities(
    const uint8_t* p_peer_codec_capabilities) {
  std::lock_guard<std::recursive_mutex> lock(codec_mutex_);

  if (!A2DP_IsPeerSinkCodecValid(p_peer_codec_capabilities)) return false;
  A2dpCodecConfig* a2dp_codec_config =
      findSourceCodecConfig(p_peer_codec_capabilities);
  if (a2dp_codec_config == nullptr) return false;
  return a2dp_codec_config->setPeerCodecCapabilities(p_peer_codec_capabilities);
}

bool A2dpCodecs::setPeerSourceCodecCapabilities(
    const uint8_t* p_peer_codec_capabilities) {
  std::lock_guard<std::recursive_mutex> lock(codec_mutex_);

  if (!A2DP_IsPeerSourceCodecValid(p_peer_codec_capabilities)) return false;
  A2dpCodecConfig* a2dp_codec_config =
      findSinkCodecConfig(p_peer_codec_capabilities);
  if (a2dp_codec_config == nullptr) return false;
  return a2dp_codec_config->setPeerCodecCapabilities(p_peer_codec_capabilities);
}

bool A2dpCodecs::getCodecConfigAndCapabilities(
    btav_a2dp_codec_config_t* p_codec_config,
    std::vector<btav_a2dp_codec_config_t>* p_codecs_local_capabilities,
+76 −4

File changed.

Preview size limit exceeded, changes collapsed.

Loading