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

Commit 69e97235 authored by Jakub Pawlowski's avatar Jakub Pawlowski
Browse files

Add LE Read ISO link quality

Tag: #feature
Test: manually verified HCI snoop log content
Bug: 150670922
Change-Id: I0d0f91b1f7e9e61079e429c1c8fb57028b4b52a3
parent 0fee6691
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -89,6 +89,10 @@ void IsoManager::RemoveIsoDataPath(uint16_t iso_handle, uint8_t data_path_dir) {
  pimpl_->iso_impl_->remove_iso_data_path(iso_handle, data_path_dir);
}

void IsoManager::ReadIsoLinkQuality(uint16_t iso_handle) {
  pimpl_->iso_impl_->read_iso_link_quality(iso_handle);
}

void IsoManager::SendIsoData(uint16_t iso_handle, const uint8_t* data,
                             uint16_t data_len) {
  pimpl_->iso_impl_->send_iso_data(iso_handle, data, data_len);
+47 −0
Original line number Diff line number Diff line
@@ -299,6 +299,53 @@ struct iso_impl {
                       base::Unretained(this)));
  }

  void on_iso_link_quality_read(uint8_t* stream, uint16_t len) {
    uint8_t status;
    uint16_t conn_handle;
    uint32_t txUnackedPackets;
    uint32_t txFlushedPackets;
    uint32_t txLastSubeventPackets;
    uint32_t retransmittedPackets;
    uint32_t crcErrorPackets;
    uint32_t rxUnreceivedPackets;
    uint32_t duplicatePackets;

    STREAM_TO_UINT8(status, stream);
    if (status != HCI_SUCCESS) {
      LOG(ERROR) << "Failed to Read ISO Link Quality, status: "
                 << loghex(status);
      return;
    }

    STREAM_TO_UINT16(conn_handle, stream);

    iso_base* iso = GetIsoIfKnown(conn_handle);
    LOG_ASSERT(iso != nullptr) << "Invalid connection handle: " << +conn_handle;

    STREAM_TO_UINT32(txUnackedPackets, stream);
    STREAM_TO_UINT32(txFlushedPackets, stream);
    STREAM_TO_UINT32(txLastSubeventPackets, stream);
    STREAM_TO_UINT32(retransmittedPackets, stream);
    STREAM_TO_UINT32(crcErrorPackets, stream);
    STREAM_TO_UINT32(rxUnreceivedPackets, stream);
    STREAM_TO_UINT32(duplicatePackets, stream);

    LOG_ASSERT(cig_callbacks_ != nullptr) << "Invalid CIG callbacks";
    cig_callbacks_->OnIsoLinkQualityRead(
        conn_handle, iso->cig_id, txUnackedPackets, txFlushedPackets,
        txLastSubeventPackets, retransmittedPackets, crcErrorPackets,
        rxUnreceivedPackets, duplicatePackets);
  }

  void read_iso_link_quality(uint16_t iso_handle) {
    iso_base* iso = GetIsoIfKnown(iso_handle);
    LOG_ASSERT(iso != nullptr) << "No such iso connection";

    btsnd_hcic_read_iso_link_quality(
        iso_handle, base::BindOnce(&iso_impl::on_iso_link_quality_read,
                                   base::Unretained(this)));
  }

  BT_HDR* prepare_ts_hci_packet(uint16_t iso_handle, uint32_t ts,
                                uint16_t seq_nb, uint16_t data_len) {
    /* Add 2 for packet seq., 2 for length, 4 for the timestamp */
+11 −0
Original line number Diff line number Diff line
@@ -1072,6 +1072,17 @@ void btsnd_hcic_remove_iso_data_path(
                            params_len, std::move(cb));
}

void btsnd_hcic_read_iso_link_quality(
    uint16_t iso_handle, base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
  const int params_len = 2;
  uint8_t param[params_len];
  uint8_t* pp = param;

  UINT16_TO_STREAM(pp, iso_handle);

  btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_LE_READ_ISO_LINK_QUALITY, param,
                            params_len, std::move(cb));
}

void btsnd_hcic_ble_periodic_advertising_create_sync(
    uint8_t options, uint8_t adv_sid, uint8_t adv_addr_type,
+14 −1
Original line number Diff line number Diff line
@@ -32,6 +32,11 @@ struct CigCallbacks {
                                  uint8_t cig_id) = 0;
  virtual void OnRemoveIsoDataPath(uint8_t status, uint16_t conn_handle,
                                   uint8_t cig_id) = 0;
  virtual void OnIsoLinkQualityRead(
      uint8_t conn_handle, uint8_t cig_id, uint32_t txUnackedPackets,
      uint32_t txFlushedPackets, uint32_t txLastSubeventPackets,
      uint32_t retransmittedPackets, uint32_t crcErrorPackets,
      uint32_t rxUnreceivedPackets, uint32_t duplicatePackets) = 0;

  virtual void OnCisEvent(uint8_t event, void* data) = 0;
  virtual void OnCigEvent(uint8_t event, void* data) = 0;
@@ -129,7 +134,7 @@ class IsoManager {
      struct iso_manager::iso_data_path_params path_params);

  /**
   * Initiates removement of isochronous data path for connected isochronous
   * Initiates removal of isochronous data path for connected isochronous
   * stream.
   *
   * @param conn_handle handle of BIS or CIS connection
@@ -137,6 +142,14 @@ class IsoManager {
   */
  virtual void RemoveIsoDataPath(uint16_t conn_handle, uint8_t data_path_dir);

  /**
   * Reads the ISO link quality. OnIsoLinkQualityRead callback is invoked only
   * if read is successful.
   *
   * @param conn_handle handle of ISO connection
   */
  virtual void ReadIsoLinkQuality(uint16_t conn_handle);

  /**
   * Sends iso data to the controller
   *
+1 −0
Original line number Diff line number Diff line
@@ -427,6 +427,7 @@
#define HCI_LE_ISO_READ_TEST_CNTRS (0x0072 | HCI_GRP_BLE_CMDS)
#define HCI_LE_ISO_TEST_END (0x0073 | HCI_GRP_BLE_CMDS)
#define HCI_LE_SET_HOST_FEATURE (0x0074 | HCI_GRP_BLE_CMDS)
#define HCI_LE_READ_ISO_LINK_QUALITY (0x0075 | HCI_GRP_BLE_CMDS)

/* Multi adv opcode */
#define HCI_BLE_MULTI_ADV (0x0154 | HCI_GRP_VENDOR_SPECIFIC)
Loading