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

Commit aabf926d authored by Henri Chataing's avatar Henri Chataing
Browse files

RootCanal: Remove current, partial implementation of LE-ISO

Support for ISO will be added as a Rust library.
The current implementation is partial, broadcast groups
are not implemented and basic connected groups commands
lack full validation.

Test: m root-canal
Bug: 253535400
Change-Id: Ibd1348a3d3229164208a9f26e64375e4b19f2ff9
parent 78133222
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -77,7 +77,6 @@ cc_library_static {
        "model/controller/acl_connection_handler.cc",
        "model/controller/controller_properties.cc",
        "model/controller/dual_mode_controller.cc",
        "model/controller/isochronous_connection_handler.cc",
        "model/controller/le_advertiser.cc",
        "model/controller/link_layer_controller.cc",
        "model/controller/sco_connection.cc",
@@ -157,7 +156,6 @@ cc_library_host_shared {
        "model/controller/controller_properties.cc",
        "model/controller/dual_mode_controller.cc",
        "model/controller/ffi.cc",
        "model/controller/isochronous_connection_handler.cc",
        "model/controller/le_advertiser.cc",
        "model/controller/link_layer_controller.cc",
        "model/controller/sco_connection.cc",
+0 −1
Original line number Diff line number Diff line
@@ -247,7 +247,6 @@ android_add_library(
      model/controller/acl_connection_handler.cc
      model/controller/controller_properties.cc
      model/controller/dual_mode_controller.cc
      model/controller/isochronous_connection_handler.cc
      model/controller/le_advertiser.cc
      model/controller/link_layer_controller.cc
      model/controller/sco_connection.cc
+1 −209
Original line number Diff line number Diff line
@@ -46,8 +46,7 @@ bool AclConnectionHandler::HasScoHandle(uint16_t handle) const {
}

uint16_t AclConnectionHandler::GetUnusedHandle() {
  while (HasHandle(last_handle_) || HasScoHandle(last_handle_) ||
         isochronous_connection_handler_.HasHandle(last_handle_)) {
  while (HasHandle(last_handle_) || HasScoHandle(last_handle_)) {
    last_handle_ = (last_handle_ + 1) % kReservedHandle;
  }
  uint16_t unused_handle = last_handle_;
@@ -278,213 +277,6 @@ void AclConnectionHandler::SetAclRole(uint16_t handle,
  acl_connections_.at(handle).SetRole(role);
}

std::unique_ptr<bluetooth::hci::LeSetCigParametersCompleteBuilder>
AclConnectionHandler::SetCigParameters(
    uint8_t id, uint32_t sdu_interval_m_to_s, uint32_t sdu_interval_s_to_m,
    bluetooth::hci::ClockAccuracy /* accuracy */,
    bluetooth::hci::Packing packing, bluetooth::hci::Enable framing,
    uint16_t max_transport_latency_m_to_s,
    uint16_t max_transport_latency_s_to_m,
    std::vector<bluetooth::hci::CisParametersConfig>& streams) {
  std::vector<uint16_t> handles;
  GroupParameters group_parameters{
      .id = id,
      .sdu_interval_m_to_s = sdu_interval_m_to_s,
      .sdu_interval_s_to_m = sdu_interval_s_to_m,
      .interleaved = packing == bluetooth::hci::Packing::INTERLEAVED,
      .framed = framing == bluetooth::hci::Enable::ENABLED,
      .max_transport_latency_m_to_s = max_transport_latency_m_to_s,
      .max_transport_latency_s_to_m = max_transport_latency_s_to_m};
  std::vector<StreamParameters> stream_parameters;
  for (size_t i = 0; i < streams.size(); i++) {
    auto handle = GetUnusedHandle();
    StreamParameters a{.group_id = group_parameters.id,
                       .stream_id = streams[i].cis_id_,
                       .max_sdu_m_to_s = streams[i].max_sdu_m_to_s_,
                       .max_sdu_s_to_m = streams[i].max_sdu_s_to_m_,
                       .rtn_m_to_s = streams[i].rtn_m_to_s_,
                       .rtn_s_to_m = streams[i].rtn_s_to_m_,
                       .handle = handle};
    handles.push_back(handle);
    stream_parameters.push_back(std::move(a));
  }

  return isochronous_connection_handler_.SetCigParameters(
      group_parameters, stream_parameters, std::move(handles));
}

void AclConnectionHandler::CreatePendingCis(
    bluetooth::hci::CreateCisConfig config) {
  CisHandles handles;
  handles.cis_handle_ = config.cis_connection_handle_;
  handles.acl_handle_ = config.acl_connection_handle_;
  handles.remote_cis_handle_ = kReservedHandle;
  pending_streams_.emplace_back(std::move(handles));
}

bool AclConnectionHandler::ConnectCis(uint16_t handle) {
  size_t position;
  CisHandles connection;
  for (position = 0; position < pending_streams_.size(); position++) {
    if (handle == pending_streams_[position].cis_handle_) {
      LOG_INFO("Found handle 0x%04hx", handle);
      connection = pending_streams_[position];
      pending_streams_.erase(pending_streams_.begin() + position);
      connected_streams_.push_back(connection);
      ASSERT(connection.cis_handle_ != kReservedHandle);
      ASSERT(connection.acl_handle_ != kReservedHandle);
      ASSERT(connection.remote_cis_handle_ != kReservedHandle);
      return true;
    }
  }

  LOG_INFO("No pending CIS connection with handle 0x%04hx", handle);
  return false;
}

void AclConnectionHandler::SetRemoteCisHandle(uint16_t handle,
                                              uint16_t remote_handle) {
  for (size_t position = 0; position < pending_streams_.size(); position++) {
    if (handle == pending_streams_[position].cis_handle_) {
      LOG_INFO("Added remote handle 0x%04hx to handle 0x%04hx", remote_handle,
               pending_streams_[position].cis_handle_);
      pending_streams_[position].remote_cis_handle_ = remote_handle;
      return;
    }
  }
  LOG_INFO("Couldn't find CIS connection with handle 0x%04hx", handle);
}

bool AclConnectionHandler::RejectCis(uint16_t handle) {
  size_t position;
  for (position = 0; position < pending_streams_.size(); position++) {
    if (handle == pending_streams_[position].cis_handle_) {
      pending_streams_.erase(pending_streams_.begin() + position);
      break;
    }
  }
  if (position == pending_streams_.size()) {
    LOG_INFO("No pending connection with handle 0x%hx", handle);
    return false;
  }
  return true;
}

uint16_t AclConnectionHandler::GetPendingAclHandle(uint16_t cis_handle) const {
  size_t position;
  uint16_t handle = 0xffff;
  for (position = 0; position < pending_streams_.size(); position++) {
    if (cis_handle == pending_streams_[position].cis_handle_) {
      handle = pending_streams_[position].acl_handle_;
      break;
    }
  }
  if (position == pending_streams_.size()) {
    LOG_INFO("No pending connection with handle 0x%hx", cis_handle);
  }
  return handle;
}

bool AclConnectionHandler::DisconnectCis(uint16_t cis_handle) {
  size_t position;
  for (position = 0; position < connected_streams_.size(); position++) {
    if (cis_handle == connected_streams_[position].cis_handle_) {
      connected_streams_.erase(connected_streams_.begin() + position);
      break;
    }
  }
  if (position == connected_streams_.size()) {
    LOG_INFO("No connected stream 0x%hx", cis_handle);
    return false;
  }
  return true;
}

bluetooth::hci::ErrorCode AclConnectionHandler::RemoveCig(uint8_t cig_id) {
  for (const auto& stream : connected_streams_) {
    if (isochronous_connection_handler_.GetGroupId(stream.cis_handle_) ==
        cig_id) {
      return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
    }
  }
  for (const auto& stream : pending_streams_) {
    if (isochronous_connection_handler_.GetGroupId(stream.cis_handle_) ==
        cig_id) {
      return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
    }
  }
  auto status = isochronous_connection_handler_.RemoveCig(cig_id);
  if (status == bluetooth::hci::ErrorCode::SUCCESS) {
    // Clean up?
  }
  return status;
}

bool AclConnectionHandler::HasPendingCisConnection(uint16_t handle) const {
  for (const auto& config : pending_streams_) {
    if (config.cis_handle_ == handle) {
      return true;
    }
  }
  return false;
}

bool AclConnectionHandler::HasPendingCis() const {
  return !pending_streams_.empty();
}

bool AclConnectionHandler::HasConnectedCis(uint16_t handle) const {
  for (const auto& cs : connected_streams_) {
    if (handle == cs.cis_handle_) {
      return true;
    }
  }
  return false;
}

bool AclConnectionHandler::HasCisHandle(uint16_t handle) const {
  for (const auto& cs : pending_streams_) {
    if (handle == cs.cis_handle_) {
      return true;
    }
  }
  for (const auto& cs : connected_streams_) {
    if (handle == cs.cis_handle_) {
      return true;
    }
  }
  return isochronous_connection_handler_.HasHandle(handle);
}

uint16_t AclConnectionHandler::GetAclHandleForCisHandle(
    uint16_t cis_handle) const {
  for (const auto& cs : connected_streams_) {
    if (cis_handle == cs.cis_handle_) {
      return cs.acl_handle_;
    }
  }
  return kReservedHandle;
}

uint16_t AclConnectionHandler::GetRemoteCisHandleForCisHandle(
    uint16_t cis_handle) const {
  for (const auto& cs : connected_streams_) {
    if (cis_handle == cs.cis_handle_) {
      return cs.remote_cis_handle_;
    }
  }
  return kReservedHandle;
}

GroupParameters AclConnectionHandler::GetGroupParameters(uint8_t id) const {
  return isochronous_connection_handler_.GetGroupParameters(id);
}

StreamParameters AclConnectionHandler::GetStreamParameters(
    uint16_t handle) const {
  return isochronous_connection_handler_.GetStreamParameters(handle);
}

void AclConnectionHandler::CreateScoConnection(
    bluetooth::hci::Address addr, ScoConnectionParameters const& parameters,
    ScoState state, ScoDatapath datapath, bool legacy) {
+0 −47
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@
#include "acl_connection.h"
#include "hci/address.h"
#include "hci/address_with_type.h"
#include "isochronous_connection_handler.h"
#include "phy.h"
#include "sco_connection.h"

@@ -109,44 +108,6 @@ class AclConnectionHandler {
  bluetooth::hci::Role GetAclRole(uint16_t handle) const;
  void SetAclRole(uint16_t handle, bluetooth::hci::Role role);

  std::unique_ptr<bluetooth::hci::LeSetCigParametersCompleteBuilder>
  SetCigParameters(uint8_t id, uint32_t sdu_interval_m_to_s,
                   uint32_t sdu_interval_s_to_m,
                   bluetooth::hci::ClockAccuracy accuracy,
                   bluetooth::hci::Packing packing,
                   bluetooth::hci::Enable framing,
                   uint16_t max_transport_latency_m_to_s,
                   uint16_t max_transport_latency_s_to_m,
                   std::vector<bluetooth::hci::CisParametersConfig>& streams);

  void CreatePendingCis(bluetooth::hci::CreateCisConfig config);

  bool ConnectCis(uint16_t handle);

  void SetRemoteCisHandle(uint16_t handle, uint16_t remote_handle);

  uint16_t GetPendingAclHandle(uint16_t cis_handle) const;

  bool RejectCis(uint16_t handle);

  bool DisconnectCis(uint16_t handle);

  bluetooth::hci::ErrorCode RemoveCig(uint8_t cig_id);

  bool HasPendingCis() const;

  bool HasPendingCisConnection(uint16_t handle) const;

  bool HasCisHandle(uint16_t handle) const;

  bool HasConnectedCis(uint16_t handle) const;

  uint16_t GetAclHandleForCisHandle(uint16_t cis_handle) const;
  uint16_t GetRemoteCisHandleForCisHandle(uint16_t cis_handle) const;

  StreamParameters GetStreamParameters(uint16_t handle) const;
  GroupParameters GetGroupParameters(uint8_t id) const;

  std::vector<uint16_t> GetAclHandles() const;

  void ResetLinkTimer(uint16_t handle);
@@ -180,14 +141,6 @@ class AclConnectionHandler {

  uint16_t GetUnusedHandle();
  uint16_t last_handle_{kReservedHandle - 2};
  IsochronousConnectionHandler isochronous_connection_handler_;
  struct CisHandles {
    uint16_t acl_handle_ = kReservedHandle;
    uint16_t cis_handle_ = kReservedHandle;
    uint16_t remote_cis_handle_ = kReservedHandle;
  };
  std::vector<CisHandles> connected_streams_;
  std::vector<CisHandles> pending_streams_;
};

}  // namespace rootcanal
+0 −74
Original line number Diff line number Diff line
/*
 * Copyright 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <algorithm>
#include <cstdint>

#include "hci/hci_packets.h"
#include "model/controller/connected_isochronous_stream.h"

namespace rootcanal {

class GroupParameters {
 public:
  uint8_t id;
  uint32_t sdu_interval_m_to_s;
  uint32_t sdu_interval_s_to_m;
  bool interleaved;
  bool framed;
  uint16_t max_transport_latency_m_to_s;
  uint16_t max_transport_latency_s_to_m;
};

class ConnectedIsochronousGroup {
 public:
  ConnectedIsochronousGroup(GroupParameters parameters,
                            std::vector<ConnectedIsochronousStream> streams)
      : parameters_(parameters), streams_(std::move(streams)) {}

  virtual ~ConnectedIsochronousGroup() = default;

  bool HasConnectedStream() const {
    return std::any_of(
        streams_.begin(), streams_.end(),
        [&](const ConnectedIsochronousStream& s) { return s.IsConnected(); });
  }

  bool StreamIsConnected(uint16_t handle) const {
    return streams_.at(handle).IsConnected();
  }

  bool HasStreams() const { return !streams_.empty(); }

  GroupParameters GetParameters() const { return parameters_; }

  StreamParameters GetStreamParameters(uint16_t handle) const {
    for (const auto& stream : streams_) {
      if (stream.GetHandle() == handle) {
        return stream.GetConfig();
      }
    }
    return StreamParameters{};
  }

 private:
  GroupParameters parameters_;
  std::vector<ConnectedIsochronousStream> streams_;
};

}  // namespace rootcanal
Loading