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

Commit 1e87b0ff authored by Jakub Pawłowski's avatar Jakub Pawłowski Committed by Gerrit Code Review
Browse files

Merge "LE Audio: Use Read Multiple for initial ASE read" into main

parents 198b69f5 b500a2a8
Loading
Loading
Loading
Loading
+69 −3
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@

#include "audio_hal_client/audio_hal_client.h"
#include "audio_hal_interface/le_audio_software.h"
#include "bt_types.h"
#include "bta/csis/csis_types.h"
#include "bta_gatt_api.h"
#include "bta_gatt_queue.h"
@@ -43,6 +44,7 @@
#include "common/time_util.h"
#include "content_control_id_keeper.h"
#include "devices.h"
#include "gatt_api.h"
#include "hci/controller_interface.h"
#include "internal_include/stack_config.h"
#include "le_audio_health_status.h"
@@ -353,6 +355,8 @@ public:
    int ases_num = leAudioDevice->ases_.size();
    void* notify_flag_ptr = NULL;

    tBTA_GATTC_MULTI multi_read{};

    for (int i = 0; i < ases_num; i++) {
      /* Last read ase characteristic should issue connected state callback
       * to upper layer
@@ -362,9 +366,26 @@ public:
        notify_flag_ptr = INT_TO_PTR(leAudioDevice->notify_connected_after_read_);
      }

      if (!com::android::bluetooth::flags::le_ase_read_multiple_variable()) {
        BtaGattQueue::ReadCharacteristic(leAudioDevice->conn_id_,
                                         leAudioDevice->ases_[i].hdls.val_hdl, OnGattReadRspStatic,
                                         notify_flag_ptr);
        continue;
      }

      if (i != 0 && (i % GATT_MAX_READ_MULTI_HANDLES == 0)) {
        multi_read.num_attr = GATT_MAX_READ_MULTI_HANDLES;
        BtaGattQueue::ReadMultiCharacteristic(leAudioDevice->conn_id_, multi_read,
                                              OnGattReadMultiRspStatic, notify_flag_ptr);
        memset(multi_read.handles, 0, GATT_MAX_READ_MULTI_HANDLES * sizeof(uint16_t));
      }
      multi_read.handles[i % GATT_MAX_READ_MULTI_HANDLES] = leAudioDevice->ases_[i].hdls.val_hdl;
    }

    if (ases_num % GATT_MAX_READ_MULTI_HANDLES != 0) {
      multi_read.num_attr = ases_num % GATT_MAX_READ_MULTI_HANDLES;
      BtaGattQueue::ReadMultiCharacteristic(leAudioDevice->conn_id_, multi_read,
                                            OnGattReadMultiRspStatic, notify_flag_ptr);
    }
  }

@@ -4960,6 +4981,51 @@ public:
    }
  }

  static void OnGattReadMultiRspStatic(uint16_t conn_id, tGATT_STATUS status,
                                       tBTA_GATTC_MULTI& handles, uint16_t total_len,
                                       uint8_t* value, void* data) {
    if (!instance) {
      return;
    }

    if (status == GATT_DATABASE_OUT_OF_SYNC) {
      LeAudioDevice* leAudioDevice = instance->leAudioDevices_.FindByConnId(conn_id);
      instance->ClearDeviceInformationAndStartSearch(leAudioDevice);
      return;
    }
    if (status != GATT_SUCCESS) {
      log::error("Failed to read multiple attributes, conn_id: 0x{:04x}, status: 0x{:02x}", conn_id,
                 +status);
      return;
    }

    size_t position = 0;
    int index = 0;
    while (position != total_len) {
      uint8_t* ptr = value + position;
      uint16_t len;
      STREAM_TO_UINT16(len, ptr);
      uint16_t hdl = handles.handles[index];

      if (position + len >= total_len) {
        log::warn("Multi read was too long, value truncated conn_id: 0x{:04x} handle: 0x{:04x}",
                  conn_id, hdl);
        break;
      }

      OnGattReadRspStatic(conn_id, status, hdl, len, ptr,
                          ((index == (handles.num_attr - 1)) ? data : nullptr));

      position += len + 2; /* skip the length of data */
      index++;
    }

    if (handles.num_attr - 1 != index) {
      log::warn("Attempted to read {} handles, but received just {} values", +handles.num_attr,
                index + 1);
    }
  }

  void LeAudioHealthSendRecommendation(const RawAddress& address, int group_id,
                                       LeAudioHealthBasedAction action) {
    log::debug("{}, {}, {}", address, group_id, ToString(action));