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

Commit 4d184874 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes from topics "bt-avdtp-get-basic-capabilities", "bt-a2dp-acceptor-codec-config"

* changes:
  Include only the Basic Capability for AVDTP GetCapabilities response
  Handle properly AVDTP SetConfig from the A2DP Sink device
parents f719457e 94c2ceb9
Loading
Loading
Loading
Loading
+22 −11
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",
@@ -1669,9 +1675,9 @@ void bta_av_getcap_results(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
  memcpy(cfg.codec_info, p_scb->peer_cap.codec_info, AVDT_CODEC_SIZE);
  memcpy(cfg.protect_info, p_scb->peer_cap.protect_info, AVDT_PROTECT_SIZE);

  APPL_TRACE_DEBUG("%s: peer %s handle:%d num_codec:%d", __func__,
  APPL_TRACE_DEBUG("%s: peer %s handle:%d num_codec:%d psc_mask=0x%x", __func__,
                   p_scb->peer_addr.ToString().c_str(), p_scb->hndl,
                   p_scb->peer_cap.num_codec);
                   p_scb->peer_cap.num_codec, p_scb->cfg.psc_mask);
  APPL_TRACE_DEBUG("%s: media type 0x%x, 0x%x", __func__, media_type,
                   p_scb->media_type);
  APPL_TRACE_DEBUG("%s: codec: %s", __func__,
@@ -1704,6 +1710,11 @@ void bta_av_getcap_results(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
    /* use only the services peer supports */
    cfg.psc_mask &= p_scb->peer_cap.psc_mask;
    p_scb->cur_psc_mask = cfg.psc_mask;
    APPL_TRACE_DEBUG(
        "%s: peer %s handle:%d sep_idx:%d sep_info_idx:%d "
        "cur_psc_mask:0x%x",
        __func__, p_scb->peer_addr.ToString().c_str(), p_scb->hndl,
        p_scb->sep_idx, p_scb->sep_info_idx, p_scb->cur_psc_mask);

    if ((uuid_int == UUID_SERVCLASS_AUDIO_SINK) &&
        (p_scb->seps[p_scb->sep_idx].p_app_sink_data_cback != NULL)) {
+245 −166

File changed.

Preview size limit exceeded, changes collapsed.

+12 −4
Original line number Diff line number Diff line
@@ -1753,6 +1753,10 @@ bool BtifAvStateMachine::StateOpened::ProcessEvent(uint32_t event,
      break;  // Ignore

    case BTIF_AV_START_STREAM_REQ_EVT:
      LOG_INFO(LOG_TAG, "%s: Peer %s : event=%s flags=%s", __PRETTY_FUNCTION__,
               peer_.PeerAddress().ToString().c_str(),
               BtifAvEvent::EventName(event).c_str(),
               peer_.FlagsToString().c_str());
      BTA_AvStart(peer_.BtaHandle());
      peer_.SetFlags(BtifAvPeer::kFlagPendingStart);
      break;
@@ -1918,7 +1922,11 @@ bool BtifAvStateMachine::StateStarted::ProcessEvent(uint32_t event,
      break;  // Ignore

    case BTIF_AV_START_STREAM_REQ_EVT:
      // We were remotely started, just ACK back the local request
      LOG_INFO(LOG_TAG, "%s: Peer %s : event=%s flags=%s", __PRETTY_FUNCTION__,
               peer_.PeerAddress().ToString().c_str(),
               BtifAvEvent::EventName(event).c_str(),
               peer_.FlagsToString().c_str());
      // We were started remotely, just ACK back the local request
      if (peer_.IsSink())
        btif_a2dp_on_started(peer_.PeerAddress(), nullptr, true);
      break;
@@ -2749,7 +2757,7 @@ bool btif_av_stream_ready(void) {
  }

  int state = peer->StateMachine().StateId();
  BTIF_TRACE_DEBUG("%s: Peer %s : state=%d, flags=%s", __func__,
  LOG_INFO(LOG_TAG, "%s: Peer %s : state=%d, flags=%s", __func__,
           peer->PeerAddress().ToString().c_str(), state,
           peer->FlagsToString().c_str());
  // check if we are remotely suspended or stop is pending
+71 −1
Original line number Diff line number Diff line
@@ -1295,7 +1295,7 @@ bool A2dpCodecConfigAacBase::setCodecConfig(const uint8_t* p_peer_codec_info,
  if (codec_user_config_.codec_specific_4 != 0)
    codec_config_.codec_specific_4 = codec_user_config_.codec_specific_4;

  // Create a local copy of the peer codec capability, and the
  // Create a local copy of the peer codec capability/config, and the
  // result codec config.
  if (is_capability) {
    status = A2DP_BuildInfoAac(AVDT_MEDIA_TYPE_AUDIO, &peer_info_cie,
@@ -1324,6 +1324,76 @@ fail:
         sizeof(ota_codec_peer_config_));
  return false;
}
bool A2dpCodecConfigAacBase::setPeerCodecCapabilities(
    const uint8_t* p_peer_codec_capabilities) {
  std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
  tA2DP_AAC_CIE peer_info_cie;
  uint8_t channelMode;
  uint16_t sampleRate;
  const tA2DP_AAC_CIE* p_a2dp_aac_caps =
      (is_source_) ? &a2dp_aac_source_caps : &a2dp_aac_sink_caps;

  // Save the internal state
  btav_a2dp_codec_config_t saved_codec_selectable_capability =
      codec_selectable_capability_;
  uint8_t saved_ota_codec_peer_capability[AVDT_CODEC_SIZE];
  memcpy(saved_ota_codec_peer_capability, ota_codec_peer_capability_,
         sizeof(ota_codec_peer_capability_));

  tA2DP_STATUS status =
      A2DP_ParseInfoAac(&peer_info_cie, p_peer_codec_capabilities, true);
  if (status != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: can't parse peer's capabilities: error = %d",
              __func__, status);
    goto fail;
  }

  // Compute the selectable capability - sample rate
  sampleRate = p_a2dp_aac_caps->sampleRate & peer_info_cie.sampleRate;
  if (sampleRate & A2DP_AAC_SAMPLING_FREQ_44100) {
    codec_selectable_capability_.sample_rate |=
        BTAV_A2DP_CODEC_SAMPLE_RATE_44100;
  }
  if (sampleRate & A2DP_AAC_SAMPLING_FREQ_48000) {
    codec_selectable_capability_.sample_rate |=
        BTAV_A2DP_CODEC_SAMPLE_RATE_48000;
  }
  if (sampleRate & A2DP_AAC_SAMPLING_FREQ_88200) {
    codec_selectable_capability_.sample_rate |=
        BTAV_A2DP_CODEC_SAMPLE_RATE_88200;
  }
  if (sampleRate & A2DP_AAC_SAMPLING_FREQ_96000) {
    codec_selectable_capability_.sample_rate |=
        BTAV_A2DP_CODEC_SAMPLE_RATE_96000;
  }

  // Compute the selectable capability - bits per sample
  codec_selectable_capability_.bits_per_sample =
      p_a2dp_aac_caps->bits_per_sample;

  // Compute the selectable capability - channel mode
  channelMode = p_a2dp_aac_caps->channelMode & peer_info_cie.channelMode;
  if (channelMode & A2DP_AAC_CHANNEL_MODE_MONO) {
    codec_selectable_capability_.channel_mode |=
        BTAV_A2DP_CODEC_CHANNEL_MODE_MONO;
  }
  if (channelMode & A2DP_AAC_CHANNEL_MODE_STEREO) {
    codec_selectable_capability_.channel_mode |=
        BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
  }

  status = A2DP_BuildInfoAac(AVDT_MEDIA_TYPE_AUDIO, &peer_info_cie,
                             ota_codec_peer_capability_);
  CHECK(status == A2DP_SUCCESS);
  return true;

fail:
  // Restore the internal state
  codec_selectable_capability_ = saved_codec_selectable_capability;
  memcpy(ota_codec_peer_capability_, saved_ota_codec_peer_capability,
         sizeof(ota_codec_peer_capability_));
  return false;
}

A2dpCodecConfigAacSink::A2dpCodecConfigAacSink(
    btav_a2dp_codec_priority_t codec_priority)
+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,
Loading