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

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

Merge "leaudio: Make sure to use 2M PHY if possible." into main

parents af5f6707 320a306b
Loading
Loading
Loading
Loading
+34 −1
Original line number Diff line number Diff line
@@ -2183,6 +2183,17 @@ class LeAudioClientImpl : public LeAudioClient {
      return;
    }

    /* If PHY update did not succeed after ACL connection, which can happen
     * when remote feature read was not that quick, lets try to change phy here
     * one more time
     */
    if (!leAudioDevice->acl_phy_update_done_ &&
        bluetooth::shim::GetController()->SupportsBle2mPhy()) {
      log::info("{} set preferred PHY to 2M",
                ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_));
      BTM_BleSetPhy(address, PHY_LE_2M, PHY_LE_2M, 0);
    }

    changeMtuIfPossible(leAudioDevice);

    leAudioDevice->encrypted_ = true;
@@ -2368,6 +2379,7 @@ class LeAudioClientImpl : public LeAudioClient {
    leAudioDevice->mtu_ = 0;
    leAudioDevice->closing_stream_for_disconnection_ = false;
    leAudioDevice->encrypted_ = false;
    leAudioDevice->acl_phy_update_done_ = false;

    groupStateMachine_->ProcessHciNotifAclDisconnected(group, leAudioDevice);

@@ -2569,6 +2581,23 @@ class LeAudioClientImpl : public LeAudioClient {
    leAudioDevice->mtu_ = mtu;
  }

  void OnPhyUpdate(uint16_t conn_id, uint8_t tx_phy, uint8_t rx_phy,
                   tGATT_STATUS status) {
    LeAudioDevice* leAudioDevice = leAudioDevices_.FindByConnId(conn_id);
    if (leAudioDevice == nullptr) {
      log::debug("Unknown conn_id {:#x}", conn_id);
      return;
    }

    log::info("{}, tx_phy: {:#x}, rx_phy: {:#x} , status: {:#x}",
              ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_), tx_phy, rx_phy,
              status);

    if (status == 0) {
      leAudioDevice->acl_phy_update_done_ = true;
    }
  }

  void OnGattServiceDiscoveryDone(const RawAddress& address) {
    LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
    if (!leAudioDevice || (leAudioDevice->conn_id_ == GATT_INVALID_CONN_ID)) {
@@ -5997,7 +6026,11 @@ void le_audio_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
    case BTA_GATTC_CFG_MTU_EVT:
      instance->OnMtuChanged(p_data->cfg_mtu.conn_id, p_data->cfg_mtu.mtu);
      break;

    case BTA_GATTC_PHY_UPDATE_EVT:
      instance->OnPhyUpdate(
          p_data->phy_update.conn_id, p_data->phy_update.tx_phy,
          p_data->phy_update.rx_phy, p_data->phy_update.status);
      break;
    default:
      break;
  }
+2 −0
Original line number Diff line number Diff line
@@ -120,6 +120,7 @@ class LeAudioDevice {
  std::string model_name_;
  bool allowlist_flag_;
  bool acl_asymmetric_;
  bool acl_phy_update_done_;

  alarm_t* link_quality_timer;
  uint16_t link_quality_timer_data;
@@ -142,6 +143,7 @@ class LeAudioDevice {
        model_name_(""),
        allowlist_flag_(false),
        acl_asymmetric_(false),
        acl_phy_update_done_(false),
        link_quality_timer(nullptr),
        dsa_({{DsaMode::DISABLED},
              types::DataPathState::IDLE,
+78 −0
Original line number Diff line number Diff line
@@ -573,6 +573,26 @@ class UnicastTestNoInit : public Test {
            base::Unretained(this->gatt_callback), event_data));
  }

  void InjectPhyChangedEvent(uint16_t conn_id, uint8_t tx_phy, uint8_t rx_phy,
                             tGATT_STATUS status) {
    ASSERT_NE(conn_id, GATT_INVALID_CONN_ID);
    tBTA_GATTC_PHY_UPDATE event_data = {
        .conn_id = conn_id,
        .tx_phy = tx_phy,
        .rx_phy = rx_phy,
        .status = status,
    };

    do_in_main_thread(FROM_HERE,
                      base::BindOnce(
                          [](tBTA_GATTC_CBACK* gatt_callback,
                             tBTA_GATTC_PHY_UPDATE event_data) {
                            gatt_callback(BTA_GATTC_PHY_UPDATE_EVT,
                                          (tBTA_GATTC*)&event_data);
                          },
                          base::Unretained(this->gatt_callback), event_data));
  }

  void InjectSearchCompleteEvent(uint16_t conn_id) {
    ASSERT_NE(conn_id, GATT_INVALID_CONN_ID);
    tBTA_GATTC_SEARCH_CMPL event_data = {
@@ -1502,6 +1522,7 @@ class UnicastTestNoInit : public Test {
        .WillByDefault(Return(true));
    ON_CALL(controller_, SupportsBleConnectedIsochronousStreamPeripheral)
        .WillByDefault(Return(true));
    ON_CALL(controller_, SupportsBle2mPhy).WillByDefault(Return(true));
    bluetooth::hci::testing::mock_controller_ = &controller_;
    bluetooth::manager::SetMockBtmInterface(&mock_btm_interface_);
    gatt::SetMockBtaGattInterface(&mock_gatt_interface_);
@@ -2908,6 +2929,63 @@ TEST_F(UnicastTestNoInit, InitializeNoHal_2_1) {
      "disable LE Audio Profile, or update your HAL");
}

TEST_F(UnicastTest, ConnectAndSetupPhy) {
  const RawAddress test_address0 = GetTestAddress(0);
  uint16_t conn_id = 1;
  SetSampleDatabaseEarbudsValid(
      1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
      codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
      default_channel_cnt, 0x0004,
      /* source sample freq 16khz */ true, /*add_csis*/
      true,                                /*add_cas*/
      true,                                /*add_pacs*/
      default_ase_cnt /*add_ascs*/);

  EXPECT_CALL(mock_btm_interface_,
              BleSetPhy(test_address0, PHY_LE_2M, PHY_LE_2M, 0))
      .Times(1);
  ConnectLeAudio(test_address0, false);
  Mock::VerifyAndClearExpectations(&mock_btm_interface_);

  EXPECT_CALL(mock_btm_interface_,
              BleSetPhy(test_address0, PHY_LE_2M, PHY_LE_2M, 0))
      .Times(1);
  InjectPhyChangedEvent(conn_id, 0, 0, GATT_REQ_NOT_SUPPORTED);
  SyncOnMainLoop();
  ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
      .WillByDefault(DoAll(Return(true)));
  InjectEncryptionChangedEvent(test_address0);
  SyncOnMainLoop();
  Mock::VerifyAndClearExpectations(&mock_btm_interface_);

  /* Make sure flag `acl_phy_update_done_` is cleared after disconnect.
   * Just repeat previous steps after reconnection
   */
  InjectDisconnectedEvent(conn_id);
  SyncOnMainLoop();

  EXPECT_CALL(mock_btm_interface_,
              BleSetPhy(test_address0, PHY_LE_2M, PHY_LE_2M, 0))
      .Times(1);

  ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
      .WillByDefault(DoAll(Return(false)));
  InjectConnectedEvent(test_address0, 1);
  SyncOnMainLoop();
  Mock::VerifyAndClearExpectations(&mock_btm_interface_);

  EXPECT_CALL(mock_btm_interface_,
              BleSetPhy(test_address0, PHY_LE_2M, PHY_LE_2M, 0))
      .Times(1);
  InjectPhyChangedEvent(conn_id, 0, 0, GATT_REQ_NOT_SUPPORTED);
  SyncOnMainLoop();
  ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
      .WillByDefault(DoAll(Return(true)));
  InjectEncryptionChangedEvent(test_address0);
  SyncOnMainLoop();
  Mock::VerifyAndClearExpectations(&mock_btm_interface_);
}

TEST_F(UnicastTest, ConnectOneEarbudEmpty) {
  const RawAddress test_address0 = GetTestAddress(0);
  SetSampleDatabaseEmpty(1, test_address0);