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

Commit d8170d3d authored by Zach Johnson's avatar Zach Johnson Committed by Gerrit Code Review
Browse files

Merge changes I17ccda26,Ie4904c38,I93b83535,I595819d0,Id2975243, ...

* changes:
  use on_XYZ as convention for event callbacks inside HciLayer::impl
  Clean up namespaces inside hci_layer
  Collapse send_acl into dequeue_and_send_acl
  Move hal callbacks into their own object, to clarify execution context
  Add function on EventHandler<T> to post events back
  Make EventHandler generic, so we use it to replace SubeventHandler
  Add common::BindOn to simplify binding callbacks to instance methods.
  Begin migrating context switching out of impl
  Collapse HciLayer::GetAclQueueEnd()
  Make hci_layer module lifecycle functions protected, to match module.h
  Move trivial functions from hci_layer.cc to hci_layer.h
  Add CallOn variant of Module.Call()
  Add Module.Call() to cut down on module boilerplate
parents 4d8608e5 e691d0c2
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -30,5 +30,10 @@ using base::Passed;
using base::RetainedRef;
using base::Unretained;

template <typename T, typename Functor, typename... Args>
inline base::Callback<base::MakeUnboundRunType<Functor, T, Args...>> BindOn(T* obj, Functor&& functor, Args&&... args) {
  return common::Bind(std::forward<Functor>(functor), common::Unretained(obj), std::forward<Args>(args)...);
}

}  // namespace common
}  // namespace bluetooth
+97 −167
Original line number Diff line number Diff line
@@ -22,8 +22,10 @@
#include "os/queue.h"
#include "packet/packet_builder.h"

namespace {
namespace bluetooth {
namespace hci {
using bluetooth::common::Bind;
using bluetooth::common::BindOn;
using bluetooth::common::BindOnce;
using bluetooth::common::Callback;
using bluetooth::common::Closure;
@@ -35,23 +37,37 @@ using bluetooth::hci::CommandStatusView;
using bluetooth::hci::EventPacketView;
using bluetooth::hci::LeMetaEventView;
using bluetooth::os::Handler;
using common::BidiQueue;
using common::BidiQueueEnd;
using hci::OpCode;
using hci::ResetCompleteView;
using os::Alarm;
using os::Handler;

static void fail_if_reset_complete_not_success(CommandCompleteView complete) {
  auto reset_complete = ResetCompleteView::Create(complete);
  ASSERT(reset_complete.IsValid());
  ASSERT(reset_complete.GetStatus() == ErrorCode::SUCCESS);
}

static void on_hci_timeout(OpCode op_code) {
  ASSERT_LOG(false, "Timed out waiting for 0x%02hx (%s)", op_code, OpCodeText(op_code).c_str());
}

template <typename T>
class EventHandler {
 public:
  EventHandler() : event_handler(), handler(nullptr) {}
  EventHandler(Callback<void(EventPacketView)> on_event, Handler* on_event_handler)
      : event_handler(std::move(on_event)), handler(on_event_handler) {}
  Callback<void(EventPacketView)> event_handler;
  EventHandler() : callback(), handler(nullptr) {}
  EventHandler(Callback<void(T)> on_event, Handler* on_event_handler)
      : callback(std::move(on_event)), handler(on_event_handler) {}
  Callback<void(T)> callback;
  Handler* handler;
};

class SubeventHandler {
 public:
  SubeventHandler() : subevent_handler(), handler(nullptr) {}
  SubeventHandler(Callback<void(LeMetaEventView)> on_event, Handler* on_event_handler)
      : subevent_handler(std::move(on_event)), handler(on_event_handler) {}
  Callback<void(LeMetaEventView)> subevent_handler;
  Handler* handler;
  void Post(T event) {
    if (handler != nullptr) {
      handler->Post(BindOnce(callback, event));
    }
  }
};

class CommandQueueEntry {
@@ -72,30 +88,6 @@ class CommandQueueEntry {
  OnceCallback<void(CommandCompleteView)> on_complete;
  Handler* caller_handler;
};
}  // namespace

namespace bluetooth {
namespace hci {

using common::BidiQueue;
using common::BidiQueueEnd;
using os::Alarm;
using os::Handler;

namespace {
using hci::OpCode;
using hci::ResetCompleteView;

void fail_if_reset_complete_not_success(CommandCompleteView complete) {
  auto reset_complete = ResetCompleteView::Create(complete);
  ASSERT(reset_complete.IsValid());
  ASSERT(reset_complete.GetStatus() == ErrorCode::SUCCESS);
}

void on_hci_timeout(OpCode op_code) {
  ASSERT_LOG(false, "Timed out waiting for 0x%02hx (%s)", op_code, OpCodeText(op_code).c_str());
}
}  // namespace

template <typename T>
class CommandInterfaceImpl : public CommandInterface<T> {
@@ -115,7 +107,7 @@ class CommandInterfaceImpl : public CommandInterface<T> {
  HciLayer& hci_;
};

struct HciLayer::impl : public hal::HciHalCallbacks {
struct HciLayer::impl {
  impl(HciLayer& module) : hal_(nullptr), module_(module) {}

  void Start(hal::HciHal* hal) {
@@ -124,33 +116,29 @@ struct HciLayer::impl : public hal::HciHalCallbacks {

    auto queue_end = acl_queue_.GetDownEnd();
    Handler* handler = module_.GetHandler();
    queue_end->RegisterDequeue(handler, Bind(&impl::dequeue_and_send_acl, common::Unretained(this)));
    RegisterEventHandler(EventCode::COMMAND_COMPLETE, Bind(&impl::command_complete_callback, common::Unretained(this)),
                         handler);
    RegisterEventHandler(EventCode::COMMAND_STATUS, Bind(&impl::command_status_callback, common::Unretained(this)),
                         handler);
    RegisterEventHandler(EventCode::LE_META_EVENT, Bind(&impl::le_meta_event_callback, common::Unretained(this)),
                         handler);
    queue_end->RegisterDequeue(handler, BindOn(this, &impl::on_outbound_acl_ready));
    module_.RegisterEventHandler(EventCode::COMMAND_COMPLETE, BindOn(this, &impl::on_command_complete), handler);
    module_.RegisterEventHandler(EventCode::COMMAND_STATUS, BindOn(this, &impl::on_command_status), handler);
    module_.RegisterEventHandler(EventCode::LE_META_EVENT, BindOn(this, &impl::on_le_meta_event), handler);
    // TODO find the right place
    RegisterEventHandler(EventCode::PAGE_SCAN_REPETITION_MODE_CHANGE, Bind(&impl::drop, common::Unretained(this)),
                         handler);
    RegisterEventHandler(EventCode::MAX_SLOTS_CHANGE, Bind(&impl::drop, common::Unretained(this)), handler);
    RegisterEventHandler(EventCode::VENDOR_SPECIFIC, Bind(&impl::drop, common::Unretained(this)), handler);
    module_.RegisterEventHandler(EventCode::PAGE_SCAN_REPETITION_MODE_CHANGE, BindOn(this, &impl::drop), handler);
    module_.RegisterEventHandler(EventCode::MAX_SLOTS_CHANGE, BindOn(this, &impl::drop), handler);
    module_.RegisterEventHandler(EventCode::VENDOR_SPECIFIC, BindOn(this, &impl::drop), handler);

    EnqueueCommand(ResetBuilder::Create(), BindOnce(&fail_if_reset_complete_not_success), handler);
    hal_->registerIncomingPacketCallback(this);
    module_.EnqueueCommand(ResetBuilder::Create(), BindOnce(&fail_if_reset_complete_not_success), handler);
  }

  void drop(EventPacketView) {}

  void dequeue_and_send_acl() {
  void on_outbound_acl_ready() {
    auto packet = acl_queue_.GetDownEnd()->TryDequeue();
    send_acl(std::move(packet));
    std::vector<uint8_t> bytes;
    BitInserter bi(bytes);
    packet->Serialize(bi);
    hal_->sendAclData(bytes);
  }

  void Stop() {
    hal_->unregisterIncomingPacketCallback();

    acl_queue_.GetDownEnd()->UnregisterDequeue();
    incoming_acl_packet_buffer_.Clear();
    delete hci_timeout_alarm_;
@@ -158,21 +146,7 @@ struct HciLayer::impl : public hal::HciHalCallbacks {
    hal_ = nullptr;
  }

  void send_acl(std::unique_ptr<hci::BasePacketBuilder> packet) {
    std::vector<uint8_t> bytes;
    BitInserter bi(bytes);
    packet->Serialize(bi);
    hal_->sendAclData(bytes);
  }

  void send_sco(std::unique_ptr<hci::BasePacketBuilder> packet) {
    std::vector<uint8_t> bytes;
    BitInserter bi(bytes);
    packet->Serialize(bi);
    hal_->sendScoData(bytes);
  }

  void command_status_callback(EventPacketView event) {
  void on_command_status(EventPacketView event) {
    CommandStatusView status_view = CommandStatusView::Create(event);
    ASSERT(status_view.IsValid());
    command_credits_ = status_view.GetNumHciCommandPackets();
@@ -196,7 +170,7 @@ struct HciLayer::impl : public hal::HciHalCallbacks {
    send_next_command();
  }

  void command_complete_callback(EventPacketView event) {
  void on_command_complete(EventPacketView event) {
    CommandCompleteView complete_view = CommandCompleteView::Create(event);
    ASSERT(complete_view.IsValid());
    command_credits_ = complete_view.GetNumHciCommandPackets();
@@ -220,66 +194,22 @@ struct HciLayer::impl : public hal::HciHalCallbacks {
    send_next_command();
  }

  void le_meta_event_callback(EventPacketView event) {
  void on_le_meta_event(EventPacketView event) {
    LeMetaEventView meta_event_view = LeMetaEventView::Create(event);
    ASSERT(meta_event_view.IsValid());
    SubeventCode subevent_code = meta_event_view.GetSubeventCode();
    ASSERT_LOG(subevent_handlers_.find(subevent_code) != subevent_handlers_.end(),
               "Unhandled le event of type 0x%02hhx (%s)", subevent_code, SubeventCodeText(subevent_code).c_str());
    auto& registered = subevent_handlers_[subevent_code];
    if (registered.handler != nullptr) {
      registered.handler->Post(BindOnce(registered.subevent_handler, meta_event_view));
    } else {
      LOG_DEBUG("Dropping unregistered le event of type 0x%02hhx (%s)", subevent_code,
                SubeventCodeText(subevent_code).c_str());
    }
  }

  // Invoked from HAL thread
  void hciEventReceived(hal::HciPacket event_bytes) override {
    auto packet = packet::PacketView<packet::kLittleEndian>(std::make_shared<std::vector<uint8_t>>(event_bytes));
    EventPacketView event = EventPacketView::Create(packet);
    ASSERT(event.IsValid());
    module_.GetHandler()->Post(
        BindOnce(&HciLayer::impl::hci_event_received_handler, common::Unretained(this), std::move(event)));
    subevent_handlers_[subevent_code].Post(meta_event_view);
  }

  void hci_event_received_handler(EventPacketView event) {
  void on_hci_event(EventPacketView event) {
    EventCode event_code = event.GetEventCode();
    if (event_handlers_.find(event_code) == event_handlers_.end()) {
      LOG_DEBUG("Dropping unregistered event of type 0x%02hhx (%s)", event_code, EventCodeText(event_code).c_str());
      return;
    }
    auto& registered = event_handlers_[event_code];
    if (registered.handler != nullptr) {
      registered.handler->Post(BindOnce(registered.event_handler, event));
    }
  }

  // From HAL thread
  void aclDataReceived(hal::HciPacket data_bytes) override {
    auto packet =
        packet::PacketView<packet::kLittleEndian>(std::make_shared<std::vector<uint8_t>>(std::move(data_bytes)));
    AclPacketView acl = AclPacketView::Create(packet);
    incoming_acl_packet_buffer_.Enqueue(std::make_unique<AclPacketView>(acl), module_.GetHandler());
  }

  void scoDataReceived(hal::HciPacket data_bytes) override {
    auto packet = packet::PacketView<packet::kLittleEndian>(std::make_shared<std::vector<uint8_t>>(data_bytes));
    ScoPacketView sco = ScoPacketView::Create(packet);
  }

  void EnqueueCommand(std::unique_ptr<CommandPacketBuilder> command,
                      OnceCallback<void(CommandCompleteView)> on_complete, os::Handler* handler) {
    module_.GetHandler()->Post(common::BindOnce(&impl::handle_enqueue_command_with_complete, common::Unretained(this),
                                                std::move(command), std::move(on_complete),
                                                common::Unretained(handler)));
  }

  void EnqueueCommand(std::unique_ptr<CommandPacketBuilder> command, OnceCallback<void(CommandStatusView)> on_status,
                      os::Handler* handler) {
    module_.GetHandler()->Post(common::BindOnce(&impl::handle_enqueue_command_with_status, common::Unretained(this),
                                                std::move(command), std::move(on_status), common::Unretained(handler)));
    event_handlers_[event_code].Post(event);
  }

  void handle_enqueue_command_with_complete(std::unique_ptr<CommandPacketBuilder> command,
@@ -318,35 +248,15 @@ struct HciLayer::impl : public hal::HciHalCallbacks {
    hci_timeout_alarm_->Schedule(BindOnce(&on_hci_timeout, op_code), kHciTimeoutMs);
  }

  BidiQueueEnd<AclPacketBuilder, AclPacketView>* GetAclQueueEnd() {
    return acl_queue_.GetUpEnd();
  }

  void RegisterEventHandler(EventCode event_code, Callback<void(EventPacketView)> event_handler, os::Handler* handler) {
    module_.GetHandler()->Post(common::BindOnce(&impl::handle_register_event_handler, common::Unretained(this),
                                                event_code, event_handler, common::Unretained(handler)));
  }

  void handle_register_event_handler(EventCode event_code, Callback<void(EventPacketView)> event_handler,
                                     os::Handler* handler) {
    ASSERT_LOG(event_handlers_.count(event_code) == 0, "Can not register a second handler for event_code %02hhx (%s)",
               event_code, EventCodeText(event_code).c_str());
    event_handlers_[event_code] = EventHandler(event_handler, handler);
  }

  void UnregisterEventHandler(EventCode event_code) {
    module_.GetHandler()->Post(
        common::BindOnce(&impl::handle_unregister_event_handler, common::Unretained(this), event_code));
    event_handlers_[event_code] = EventHandler<EventPacketView>(event_handler, handler);
  }

  void handle_unregister_event_handler(EventCode event_code) {
    event_handlers_[event_code] = EventHandler();
  }

  void RegisterLeEventHandler(SubeventCode subevent_code, Callback<void(LeMetaEventView)> event_handler,
                              os::Handler* handler) {
    module_.GetHandler()->Post(common::BindOnce(&impl::handle_register_le_event_handler, common::Unretained(this),
                                                subevent_code, event_handler, common::Unretained(handler)));
    event_handlers_[event_code] = EventHandler<EventPacketView>();
  }

  void handle_register_le_event_handler(SubeventCode subevent_code, Callback<void(LeMetaEventView)> subevent_handler,
@@ -354,16 +264,11 @@ struct HciLayer::impl : public hal::HciHalCallbacks {
    ASSERT_LOG(subevent_handlers_.count(subevent_code) == 0,
               "Can not register a second handler for subevent_code %02hhx (%s)", subevent_code,
               SubeventCodeText(subevent_code).c_str());
    subevent_handlers_[subevent_code] = SubeventHandler(subevent_handler, handler);
  }

  void UnregisterLeEventHandler(SubeventCode subevent_code) {
    module_.GetHandler()->Post(
        common::BindOnce(&impl::handle_unregister_le_event_handler, common::Unretained(this), subevent_code));
    subevent_handlers_[subevent_code] = EventHandler<LeMetaEventView>(subevent_handler, handler);
  }

  void handle_unregister_le_event_handler(SubeventCode subevent_code) {
    subevent_handlers_[subevent_code] = SubeventHandler();
    subevent_handlers_[subevent_code] = EventHandler<LeMetaEventView>();
  }

  // The HAL
@@ -383,8 +288,8 @@ struct HciLayer::impl : public hal::HciHalCallbacks {
  // Command Handling
  std::list<CommandQueueEntry> command_queue_;

  std::map<EventCode, EventHandler> event_handlers_;
  std::map<SubeventCode, SubeventHandler> subevent_handlers_;
  std::map<EventCode, EventHandler<EventPacketView>> event_handlers_;
  std::map<SubeventCode, EventHandler<LeMetaEventView>> subevent_handlers_;
  OpCode waiting_command_{OpCode::NONE};
  uint8_t command_credits_{1};  // Send reset first
  Alarm* hci_timeout_alarm_{nullptr};
@@ -394,42 +299,70 @@ struct HciLayer::impl : public hal::HciHalCallbacks {
  os::EnqueueBuffer<AclPacketView> incoming_acl_packet_buffer_{acl_queue_.GetDownEnd()};
};

HciLayer::HciLayer() : impl_(std::make_unique<impl>(*this)) {}
// All functions here are running on the HAL thread
struct HciLayer::hal_callbacks : public hal::HciHalCallbacks {
  hal_callbacks(HciLayer& module) : module_(module) {}

  void hciEventReceived(hal::HciPacket event_bytes) override {
    auto packet = packet::PacketView<packet::kLittleEndian>(std::make_shared<std::vector<uint8_t>>(event_bytes));
    EventPacketView event = EventPacketView::Create(packet);
    ASSERT(event.IsValid());
    module_.CallOn(module_.impl_, &impl::on_hci_event, std::move(event));
  }

  void aclDataReceived(hal::HciPacket data_bytes) override {
    auto packet =
        packet::PacketView<packet::kLittleEndian>(std::make_shared<std::vector<uint8_t>>(std::move(data_bytes)));
    AclPacketView acl = AclPacketView::Create(packet);
    module_.impl_->incoming_acl_packet_buffer_.Enqueue(std::make_unique<AclPacketView>(acl), module_.GetHandler());
  }

  void scoDataReceived(hal::HciPacket data_bytes) override {
    // Not implemented yet
  }

  HciLayer& module_;
};

HciLayer::HciLayer() : impl_(new impl(*this)), hal_callbacks_(new hal_callbacks(*this)) {}

HciLayer::~HciLayer() {
  impl_.reset();
  delete impl_;
  delete hal_callbacks_;
}

void HciLayer::EnqueueCommand(std::unique_ptr<CommandPacketBuilder> command,
                              common::OnceCallback<void(CommandCompleteView)> on_complete, os::Handler* handler) {
  impl_->EnqueueCommand(std::move(command), std::move(on_complete), handler);
  CallOn(impl_, &impl::handle_enqueue_command_with_complete, std::move(command), std::move(on_complete),
         common::Unretained(handler));
}

void HciLayer::EnqueueCommand(std::unique_ptr<CommandPacketBuilder> command,
                              common::OnceCallback<void(CommandStatusView)> on_status, os::Handler* handler) {
  impl_->EnqueueCommand(std::move(command), std::move(on_status), handler);
  CallOn(impl_, &impl::handle_enqueue_command_with_status, std::move(command), std::move(on_status),
         common::Unretained(handler));
}

common::BidiQueueEnd<AclPacketBuilder, AclPacketView>* HciLayer::GetAclQueueEnd() {
  return impl_->GetAclQueueEnd();
  return impl_->acl_queue_.GetUpEnd();
}

void HciLayer::RegisterEventHandler(EventCode event_code, common::Callback<void(EventPacketView)> event_handler,
                                    os::Handler* handler) {
  impl_->RegisterEventHandler(event_code, std::move(event_handler), handler);
  CallOn(impl_, &impl::handle_register_event_handler, event_code, event_handler, common::Unretained(handler));
}

void HciLayer::UnregisterEventHandler(EventCode event_code) {
  impl_->UnregisterEventHandler(event_code);
  CallOn(impl_, &impl::handle_unregister_event_handler, event_code);
}

void HciLayer::RegisterLeEventHandler(SubeventCode subevent_code, common::Callback<void(LeMetaEventView)> event_handler,
                                      os::Handler* handler) {
  impl_->RegisterLeEventHandler(subevent_code, std::move(event_handler), handler);
  CallOn(impl_, &impl::handle_register_le_event_handler, subevent_code, event_handler, common::Unretained(handler));
}

void HciLayer::UnregisterLeEventHandler(SubeventCode subevent_code) {
  impl_->UnregisterLeEventHandler(subevent_code);
  CallOn(impl_, &impl::handle_unregister_le_event_handler, subevent_code);
}

AclConnectionInterface* HciLayer::GetAclConnectionInterface(common::Callback<void(EventPacketView)> event_handler,
@@ -488,20 +421,17 @@ void HciLayer::ListDependencies(ModuleList* list) {
  list->add<hal::HciHal>();
}

os::Handler* HciLayer::GetHciHandler() {
  return GetHandler();
}

void HciLayer::Start() {
  impl_->Start(GetDependency<hal::HciHal>());
  auto hal = GetDependency<hal::HciHal>();
  impl_->Start(hal);
  hal->registerIncomingPacketCallback(hal_callbacks_);
}

void HciLayer::Stop() {
  auto hal = GetDependency<hal::HciHal>();
  hal->unregisterIncomingPacketCallback();
  impl_->Stop();
}

std::string HciLayer::ToString() const {
  return "Hci Layer";
}
}  // namespace hci
}  // namespace bluetooth
+14 −6
Original line number Diff line number Diff line
@@ -82,22 +82,30 @@ class HciLayer : public Module, public CommandInterface<CommandPacketBuilder> {
  virtual LeScanningInterface* GetLeScanningInterface(common::Callback<void(LeMetaEventView)> event_handler,
                                                      os::Handler* handler);

  os::Handler* GetHciHandler() {
    return GetHandler();
  }

  std::string ToString() const override {
    return "Hci Layer";
  }

  static constexpr std::chrono::milliseconds kHciTimeoutMs = std::chrono::milliseconds(2000);

  static const ModuleFactory Factory;

 protected:
  void ListDependencies(ModuleList* list) override;

  void Start() override;

  void Stop() override;

  os::Handler* GetHciHandler();

  std::string ToString() const override;
  static constexpr std::chrono::milliseconds kHciTimeoutMs = std::chrono::milliseconds(2000);

 private:
  struct impl;
  std::unique_ptr<impl> impl_;
  struct hal_callbacks;
  impl* impl_;
  hal_callbacks* hal_callbacks_;
};
}  // namespace hci
}  // namespace bluetooth
+11 −0
Original line number Diff line number Diff line
@@ -99,6 +99,17 @@ class Module {
    return static_cast<T*>(GetDependency(&T::Factory));
  }

  template <typename Functor, typename... Args>
  void Call(Functor&& functor, Args&&... args) {
    GetHandler()->Post(common::BindOnce(std::forward<Functor>(functor), std::forward<Args>(args)...));
  }

  template <typename T, typename Functor, typename... Args>
  void CallOn(T* obj, Functor&& functor, Args&&... args) {
    GetHandler()->Post(
        common::BindOnce(std::forward<Functor>(functor), common::Unretained(obj), std::forward<Args>(args)...));
  }

 private:
  Module* GetDependency(const ModuleFactory* module) const;