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

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

Merge "Use the same fixed channel allocator for both Classic and LE connections"

parents f80ee977 8c8edf61
Loading
Loading
Loading
Loading
+1 −4
Original line number Diff line number Diff line
@@ -11,11 +11,9 @@ filegroup {
        "classic_fixed_channel_service.cc",
        "internal/classic_dynamic_channel_allocator.cc",
        "internal/classic_dynamic_channel_impl.cc",
        "internal/classic_fixed_channel_allocator.cc",
        "internal/classic_fixed_channel_impl.cc",
        "internal/classic_fixed_channel_service_manager_impl.cc",
        "internal/classic_link_manager.cc",
        "internal/le_fixed_channel_allocator.cc",
        "internal/le_fixed_channel_impl.cc",
        "internal/le_fixed_channel_service_manager_impl.cc",
        "internal/le_link_manager.cc",
@@ -32,11 +30,10 @@ filegroup {
        "l2cap_packet_test.cc",
        "internal/classic_dynamic_channel_allocator_test.cc",
        "internal/classic_dynamic_channel_impl_test.cc",
        "internal/classic_fixed_channel_allocator_test.cc",
        "internal/classic_fixed_channel_impl_test.cc",
        "internal/classic_fixed_channel_service_manager_test.cc",
        "internal/classic_link_manager_test.cc",
        "internal/le_fixed_channel_allocator_test.cc",
        "internal/fixed_channel_allocator_test.cc",
        "internal/le_fixed_channel_impl_test.cc",
        "internal/le_fixed_channel_service_manager_test.cc",
        "internal/le_link_manager_test.cc",
+0 −81
Original line number Diff line number Diff line
/*
 * Copyright 2019 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.
 */

#include <unordered_map>

#include "classic_fixed_channel_allocator.h"
#include "l2cap/cid.h"
#include "l2cap/internal/classic_fixed_channel_allocator.h"
#include "l2cap/internal/classic_link.h"
#include "l2cap/security_policy.h"
#include "os/handler.h"
#include "os/log.h"

namespace bluetooth {
namespace l2cap {
namespace internal {

std::shared_ptr<ClassicFixedChannelImpl> ClassicFixedChannelAllocator::AllocateChannel(Cid cid,
                                                                                       SecurityPolicy security_policy) {
  ASSERT_LOG(!IsChannelAllocated((cid)), "Cid 0x%x for device %s is already in use", cid,
             link_->GetDevice().ToString().c_str());
  ASSERT_LOG(cid >= kFirstFixedChannel && cid <= kLastFixedChannel, "Cid %d out of bound", cid);
  auto elem = channels_.try_emplace(cid, std::make_shared<ClassicFixedChannelImpl>(cid, link_, l2cap_handler_));
  ASSERT_LOG(elem.second, "Failed to create channel for cid 0x%x device %s", cid,
             link_->GetDevice().ToString().c_str());
  ASSERT(elem.first->second != nullptr);
  return elem.first->second;
}

void ClassicFixedChannelAllocator::FreeChannel(Cid cid) {
  ASSERT_LOG(IsChannelAllocated(cid), "Channel is not in use: cid %d, device %s", cid,
             link_->GetDevice().ToString().c_str());
  channels_.erase(cid);
}

bool ClassicFixedChannelAllocator::IsChannelAllocated(Cid cid) const {
  return channels_.find(cid) != channels_.end();
}

std::shared_ptr<ClassicFixedChannelImpl> ClassicFixedChannelAllocator::FindChannel(Cid cid) {
  ASSERT_LOG(IsChannelAllocated(cid), "Channel is not in use: cid %d, device %s", cid,
             link_->GetDevice().ToString().c_str());
  return channels_.find(cid)->second;
}

size_t ClassicFixedChannelAllocator::NumberOfChannels() const {
  return channels_.size();
}

void ClassicFixedChannelAllocator::OnAclDisconnected(hci::ErrorCode reason) {
  for (auto& elem : channels_) {
    elem.second->OnClosed(reason);
  }
}

int ClassicFixedChannelAllocator::GetRefCount() {
  int ref_count = 0;
  for (auto& elem : channels_) {
    if (elem.second->IsAcquired()) {
      ref_count++;
    }
  }
  return ref_count;
}

}  // namespace internal
}  // namespace l2cap
}  // namespace bluetooth
+0 −69
Original line number Diff line number Diff line
/*
 * Copyright 2019 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 <hci/hci_packets.h>
#include <unordered_map>

#include "l2cap/cid.h"
#include "l2cap/internal/classic_fixed_channel_impl.h"
#include "l2cap/security_policy.h"
#include "os/handler.h"
#include "os/log.h"

namespace bluetooth {
namespace l2cap {
namespace internal {

class ClassicLink;

// Helper class for keeping channels in a Link. It allocates and frees Channel object, and supports querying whether a
// channel is in use
class ClassicFixedChannelAllocator {
 public:
  ClassicFixedChannelAllocator(ClassicLink* link, os::Handler* l2cap_handler)
      : link_(link), l2cap_handler_(l2cap_handler) {
    ASSERT(link_ != nullptr);
    ASSERT(l2cap_handler_ != nullptr);
  }

  // Allocates a channel. If cid is used, return nullptr. NOTE: The returned ClassicFixedChannelImpl object is still
  // owned by the channel allocator, NOT the client.
  std::shared_ptr<ClassicFixedChannelImpl> AllocateChannel(Cid cid, SecurityPolicy security_policy);

  // Frees a channel. If cid doesn't exist, it will crash
  void FreeChannel(Cid cid);

  bool IsChannelAllocated(Cid cid) const;

  std::shared_ptr<ClassicFixedChannelImpl> FindChannel(Cid cid);

  size_t NumberOfChannels() const;

  void OnAclDisconnected(hci::ErrorCode hci_status);

  int GetRefCount();

 private:
  ClassicLink* link_;
  os::Handler* l2cap_handler_;
  std::unordered_map<Cid, std::shared_ptr<ClassicFixedChannelImpl>> channels_;
};

}  // namespace internal
}  // namespace l2cap
}  // namespace bluetooth
+2 −0
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@ namespace testing {

class MockClassicFixedChannelImpl : public ClassicFixedChannelImpl {
 public:
  MockClassicFixedChannelImpl(Cid cid, ClassicLink* link, os::Handler* l2cap_handler)
      : ClassicFixedChannelImpl(cid, link, l2cap_handler) {}
  MOCK_METHOD(void, RegisterOnCloseCallback,
              (os::Handler * user_handler, ClassicFixedChannel::OnCloseCallback on_close_callback), (override));
  MOCK_METHOD(void, Acquire, (), (override));
+2 −2
Original line number Diff line number Diff line
@@ -20,8 +20,8 @@
#include <memory>

#include "hci/acl_manager.h"
#include "l2cap/internal/classic_fixed_channel_allocator.h"
#include "l2cap/internal/classic_fixed_channel_impl.h"
#include "l2cap/internal/fixed_channel_allocator.h"
#include "l2cap/internal/parameter_provider.h"
#include "l2cap/internal/scheduler.h"
#include "os/alarm.h"
@@ -89,7 +89,7 @@ class ClassicLink {

 private:
  os::Handler* l2cap_handler_;
  ClassicFixedChannelAllocator fixed_channel_allocator_{this, l2cap_handler_};
  FixedChannelAllocator<ClassicFixedChannelImpl, ClassicLink> fixed_channel_allocator_{this, l2cap_handler_};
  std::unique_ptr<hci::AclConnection> acl_connection_;
  std::unique_ptr<Scheduler> scheduler_;
  ParameterProvider* parameter_provider_;
Loading