Merge "Remove IBluetooth.sendConnectionStateChanged"
diff --git a/gd/hci/acl_manager.cc b/gd/hci/acl_manager.cc
index 2852b6c..faad20b 100644
--- a/gd/hci/acl_manager.cc
+++ b/gd/hci/acl_manager.cc
@@ -924,7 +924,7 @@
                                           supervision_timeout, minimum_ce_length, maximum_ce_length),
         common::BindOnce([](CommandStatusView status) {
           ASSERT(status.IsValid());
-          ASSERT(status.GetCommandOpCode() == OpCode::CREATE_CONNECTION);
+          ASSERT(status.GetCommandOpCode() == OpCode::LE_CREATE_CONNECTION);
         }),
         handler_);
   }
diff --git a/gd/hci/acl_manager_test.cc b/gd/hci/acl_manager_test.cc
index 8b2cb32..3e3f1b5 100644
--- a/gd/hci/acl_manager_test.cc
+++ b/gd/hci/acl_manager_test.cc
@@ -101,6 +101,7 @@
   void EnqueueCommand(std::unique_ptr<CommandPacketBuilder> command,
                       common::OnceCallback<void(CommandStatusView)> on_status, os::Handler* handler) override {
     command_queue_.push(std::move(command));
+    command_status_callbacks.push_front(std::move(on_status));
     not_empty_.notify_all();
   }
 
@@ -155,9 +156,9 @@
   void IncomingEvent(std::unique_ptr<EventPacketBuilder> event_builder) {
     auto packet = GetPacketView(std::move(event_builder));
     EventPacketView event = EventPacketView::Create(packet);
-    EXPECT_TRUE(event.IsValid());
+    ASSERT_TRUE(event.IsValid());
     EventCode event_code = event.GetEventCode();
-    EXPECT_TRUE(registered_events_.find(event_code) != registered_events_.end());
+    ASSERT_TRUE(registered_events_.find(event_code) != registered_events_.end()) << EventCodeText(event_code);
     registered_events_[event_code].Run(event);
   }
 
@@ -202,6 +203,13 @@
     command_complete_callbacks.pop_front();
   }
 
+  void CommandStatusCallback(EventPacketView event) {
+    CommandStatusView status_view = CommandStatusView::Create(event);
+    ASSERT(status_view.IsValid());
+    std::move(command_status_callbacks.front()).Run(status_view);
+    command_status_callbacks.pop_front();
+  }
+
   PacketView<kLittleEndian> OutgoingAclData() {
     auto queue_end = acl_queue_.GetDownEnd();
     std::unique_ptr<AclPacketBuilder> received;
@@ -217,13 +225,19 @@
   }
 
   void ListDependencies(ModuleList* list) override {}
-  void Start() override {}
+  void Start() override {
+    RegisterEventHandler(EventCode::COMMAND_COMPLETE,
+                         base::Bind(&TestHciLayer::CommandCompleteCallback, common::Unretained(this)), nullptr);
+    RegisterEventHandler(EventCode::COMMAND_STATUS,
+                         base::Bind(&TestHciLayer::CommandStatusCallback, common::Unretained(this)), nullptr);
+  }
   void Stop() override {}
 
  private:
   std::map<EventCode, common::Callback<void(EventPacketView)>> registered_events_;
   std::map<SubeventCode, common::Callback<void(LeMetaEventView)>> registered_le_events_;
   std::list<base::OnceCallback<void(CommandCompleteView)>> command_complete_callbacks;
+  std::list<base::OnceCallback<void(CommandStatusView)>> command_status_callbacks;
   BidiQueue<AclPacketView, AclPacketBuilder> acl_queue_{3 /* TODO: Set queue depth */};
 
   std::queue<std::unique_ptr<CommandPacketBuilder>> command_queue_;
@@ -235,6 +249,7 @@
  protected:
   void SetUp() override {
     test_hci_layer_ = new TestHciLayer;  // Ownership is transferred to registry
+    test_hci_layer_->Start();
     test_controller_ = new TestController;
     fake_registry_.InjectTestModule(&HciLayer::Factory, test_hci_layer_);
     fake_registry_.InjectTestModule(&Controller::Factory, test_controller_);
@@ -348,9 +363,6 @@
  protected:
   void SetUp() override {
     AclManagerTest::SetUp();
-    test_hci_layer_->RegisterEventHandler(
-        EventCode::COMMAND_COMPLETE,
-        base::Bind(&TestHciLayer::CommandCompleteCallback, common::Unretained(test_hci_layer_)), nullptr);
 
     handle_ = 0x123;
     acl_manager_->CreateConnection(remote);
@@ -473,6 +485,8 @@
   EXPECT_EQ(command_view.GetPeerAddress(), remote);
   EXPECT_EQ(command_view.GetPeerAddressType(), AddressType::PUBLIC_DEVICE_ADDRESS);
 
+  test_hci_layer_->IncomingEvent(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01));
+
   auto first_connection = GetLeConnectionFuture();
 
   test_hci_layer_->IncomingLeMetaEvent(
@@ -497,6 +511,8 @@
   EXPECT_EQ(command_view.GetPeerAddress(), remote);
   EXPECT_EQ(command_view.GetPeerAddressType(), AddressType::PUBLIC_DEVICE_ADDRESS);
 
+  test_hci_layer_->IncomingEvent(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01));
+
   EXPECT_CALL(mock_le_connection_callbacks_,
               OnLeConnectFail(remote_with_type, ErrorCode::CONNECTION_REJECTED_LIMITED_RESOURCES));
   test_hci_layer_->IncomingLeMetaEvent(LeConnectionCompleteBuilder::Create(
diff --git a/gd/l2cap/Android.bp b/gd/l2cap/Android.bp
index 51258b4..0bdfbd2 100644
--- a/gd/l2cap/Android.bp
+++ b/gd/l2cap/Android.bp
@@ -2,14 +2,11 @@
     name: "BluetoothL2capSources",
     srcs: [
         "fcs.cc",
-        "classic/dynamic_channel.cc",
         "classic/dynamic_channel_manager.cc",
         "classic/dynamic_channel_service.cc",
         "classic/fixed_channel.cc",
         "classic/fixed_channel_manager.cc",
         "classic/fixed_channel_service.cc",
-        "classic/internal/dynamic_channel_allocator.cc",
-        "classic/internal/dynamic_channel_impl.cc",
         "classic/internal/dynamic_channel_service_manager_impl.cc",
         "classic/internal/fixed_channel_impl.cc",
         "classic/internal/fixed_channel_service_manager_impl.cc",
@@ -17,8 +14,11 @@
         "classic/internal/link_manager.cc",
         "classic/internal/signalling_manager.cc",
         "classic/l2cap_classic_module.cc",
+        "dynamic_channel.cc",
         "internal/basic_mode_channel_data_controller.cc",
         "internal/data_pipeline_manager.cc",
+        "internal/dynamic_channel_allocator.cc",
+        "internal/dynamic_channel_impl.cc",
         "internal/enhanced_retransmission_mode_channel_data_controller.cc",
         "internal/le_credit_based_channel_data_controller.cc",
         "internal/receiver.cc",
@@ -37,14 +37,14 @@
 filegroup {
     name: "BluetoothL2capTestSources",
     srcs: [
-        "classic/internal/dynamic_channel_allocator_test.cc",
-        "classic/internal/dynamic_channel_impl_test.cc",
         "classic/internal/dynamic_channel_service_manager_test.cc",
         "classic/internal/fixed_channel_impl_test.cc",
         "classic/internal/fixed_channel_service_manager_test.cc",
         "classic/internal/link_manager_test.cc",
         "classic/internal/signalling_manager_test.cc",
         "internal/basic_mode_channel_data_controller_test.cc",
+        "internal/dynamic_channel_allocator_test.cc",
+        "internal/dynamic_channel_impl_test.cc",
         "internal/enhanced_retransmission_mode_channel_data_controller_test.cc",
         "internal/fixed_channel_allocator_test.cc",
         "internal/le_credit_based_channel_data_controller_test.cc",
@@ -76,7 +76,7 @@
 filegroup {
     name: "BluetoothL2capFuzzTestSources",
     srcs: [
-        "classic/internal/dynamic_channel_allocator_fuzz_test.cc",
+        "internal/dynamic_channel_allocator_fuzz_test.cc",
         "l2cap_packet_fuzz_test.cc",
     ],
 }
diff --git a/gd/l2cap/classic/dynamic_channel_manager.h b/gd/l2cap/classic/dynamic_channel_manager.h
index 340d68d..4810270 100644
--- a/gd/l2cap/classic/dynamic_channel_manager.h
+++ b/gd/l2cap/classic/dynamic_channel_manager.h
@@ -19,9 +19,9 @@
 
 #include "hci/acl_manager.h"
 #include "hci/address.h"
-#include "l2cap/classic/dynamic_channel.h"
 #include "l2cap/classic/dynamic_channel_configuration_option.h"
 #include "l2cap/classic/dynamic_channel_service.h"
+#include "l2cap/dynamic_channel.h"
 #include "l2cap/l2cap_packets.h"
 #include "l2cap/psm.h"
 #include "l2cap/security_policy.h"
diff --git a/gd/l2cap/classic/fixed_channel_manager.h b/gd/l2cap/classic/fixed_channel_manager.h
index 5e8f6ab..65c0b73 100644
--- a/gd/l2cap/classic/fixed_channel_manager.h
+++ b/gd/l2cap/classic/fixed_channel_manager.h
@@ -142,6 +142,7 @@
   FixedChannelManager(internal::FixedChannelServiceManagerImpl* service_manager, internal::LinkManager* link_manager,
                       os::Handler* l2cap_layer_handler)
       : service_manager_(service_manager), link_manager_(link_manager), l2cap_layer_handler_(l2cap_layer_handler) {}
+
   internal::FixedChannelServiceManagerImpl* service_manager_ = nullptr;
   internal::LinkManager* link_manager_ = nullptr;
   os::Handler* l2cap_layer_handler_ = nullptr;
diff --git a/gd/l2cap/classic/internal/channel_configuration_state.h b/gd/l2cap/classic/internal/channel_configuration_state.h
new file mode 100644
index 0000000..b0dead5
--- /dev/null
+++ b/gd/l2cap/classic/internal/channel_configuration_state.h
@@ -0,0 +1,62 @@
+/*
+ * 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 "l2cap/l2cap_packets.h"
+#include "l2cap/mtu.h"
+
+namespace bluetooth {
+namespace l2cap {
+namespace classic {
+namespace internal {
+
+struct ChannelConfigurationState {
+ public:
+  enum State {
+    /**
+     * for the initiator path, a request has been sent but a positive response has not yet been received, and for the
+     * acceptor path, a request with acceptable options has not yet been received.
+     */
+    WAIT_CONFIG_REQ_RSP,
+    /**
+     * the acceptor path is complete after having responded to acceptable options, but for the initiator path, a
+     * positive response on the recent request has not yet been received.
+     */
+    WAIT_CONFIG_RSP,
+    /**
+     * the initiator path is complete after having received a positive response, but for the acceptor path, a request
+     * with acceptable options has not yet been received.
+     */
+    WAIT_CONFIG_REQ,
+    /**
+     * Configuration is complete
+     */
+    CONFIGURED,
+  };
+  State state_ = State::WAIT_CONFIG_REQ_RSP;
+
+  Mtu incoming_mtu_ = kDefaultClassicMtu;
+  Mtu outgoing_mtu_ = kDefaultClassicMtu;
+  RetransmissionAndFlowControlModeOption retransmission_and_flow_control_mode_;
+  RetransmissionAndFlowControlConfigurationOption local_retransmission_and_flow_control_;
+  RetransmissionAndFlowControlConfigurationOption remote_retransmission_and_flow_control_;
+  FcsType fcs_type_ = FcsType::DEFAULT;
+};
+}  // namespace internal
+}  // namespace classic
+}  // namespace l2cap
+}  // namespace bluetooth
diff --git a/gd/l2cap/classic/internal/dynamic_channel_service_impl.h b/gd/l2cap/classic/internal/dynamic_channel_service_impl.h
index 2fcf3fc..672d24b 100644
--- a/gd/l2cap/classic/internal/dynamic_channel_service_impl.h
+++ b/gd/l2cap/classic/internal/dynamic_channel_service_impl.h
@@ -18,10 +18,10 @@
 
 #include "common/bind.h"
 
-#include "l2cap/classic/dynamic_channel.h"
 #include "l2cap/classic/dynamic_channel_configuration_option.h"
 #include "l2cap/classic/dynamic_channel_manager.h"
 #include "l2cap/classic/dynamic_channel_service.h"
+#include "l2cap/dynamic_channel.h"
 
 namespace bluetooth {
 namespace l2cap {
diff --git a/gd/l2cap/classic/internal/dynamic_channel_service_manager_impl_mock.h b/gd/l2cap/classic/internal/dynamic_channel_service_manager_impl_mock.h
index 34363f1..05d4b7f 100644
--- a/gd/l2cap/classic/internal/dynamic_channel_service_manager_impl_mock.h
+++ b/gd/l2cap/classic/internal/dynamic_channel_service_manager_impl_mock.h
@@ -15,8 +15,8 @@
  */
 #pragma once
 
-#include "l2cap/classic/internal/dynamic_channel_impl.h"
 #include "l2cap/classic/internal/dynamic_channel_service_manager_impl.h"
+#include "l2cap/internal/dynamic_channel_impl.h"
 
 #include <gmock/gmock.h>
 
diff --git a/gd/l2cap/classic/internal/fixed_channel_impl.cc b/gd/l2cap/classic/internal/fixed_channel_impl.cc
index 8ac6c94..9bfaef8 100644
--- a/gd/l2cap/classic/internal/fixed_channel_impl.cc
+++ b/gd/l2cap/classic/internal/fixed_channel_impl.cc
@@ -94,8 +94,6 @@
   link_->RefreshRefCount();
 }
 
-void FixedChannelImpl::SetSender(l2cap::internal::Sender* sender) {}
-
 }  // namespace internal
 }  // namespace classic
 }  // namespace l2cap
diff --git a/gd/l2cap/classic/internal/fixed_channel_impl.h b/gd/l2cap/classic/internal/fixed_channel_impl.h
index 6fde5c6..4c4e9f1 100644
--- a/gd/l2cap/classic/internal/fixed_channel_impl.h
+++ b/gd/l2cap/classic/internal/fixed_channel_impl.h
@@ -38,7 +38,7 @@
   virtual ~FixedChannelImpl() = default;
 
   hci::Address GetDevice() const {
-    return device_;
+    return device_.GetAddress();
   }
 
   virtual void RegisterOnCloseCallback(os::Handler* user_handler, FixedChannel::OnCloseCallback on_close_callback);
@@ -74,14 +74,13 @@
   Cid GetRemoteCid() const {
     return cid_;
   }
-  void SetSender(l2cap::internal::Sender* sender) override;
 
  private:
   // Constructor states
   // For logging purpose only
   const Cid cid_;
   // For logging purpose only
-  const hci::Address device_;
+  const hci::AddressWithType device_;
   // Needed to handle Acquire() and Release()
   Link* link_;
   os::Handler* l2cap_handler_;
diff --git a/gd/l2cap/classic/internal/fixed_channel_impl_test.cc b/gd/l2cap/classic/internal/fixed_channel_impl_test.cc
index 750473d..3a35d82 100644
--- a/gd/l2cap/classic/internal/fixed_channel_impl_test.cc
+++ b/gd/l2cap/classic/internal/fixed_channel_impl_test.cc
@@ -61,16 +61,18 @@
 TEST_F(L2capClassicFixedChannelImplTest, get_device) {
   MockParameterProvider mock_parameter_provider;
   MockLink mock_classic_link(l2cap_handler_, &mock_parameter_provider);
-  hci::Address device{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}};
+  hci::AddressWithType device{hci::Address{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}},
+                              hci::AddressType::PUBLIC_IDENTITY_ADDRESS};
   EXPECT_CALL(mock_classic_link, GetDevice()).WillRepeatedly(Return(device));
   FixedChannelImpl fixed_channel_impl(kSmpBrCid, &mock_classic_link, l2cap_handler_);
-  EXPECT_EQ(device, fixed_channel_impl.GetDevice());
+  EXPECT_EQ(device.GetAddress(), fixed_channel_impl.GetDevice());
 }
 
 TEST_F(L2capClassicFixedChannelImplTest, close_triggers_callback) {
   MockParameterProvider mock_parameter_provider;
   MockLink mock_classic_link(l2cap_handler_, &mock_parameter_provider);
-  hci::Address device{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}};
+  hci::AddressWithType device{hci::Address{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}},
+                              hci::AddressType::PUBLIC_IDENTITY_ADDRESS};
   EXPECT_CALL(mock_classic_link, GetDevice()).WillRepeatedly(Return(device));
   FixedChannelImpl fixed_channel_impl(kSmpBrCid, &mock_classic_link, l2cap_handler_);
 
@@ -91,7 +93,8 @@
 TEST_F(L2capClassicFixedChannelImplTest, register_callback_after_close_should_call_immediately) {
   MockParameterProvider mock_parameter_provider;
   MockLink mock_classic_link(l2cap_handler_, &mock_parameter_provider);
-  hci::Address device{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}};
+  hci::AddressWithType device{hci::Address{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}},
+                              hci::AddressType::PUBLIC_IDENTITY_ADDRESS};
   EXPECT_CALL(mock_classic_link, GetDevice()).WillRepeatedly(Return(device));
   FixedChannelImpl fixed_channel_impl(kSmpBrCid, &mock_classic_link, l2cap_handler_);
 
@@ -112,7 +115,8 @@
 TEST_F(L2capClassicFixedChannelImplTest, close_twice_should_fail) {
   MockParameterProvider mock_parameter_provider;
   MockLink mock_classic_link(l2cap_handler_, &mock_parameter_provider);
-  hci::Address device{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}};
+  hci::AddressWithType device{hci::Address{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}},
+                              hci::AddressType::PUBLIC_IDENTITY_ADDRESS};
   EXPECT_CALL(mock_classic_link, GetDevice()).WillRepeatedly(Return(device));
   FixedChannelImpl fixed_channel_impl(kSmpBrCid, &mock_classic_link, l2cap_handler_);
 
@@ -136,7 +140,8 @@
 TEST_F(L2capClassicFixedChannelImplTest, multiple_registeration_should_fail) {
   MockParameterProvider mock_parameter_provider;
   MockLink mock_classic_link(l2cap_handler_, &mock_parameter_provider);
-  hci::Address device{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}};
+  hci::AddressWithType device{hci::Address{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}},
+                              hci::AddressType::PUBLIC_IDENTITY_ADDRESS};
   EXPECT_CALL(mock_classic_link, GetDevice()).WillRepeatedly(Return(device));
   FixedChannelImpl fixed_channel_impl(kSmpBrCid, &mock_classic_link, l2cap_handler_);
 
@@ -156,7 +161,8 @@
 TEST_F(L2capClassicFixedChannelImplTest, call_acquire_before_registeration_should_fail) {
   MockParameterProvider mock_parameter_provider;
   MockLink mock_classic_link(l2cap_handler_, &mock_parameter_provider);
-  hci::Address device{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}};
+  hci::AddressWithType device{hci::Address{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}},
+                              hci::AddressType::PUBLIC_IDENTITY_ADDRESS};
   EXPECT_CALL(mock_classic_link, GetDevice()).WillRepeatedly(Return(device));
   FixedChannelImpl fixed_channel_impl(kSmpBrCid, &mock_classic_link, l2cap_handler_);
   EXPECT_DEATH(fixed_channel_impl.Acquire(), ".*Acquire.*");
@@ -165,7 +171,8 @@
 TEST_F(L2capClassicFixedChannelImplTest, call_release_before_registeration_should_fail) {
   MockParameterProvider mock_parameter_provider;
   MockLink mock_classic_link(l2cap_handler_, &mock_parameter_provider);
-  hci::Address device{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}};
+  hci::AddressWithType device{hci::Address{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}},
+                              hci::AddressType::PUBLIC_IDENTITY_ADDRESS};
   EXPECT_CALL(mock_classic_link, GetDevice()).WillRepeatedly(Return(device));
   FixedChannelImpl fixed_channel_impl(kSmpBrCid, &mock_classic_link, l2cap_handler_);
   EXPECT_DEATH(fixed_channel_impl.Release(), ".*Release.*");
@@ -174,7 +181,8 @@
 TEST_F(L2capClassicFixedChannelImplTest, test_acquire_release_channel) {
   MockParameterProvider mock_parameter_provider;
   MockLink mock_classic_link(l2cap_handler_, &mock_parameter_provider);
-  hci::Address device{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}};
+  hci::AddressWithType device{hci::Address{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}},
+                              hci::AddressType::PUBLIC_IDENTITY_ADDRESS};
   EXPECT_CALL(mock_classic_link, GetDevice()).WillRepeatedly(Return(device));
   FixedChannelImpl fixed_channel_impl(kSmpBrCid, &mock_classic_link, l2cap_handler_);
 
@@ -202,7 +210,8 @@
 TEST_F(L2capClassicFixedChannelImplTest, test_acquire_after_close) {
   MockParameterProvider mock_parameter_provider;
   MockLink mock_classic_link(l2cap_handler_, &mock_parameter_provider);
-  hci::Address device{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}};
+  hci::AddressWithType device{hci::Address{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}},
+                              hci::AddressType::PUBLIC_IDENTITY_ADDRESS};
   EXPECT_CALL(mock_classic_link, GetDevice()).WillRepeatedly(Return(device));
   FixedChannelImpl fixed_channel_impl(kSmpBrCid, &mock_classic_link, l2cap_handler_);
 
diff --git a/gd/l2cap/classic/internal/link.cc b/gd/l2cap/classic/internal/link.cc
index 63f5f71..a23f5ec 100644
--- a/gd/l2cap/classic/internal/link.cc
+++ b/gd/l2cap/classic/internal/link.cc
@@ -36,8 +36,8 @@
     : l2cap_handler_(l2cap_handler), acl_connection_(std::move(acl_connection)),
       data_pipeline_manager_(l2cap_handler, acl_connection_->GetAclQueueEnd()), parameter_provider_(parameter_provider),
       dynamic_service_manager_(dynamic_service_manager), fixed_service_manager_(fixed_service_manager),
-      signalling_manager_(l2cap_handler_, this, dynamic_service_manager_, &dynamic_channel_allocator_,
-                          fixed_service_manager_) {
+      signalling_manager_(l2cap_handler_, this, &data_pipeline_manager_, dynamic_service_manager_,
+                          &dynamic_channel_allocator_, fixed_service_manager_) {
   ASSERT(l2cap_handler_ != nullptr);
   ASSERT(acl_connection_ != nullptr);
   ASSERT(parameter_provider_ != nullptr);
@@ -86,8 +86,8 @@
   signalling_manager_.SendInformationRequest(type);
 }
 
-std::shared_ptr<DynamicChannelImpl> Link::AllocateDynamicChannel(Psm psm, Cid remote_cid,
-                                                                 SecurityPolicy security_policy) {
+std::shared_ptr<l2cap::internal::DynamicChannelImpl> Link::AllocateDynamicChannel(Psm psm, Cid remote_cid,
+                                                                                  SecurityPolicy security_policy) {
   auto channel = dynamic_channel_allocator_.AllocateChannel(psm, remote_cid, security_policy);
   if (channel != nullptr) {
     data_pipeline_manager_.AttachChannel(channel->GetCid(), channel);
@@ -96,8 +96,8 @@
   return channel;
 }
 
-std::shared_ptr<DynamicChannelImpl> Link::AllocateReservedDynamicChannel(Cid reserved_cid, Psm psm, Cid remote_cid,
-                                                                         SecurityPolicy security_policy) {
+std::shared_ptr<l2cap::internal::DynamicChannelImpl> Link::AllocateReservedDynamicChannel(
+    Cid reserved_cid, Psm psm, Cid remote_cid, SecurityPolicy security_policy) {
   auto channel = dynamic_channel_allocator_.AllocateReservedChannel(reserved_cid, psm, remote_cid, security_policy);
   if (channel != nullptr) {
     data_pipeline_manager_.AttachChannel(channel->GetCid(), channel);
diff --git a/gd/l2cap/classic/internal/link.h b/gd/l2cap/classic/internal/link.h
index 44a5b25..8e1e0c9 100644
--- a/gd/l2cap/classic/internal/link.h
+++ b/gd/l2cap/classic/internal/link.h
@@ -21,13 +21,14 @@
 
 #include "hci/acl_manager.h"
 #include "l2cap/classic/dynamic_channel_configuration_option.h"
-#include "l2cap/classic/internal/dynamic_channel_allocator.h"
-#include "l2cap/classic/internal/dynamic_channel_impl.h"
 #include "l2cap/classic/internal/dynamic_channel_service_manager_impl.h"
 #include "l2cap/classic/internal/fixed_channel_impl.h"
 #include "l2cap/classic/internal/fixed_channel_service_manager_impl.h"
 #include "l2cap/internal/data_pipeline_manager.h"
+#include "l2cap/internal/dynamic_channel_allocator.h"
+#include "l2cap/internal/dynamic_channel_impl.h"
 #include "l2cap/internal/fixed_channel_allocator.h"
+#include "l2cap/internal/ilink.h"
 #include "l2cap/internal/parameter_provider.h"
 #include "os/alarm.h"
 #include "os/handler.h"
@@ -38,7 +39,7 @@
 namespace classic {
 namespace internal {
 
-class Link {
+class Link : public l2cap::internal::ILink {
  public:
   Link(os::Handler* l2cap_handler, std::unique_ptr<hci::AclConnection> acl_connection,
        l2cap::internal::ParameterProvider* parameter_provider,
@@ -47,8 +48,8 @@
 
   virtual ~Link() = default;
 
-  virtual hci::Address GetDevice() {
-    return acl_connection_->GetAddress();
+  virtual hci::AddressWithType GetDevice() {
+    return {acl_connection_->GetAddress(), acl_connection_->GetAddressType()};
   }
 
   struct PendingDynamicChannelConnection {
@@ -80,13 +81,13 @@
 
   virtual void SendInformationRequest(InformationRequestInfoType type);
 
-  virtual void SendDisconnectionRequest(Cid local_cid, Cid remote_cid);
+  virtual void SendDisconnectionRequest(Cid local_cid, Cid remote_cid) override;
 
-  virtual std::shared_ptr<DynamicChannelImpl> AllocateDynamicChannel(Psm psm, Cid remote_cid,
-                                                                     SecurityPolicy security_policy);
+  virtual std::shared_ptr<l2cap::internal::DynamicChannelImpl> AllocateDynamicChannel(Psm psm, Cid remote_cid,
+                                                                                      SecurityPolicy security_policy);
 
-  virtual std::shared_ptr<DynamicChannelImpl> AllocateReservedDynamicChannel(Cid reserved_cid, Psm psm, Cid remote_cid,
-                                                                             SecurityPolicy security_policy);
+  virtual std::shared_ptr<l2cap::internal::DynamicChannelImpl> AllocateReservedDynamicChannel(
+      Cid reserved_cid, Psm psm, Cid remote_cid, SecurityPolicy security_policy);
 
   virtual classic::DynamicChannelConfigurationOption GetConfigurationForInitialConfiguration(Cid cid);
 
@@ -113,7 +114,7 @@
  private:
   os::Handler* l2cap_handler_;
   l2cap::internal::FixedChannelAllocator<FixedChannelImpl, Link> fixed_channel_allocator_{this, l2cap_handler_};
-  DynamicChannelAllocator dynamic_channel_allocator_{this, l2cap_handler_};
+  l2cap::internal::DynamicChannelAllocator dynamic_channel_allocator_{this, l2cap_handler_};
   std::unique_ptr<hci::AclConnection> acl_connection_;
   l2cap::internal::DataPipelineManager data_pipeline_manager_;
   l2cap::internal::ParameterProvider* parameter_provider_;
diff --git a/gd/l2cap/classic/internal/link_manager.cc b/gd/l2cap/classic/internal/link_manager.cc
index 812b180..96e1333 100644
--- a/gd/l2cap/classic/internal/link_manager.cc
+++ b/gd/l2cap/classic/internal/link_manager.cc
@@ -20,7 +20,6 @@
 #include "hci/address.h"
 #include "l2cap/classic/internal/link.h"
 #include "l2cap/internal/scheduler_fifo.h"
-#include "os/handler.h"
 #include "os/log.h"
 
 #include "l2cap/classic/internal/link_manager.h"
diff --git a/gd/l2cap/classic/internal/link_mock.h b/gd/l2cap/classic/internal/link_mock.h
index cbbad15..4eb336e 100644
--- a/gd/l2cap/classic/internal/link_mock.h
+++ b/gd/l2cap/classic/internal/link_mock.h
@@ -38,10 +38,10 @@
   explicit MockLink(os::Handler* handler, l2cap::internal::ParameterProvider* parameter_provider,
                     std::unique_ptr<hci::AclConnection> acl_connection)
       : Link(handler, std::move(acl_connection), parameter_provider, nullptr, nullptr){};
-  MOCK_METHOD(hci::Address, GetDevice, (), (override));
+  MOCK_METHOD(hci::AddressWithType, GetDevice, (), (override));
   MOCK_METHOD(void, OnAclDisconnected, (hci::ErrorCode status), (override));
   MOCK_METHOD(void, Disconnect, (), (override));
-  MOCK_METHOD(std::shared_ptr<DynamicChannelImpl>, AllocateDynamicChannel,
+  MOCK_METHOD(std::shared_ptr<l2cap::internal::DynamicChannelImpl>, AllocateDynamicChannel,
               (Psm psm, Cid cid, SecurityPolicy security_policy), (override));
   MOCK_METHOD(bool, IsFixedChannelAllocated, (Cid cid), (override));
   MOCK_METHOD(void, RefreshRefCount, (), (override));
diff --git a/gd/l2cap/classic/internal/signalling_manager.cc b/gd/l2cap/classic/internal/signalling_manager.cc
index 7398c17..a89d0ad 100644
--- a/gd/l2cap/classic/internal/signalling_manager.cc
+++ b/gd/l2cap/classic/internal/signalling_manager.cc
@@ -19,7 +19,9 @@
 #include <chrono>
 
 #include "common/bind.h"
+#include "l2cap/classic/internal/channel_configuration_state.h"
 #include "l2cap/classic/internal/link.h"
+#include "l2cap/internal/data_pipeline_manager.h"
 #include "l2cap/l2cap_packets.h"
 #include "os/log.h"
 #include "packet/raw_builder.h"
@@ -31,11 +33,13 @@
 static constexpr auto kTimeout = std::chrono::seconds(3);
 
 ClassicSignallingManager::ClassicSignallingManager(os::Handler* handler, Link* link,
+                                                   l2cap::internal::DataPipelineManager* data_pipeline_manager,
                                                    DynamicChannelServiceManagerImpl* dynamic_service_manager,
-                                                   DynamicChannelAllocator* channel_allocator,
+                                                   l2cap::internal::DynamicChannelAllocator* channel_allocator,
                                                    FixedChannelServiceManagerImpl* fixed_service_manager)
-    : handler_(handler), link_(link), dynamic_service_manager_(dynamic_service_manager),
-      channel_allocator_(channel_allocator), fixed_service_manager_(fixed_service_manager), alarm_(handler) {
+    : handler_(handler), link_(link), data_pipeline_manager_(data_pipeline_manager),
+      dynamic_service_manager_(dynamic_service_manager), channel_allocator_(channel_allocator),
+      fixed_service_manager_(fixed_service_manager), alarm_(handler) {
   ASSERT(handler_ != nullptr);
   ASSERT(link_ != nullptr);
   signalling_channel_ = link_->AllocateFixedChannel(kClassicSignallingCid, {});
@@ -147,23 +151,35 @@
   }
   send_connection_response(signal_id, remote_cid, new_channel->GetCid(), ConnectionResponseResult::SUCCESS,
                            ConnectionResponseStatus::NO_FURTHER_INFORMATION_AVAILABLE);
+  auto& configuration_state = channel_configuration_[new_channel->GetCid()];
   auto* service = dynamic_service_manager_->GetService(psm);
   auto initial_config = service->GetConfigOption();
+
+  auto mtu_configuration = std::make_unique<MtuConfigurationOption>();
+  mtu_configuration->mtu_ = initial_config.incoming_mtu;
+  configuration_state.incoming_mtu_ = initial_config.incoming_mtu;
+
+  auto fcs_option = std::make_unique<FrameCheckSequenceOption>();
+  fcs_option->fcs_type_ = FcsType::DEFAULT;
+  if (!link_->GetRemoteSupportsFcs()) {
+    fcs_option->fcs_type_ = FcsType::NO_FCS;
+    configuration_state.fcs_type_ = FcsType::NO_FCS;
+  }
+
+  auto retransmission_flow_control_configuration = std::make_unique<RetransmissionAndFlowControlConfigurationOption>();
   if (!link_->GetRemoteSupportsErtm()) {
     initial_config.channel_mode = DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC;
   }
-  auto mtu_configuration = std::make_unique<MtuConfigurationOption>();
-  mtu_configuration->mtu_ = initial_config.incoming_mtu;
-  auto fcs_option = std::make_unique<FrameCheckSequenceOption>();
-  fcs_option->fcs_type_ = FcsType::NO_FCS;
-  auto retransmission_flow_control_configuration = std::make_unique<RetransmissionAndFlowControlConfigurationOption>();
   switch (initial_config.channel_mode) {
     case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC:
       retransmission_flow_control_configuration->mode_ = RetransmissionAndFlowControlModeOption::L2CAP_BASIC;
+      configuration_state.retransmission_and_flow_control_mode_ = RetransmissionAndFlowControlModeOption::L2CAP_BASIC;
       break;
     case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION:
       retransmission_flow_control_configuration->mode_ =
           RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION;
+      configuration_state.retransmission_and_flow_control_mode_ =
+          RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION;
       // TODO: Decide where to put initial values
       retransmission_flow_control_configuration->tx_window_size_ = 10;
       retransmission_flow_control_configuration->max_transmit_ = 20;
@@ -172,9 +188,8 @@
       retransmission_flow_control_configuration->maximum_pdu_size_ = 1010;
       break;
   }
+  configuration_state.local_retransmission_and_flow_control_ = *retransmission_flow_control_configuration;
 
-  new_channel->SetRetransmissionFlowControlConfig(*retransmission_flow_control_configuration);
-  new_channel->SetIncomingMtu(initial_config.incoming_mtu);
   std::vector<std::unique_ptr<ConfigurationOption>> config;
   config.emplace_back(std::move(mtu_configuration));
   config.emplace_back(std::move(retransmission_flow_control_configuration));
@@ -211,20 +226,35 @@
     return;
   }
   alarm_.Cancel();
+
+  auto& configuration_state = channel_configuration_[new_channel->GetCid()];
   auto initial_config = link_->GetConfigurationForInitialConfiguration(new_channel->GetCid());
+
+  auto mtu_configuration = std::make_unique<MtuConfigurationOption>();
+  mtu_configuration->mtu_ = initial_config.incoming_mtu;
+  configuration_state.incoming_mtu_ = initial_config.incoming_mtu;
+
+  auto fcs_option = std::make_unique<FrameCheckSequenceOption>();
+  fcs_option->fcs_type_ = FcsType::DEFAULT;
+  if (!link_->GetRemoteSupportsFcs()) {
+    fcs_option->fcs_type_ = FcsType::NO_FCS;
+    configuration_state.fcs_type_ = FcsType::NO_FCS;
+  }
+
+  auto retransmission_flow_control_configuration = std::make_unique<RetransmissionAndFlowControlConfigurationOption>();
   if (!link_->GetRemoteSupportsErtm()) {
     initial_config.channel_mode = DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC;
   }
-  auto mtu_configuration = std::make_unique<MtuConfigurationOption>();
-  mtu_configuration->mtu_ = initial_config.incoming_mtu;
-  auto retransmission_flow_control_configuration = std::make_unique<RetransmissionAndFlowControlConfigurationOption>();
   switch (initial_config.channel_mode) {
     case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC:
       retransmission_flow_control_configuration->mode_ = RetransmissionAndFlowControlModeOption::L2CAP_BASIC;
+      configuration_state.retransmission_and_flow_control_mode_ = RetransmissionAndFlowControlModeOption::L2CAP_BASIC;
       break;
     case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION:
       retransmission_flow_control_configuration->mode_ =
           RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION;
+      configuration_state.retransmission_and_flow_control_mode_ =
+          RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION;
       // TODO: Decide where to put initial values
       retransmission_flow_control_configuration->tx_window_size_ = 10;
       retransmission_flow_control_configuration->max_transmit_ = 20;
@@ -233,11 +263,12 @@
       retransmission_flow_control_configuration->maximum_pdu_size_ = 1010;
       break;
   }
+  configuration_state.local_retransmission_and_flow_control_ = *retransmission_flow_control_configuration;
+
   std::vector<std::unique_ptr<ConfigurationOption>> config;
   config.emplace_back(std::move(mtu_configuration));
-  if (initial_config.channel_mode != DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC) {
-    config.emplace_back(std::move(retransmission_flow_control_configuration));
-  }
+  config.emplace_back(std::move(retransmission_flow_control_configuration));
+  config.emplace_back(std::move(fcs_option));
   SendConfigurationRequest(remote_cid, {});
 }
 
@@ -249,10 +280,13 @@
     return;
   }
 
+  auto& configuration_state = channel_configuration_[cid];
+
   for (auto& option : options) {
     switch (option->type_) {
       case ConfigurationOptionType::MTU: {
-        channel->SetIncomingMtu(MtuConfigurationOption::Specialize(option.get())->mtu_);
+        configuration_state.outgoing_mtu_ = MtuConfigurationOption::Specialize(option.get())->mtu_;
+        // TODO: If less than minimum (required by spec), reject
         break;
       }
       case ConfigurationOptionType::FLUSH_TIMEOUT: {
@@ -261,11 +295,11 @@
       }
       case ConfigurationOptionType::RETRANSMISSION_AND_FLOW_CONTROL: {
         auto config = RetransmissionAndFlowControlConfigurationOption::Specialize(option.get());
-        channel->SetRetransmissionFlowControlConfig(*config);
+        configuration_state.remote_retransmission_and_flow_control_ = *config;
         break;
       }
       case ConfigurationOptionType::FRAME_CHECK_SEQUENCE: {
-        channel->SetFcsType(FrameCheckSequenceOption::Specialize(option.get())->fcs_type_);
+        configuration_state.fcs_type_ = FrameCheckSequenceOption::Specialize(option.get())->fcs_type_;
         break;
       }
       default:
@@ -278,18 +312,22 @@
     }
   }
 
-  auto response = ConfigurationResponseBuilder::Create(signal_id.Value(), channel->GetRemoteCid(), is_continuation,
-                                                       ConfigurationResponseResult::SUCCESS, {});
-  enqueue_buffer_->Enqueue(std::move(response), handler_);
-  channel->SetIncomingConfigurationStatus(DynamicChannelImpl::ConfigurationStatus::CONFIGURED);
-  if (channel->GetOutgoingConfigurationStatus() == DynamicChannelImpl::ConfigurationStatus::CONFIGURED) {
+  if (configuration_state.state_ == ChannelConfigurationState::State::WAIT_CONFIG_REQ) {
     std::unique_ptr<DynamicChannel> user_channel = std::make_unique<DynamicChannel>(channel, handler_);
     if (channel->local_initiated_) {
       link_->NotifyChannelCreation(cid, std::move(user_channel));
     } else {
       dynamic_service_manager_->GetService(channel->GetPsm())->NotifyChannelCreation(std::move(user_channel));
     }
+    configuration_state.state_ = ChannelConfigurationState::State::CONFIGURED;
+    data_pipeline_manager_->UpdateClassicConfiguration(cid, configuration_state);
+  } else if (configuration_state.state_ == ChannelConfigurationState::State::WAIT_CONFIG_REQ_RSP) {
+    configuration_state.state_ = ChannelConfigurationState::State::WAIT_CONFIG_RSP;
   }
+
+  auto response = ConfigurationResponseBuilder::Create(signal_id.Value(), channel->GetRemoteCid(), is_continuation,
+                                                       ConfigurationResponseResult::SUCCESS, {});
+  enqueue_buffer_->Enqueue(std::move(response), handler_);
 }
 
 void ClassicSignallingManager::OnConfigurationResponse(SignalId signal_id, Cid cid, Continuation is_continuation,
@@ -310,15 +348,50 @@
     return;
   }
 
-  channel->SetOutgoingConfigurationStatus(DynamicChannelImpl::ConfigurationStatus::CONFIGURED);
-  if (channel->GetIncomingConfigurationStatus() == DynamicChannelImpl::ConfigurationStatus::CONFIGURED) {
+  // TODO: Handle status not SUCCESS
+
+  auto& configuration_state = channel_configuration_[channel->GetCid()];
+
+  for (auto& option : options) {
+    switch (option->type_) {
+      case ConfigurationOptionType::MTU: {
+        auto config = MtuConfigurationOption::Specialize(option.get());
+        configuration_state.incoming_mtu_ = config->mtu_;
+        break;
+      }
+      case ConfigurationOptionType::FLUSH_TIMEOUT: {
+        // TODO: Handle this configuration option
+        break;
+      }
+      case ConfigurationOptionType::RETRANSMISSION_AND_FLOW_CONTROL: {
+        auto config = RetransmissionAndFlowControlConfigurationOption::Specialize(option.get());
+        configuration_state.retransmission_and_flow_control_mode_ = config->mode_;
+        configuration_state.local_retransmission_and_flow_control_ = *config;
+        break;
+      }
+      case ConfigurationOptionType::FRAME_CHECK_SEQUENCE: {
+        configuration_state.fcs_type_ = FrameCheckSequenceOption::Specialize(option.get())->fcs_type_;
+        break;
+      }
+      default:
+        LOG_WARN("Received some unsupported configuration option: %d", static_cast<int>(option->type_));
+        return;
+    }
+  }
+
+  if (configuration_state.state_ == ChannelConfigurationState::State::WAIT_CONFIG_RSP) {
     std::unique_ptr<DynamicChannel> user_channel = std::make_unique<DynamicChannel>(channel, handler_);
     if (channel->local_initiated_) {
       link_->NotifyChannelCreation(cid, std::move(user_channel));
     } else {
       dynamic_service_manager_->GetService(channel->GetPsm())->NotifyChannelCreation(std::move(user_channel));
     }
+    configuration_state.state_ = ChannelConfigurationState::State::CONFIGURED;
+    data_pipeline_manager_->UpdateClassicConfiguration(cid, configuration_state);
+  } else if (configuration_state.state_ == ChannelConfigurationState::State::WAIT_CONFIG_REQ_RSP) {
+    configuration_state.state_ = ChannelConfigurationState::State::WAIT_CONFIG_REQ;
   }
+
   alarm_.Cancel();
   handle_send_next_command();
 }
diff --git a/gd/l2cap/classic/internal/signalling_manager.h b/gd/l2cap/classic/internal/signalling_manager.h
index 0e17ec7..81c8c31 100644
--- a/gd/l2cap/classic/internal/signalling_manager.h
+++ b/gd/l2cap/classic/internal/signalling_manager.h
@@ -21,10 +21,12 @@
 #include <vector>
 
 #include "l2cap/cid.h"
-#include "l2cap/classic/internal/dynamic_channel_allocator.h"
+#include "l2cap/classic/internal/channel_configuration_state.h"
 #include "l2cap/classic/internal/dynamic_channel_service_manager_impl.h"
 #include "l2cap/classic/internal/fixed_channel_impl.h"
 #include "l2cap/classic/internal/fixed_channel_service_manager_impl.h"
+#include "l2cap/internal/data_pipeline_manager.h"
+#include "l2cap/internal/dynamic_channel_allocator.h"
 #include "l2cap/l2cap_packets.h"
 #include "l2cap/psm.h"
 #include "l2cap/signal_id.h"
@@ -53,8 +55,9 @@
 class ClassicSignallingManager {
  public:
   ClassicSignallingManager(os::Handler* handler, Link* link,
+                           l2cap::internal::DataPipelineManager* data_pipeline_manager,
                            classic::internal::DynamicChannelServiceManagerImpl* dynamic_service_manager,
-                           classic::internal::DynamicChannelAllocator* channel_allocator,
+                           l2cap::internal::DynamicChannelAllocator* channel_allocator,
                            classic::internal::FixedChannelServiceManagerImpl* fixed_service_manager);
 
   virtual ~ClassicSignallingManager();
@@ -103,15 +106,17 @@
 
   os::Handler* handler_;
   Link* link_;
+  [[maybe_unused]] l2cap::internal::DataPipelineManager* data_pipeline_manager_;
   std::shared_ptr<classic::internal::FixedChannelImpl> signalling_channel_;
   DynamicChannelServiceManagerImpl* dynamic_service_manager_;
-  DynamicChannelAllocator* channel_allocator_;
+  l2cap::internal::DynamicChannelAllocator* channel_allocator_;
   FixedChannelServiceManagerImpl* fixed_service_manager_;
   std::unique_ptr<os::EnqueueBuffer<packet::BasePacketBuilder>> enqueue_buffer_;
   PendingCommand last_sent_command_;
   std::queue<PendingCommand> pending_commands_;
   os::Alarm alarm_;
   SignalId next_signal_id_ = kInitialSignalId;
+  std::unordered_map<Cid, ChannelConfigurationState> channel_configuration_;
 };
 
 }  // namespace internal
diff --git a/gd/l2cap/classic/dynamic_channel.cc b/gd/l2cap/dynamic_channel.cc
similarity index 73%
rename from gd/l2cap/classic/dynamic_channel.cc
rename to gd/l2cap/dynamic_channel.cc
index b888b91..f8b64e6 100644
--- a/gd/l2cap/classic/dynamic_channel.cc
+++ b/gd/l2cap/dynamic_channel.cc
@@ -14,13 +14,12 @@
  * limitations under the License.
  */
 
-#include "l2cap/classic/dynamic_channel.h"
+#include "l2cap/dynamic_channel.h"
 #include "common/bind.h"
-#include "l2cap/classic/internal/dynamic_channel_impl.h"
+#include "l2cap/internal/dynamic_channel_impl.h"
 
 namespace bluetooth {
 namespace l2cap {
-namespace classic {
 
 hci::Address DynamicChannel::GetDevice() const {
   return impl_->GetDevice();
@@ -28,18 +27,17 @@
 
 void DynamicChannel::RegisterOnCloseCallback(os::Handler* user_handler,
                                              DynamicChannel::OnCloseCallback on_close_callback) {
-  l2cap_handler_->Post(common::BindOnce(&internal::DynamicChannelImpl::RegisterOnCloseCallback, impl_, user_handler,
-                                        std::move(on_close_callback)));
+  l2cap_handler_->Post(common::BindOnce(&l2cap::internal::DynamicChannelImpl::RegisterOnCloseCallback, impl_,
+                                        user_handler, std::move(on_close_callback)));
 }
 
 void DynamicChannel::Close() {
-  l2cap_handler_->Post(common::BindOnce(&internal::DynamicChannelImpl::Close, impl_));
+  l2cap_handler_->Post(common::BindOnce(&l2cap::internal::DynamicChannelImpl::Close, impl_));
 }
 
 common::BidiQueueEnd<packet::BasePacketBuilder, packet::PacketView<packet::kLittleEndian>>*
 DynamicChannel::GetQueueUpEnd() const {
   return impl_->GetQueueUpEnd();
 }
-}  // namespace classic
 }  // namespace l2cap
 }  // namespace bluetooth
\ No newline at end of file
diff --git a/gd/l2cap/classic/dynamic_channel.h b/gd/l2cap/dynamic_channel.h
similarity index 92%
rename from gd/l2cap/classic/dynamic_channel.h
rename to gd/l2cap/dynamic_channel.h
index eb52c16..b7496f8 100644
--- a/gd/l2cap/classic/dynamic_channel.h
+++ b/gd/l2cap/dynamic_channel.h
@@ -24,7 +24,6 @@
 
 namespace bluetooth {
 namespace l2cap {
-namespace classic {
 
 namespace internal {
 class DynamicChannelImpl;
@@ -37,7 +36,7 @@
 class DynamicChannel {
  public:
   // Should only be constructed by modules that have access to LinkManager
-  DynamicChannel(std::shared_ptr<internal::DynamicChannelImpl> impl, os::Handler* l2cap_handler)
+  DynamicChannel(std::shared_ptr<l2cap::internal::DynamicChannelImpl> impl, os::Handler* l2cap_handler)
       : impl_(std::move(impl)), l2cap_handler_(l2cap_handler) {
     ASSERT(impl_ != nullptr);
     ASSERT(l2cap_handler_ != nullptr);
@@ -72,10 +71,9 @@
   common::BidiQueueEnd<packet::BasePacketBuilder, packet::PacketView<packet::kLittleEndian>>* GetQueueUpEnd() const;
 
  private:
-  std::shared_ptr<internal::DynamicChannelImpl> impl_;
+  std::shared_ptr<l2cap::internal::DynamicChannelImpl> impl_;
   os::Handler* l2cap_handler_;
 };
 
-}  // namespace classic
 }  // namespace l2cap
 }  // namespace bluetooth
diff --git a/gd/l2cap/internal/channel_impl.h b/gd/l2cap/internal/channel_impl.h
index ae17660..427a15f 100644
--- a/gd/l2cap/internal/channel_impl.h
+++ b/gd/l2cap/internal/channel_impl.h
@@ -47,13 +47,6 @@
   virtual Cid GetCid() const = 0;
 
   virtual Cid GetRemoteCid() const = 0;
-
-  /**
-   * Callback from the Scheduler to notify the Sender for this channel. On config update, channel might notify the
-   * configuration change to Sender.
-   * Fixed channel doesn't need to implement it, as it doesn't need to send config update to Sender.
-   */
-  virtual void SetSender(l2cap::internal::Sender* sender) = 0;
 };
 
 }  // namespace internal
diff --git a/gd/l2cap/internal/channel_impl_mock.h b/gd/l2cap/internal/channel_impl_mock.h
index 710e69a..4430487 100644
--- a/gd/l2cap/internal/channel_impl_mock.h
+++ b/gd/l2cap/internal/channel_impl_mock.h
@@ -34,7 +34,6 @@
               GetQueueDownEnd, (), (override));
   MOCK_METHOD(Cid, GetCid, (), (const, override));
   MOCK_METHOD(Cid, GetRemoteCid, (), (const, override));
-  MOCK_METHOD(void, SetSender, (l2cap::internal::Sender*), (override));
 };
 
 }  // namespace testing
diff --git a/gd/l2cap/internal/data_pipeline_manager.cc b/gd/l2cap/internal/data_pipeline_manager.cc
index d0023c0..1c8d973 100644
--- a/gd/l2cap/internal/data_pipeline_manager.cc
+++ b/gd/l2cap/internal/data_pipeline_manager.cc
@@ -30,9 +30,6 @@
   ASSERT(sender_map_.find(cid) == sender_map_.end());
   sender_map_.emplace(std::piecewise_construct, std::forward_as_tuple(cid),
                       std::forward_as_tuple(handler_, scheduler_.get(), channel));
-  if (channel->GetCid() >= kFirstDynamicChannel) {
-    channel->SetSender(&sender_map_.find(cid)->second);
-  }
 }
 
 void DataPipelineManager::DetachChannel(Cid cid) {
@@ -50,6 +47,11 @@
   sender_map_.find(cid)->second.OnPacketSent();
 }
 
+void DataPipelineManager::UpdateClassicConfiguration(Cid cid, classic::internal::ChannelConfigurationState config) {
+  ASSERT(sender_map_.find(cid) != sender_map_.end());
+  sender_map_.find(cid)->second.UpdateClassicConfiguration(config);
+}
+
 }  // namespace internal
 }  // namespace l2cap
 }  // namespace bluetooth
diff --git a/gd/l2cap/internal/data_pipeline_manager.h b/gd/l2cap/internal/data_pipeline_manager.h
index f801297..fffbfc7 100644
--- a/gd/l2cap/internal/data_pipeline_manager.h
+++ b/gd/l2cap/internal/data_pipeline_manager.h
@@ -23,6 +23,7 @@
 #include "common/bind.h"
 #include "data_controller.h"
 #include "l2cap/cid.h"
+#include "l2cap/classic/internal/channel_configuration_state.h"
 #include "l2cap/internal/channel_impl.h"
 #include "l2cap/internal/receiver.h"
 #include "l2cap/internal/scheduler.h"
@@ -61,6 +62,7 @@
   virtual void DetachChannel(Cid cid);
   virtual DataController* GetDataController(Cid cid);
   virtual void OnPacketSent(Cid cid);
+  virtual void UpdateClassicConfiguration(Cid cid, classic::internal::ChannelConfigurationState config);
   virtual ~DataPipelineManager() = default;
 
  private:
diff --git a/gd/l2cap/classic/internal/dynamic_channel_allocator.cc b/gd/l2cap/internal/dynamic_channel_allocator.cc
similarity index 97%
rename from gd/l2cap/classic/internal/dynamic_channel_allocator.cc
rename to gd/l2cap/internal/dynamic_channel_allocator.cc
index 95830e0..6f00274 100644
--- a/gd/l2cap/classic/internal/dynamic_channel_allocator.cc
+++ b/gd/l2cap/internal/dynamic_channel_allocator.cc
@@ -17,15 +17,14 @@
 #include <unordered_map>
 
 #include "l2cap/cid.h"
-#include "l2cap/classic/internal/dynamic_channel_allocator.h"
 #include "l2cap/classic/internal/link.h"
+#include "l2cap/internal/dynamic_channel_allocator.h"
+#include "l2cap/internal/dynamic_channel_impl.h"
 #include "l2cap/security_policy.h"
-#include "os/handler.h"
 #include "os/log.h"
 
 namespace bluetooth {
 namespace l2cap {
-namespace classic {
 namespace internal {
 
 std::shared_ptr<DynamicChannelImpl> DynamicChannelAllocator::AllocateChannel(Psm psm, Cid remote_cid,
@@ -135,6 +134,5 @@
 }
 
 }  // namespace internal
-}  // namespace classic
 }  // namespace l2cap
 }  // namespace bluetooth
diff --git a/gd/l2cap/classic/internal/dynamic_channel_allocator.h b/gd/l2cap/internal/dynamic_channel_allocator.h
similarity index 90%
rename from gd/l2cap/classic/internal/dynamic_channel_allocator.h
rename to gd/l2cap/internal/dynamic_channel_allocator.h
index 57e0f90..09a3588 100644
--- a/gd/l2cap/classic/internal/dynamic_channel_allocator.h
+++ b/gd/l2cap/internal/dynamic_channel_allocator.h
@@ -19,8 +19,9 @@
 #include <unordered_map>
 #include <unordered_set>
 
+#include "hci/acl_manager.h"
 #include "l2cap/cid.h"
-#include "l2cap/classic/internal/dynamic_channel_impl.h"
+#include "l2cap/internal/ilink.h"
 #include "l2cap/psm.h"
 #include "l2cap/security_policy.h"
 #include "os/handler.h"
@@ -28,16 +29,16 @@
 
 namespace bluetooth {
 namespace l2cap {
-namespace classic {
 namespace internal {
 
-class Link;
+class DynamicChannelImpl;
 
 // Helper class for keeping channels in a Link. It allocates and frees Channel object, and supports querying whether a
 // channel is in use
 class DynamicChannelAllocator {
  public:
-  DynamicChannelAllocator(Link* link, os::Handler* l2cap_handler) : link_(link), l2cap_handler_(l2cap_handler) {
+  DynamicChannelAllocator(l2cap::internal::ILink* link, os::Handler* l2cap_handler)
+      : link_(link), l2cap_handler_(l2cap_handler) {
     ASSERT(link_ != nullptr);
     ASSERT(l2cap_handler_ != nullptr);
   }
@@ -67,7 +68,7 @@
   void OnAclDisconnected(hci::ErrorCode hci_status);
 
  private:
-  Link* link_;
+  l2cap::internal::ILink* link_;
   os::Handler* l2cap_handler_;
   std::unordered_set<Cid> used_cid_;
   std::unordered_map<Cid, std::shared_ptr<DynamicChannelImpl>> channels_;
@@ -75,6 +76,5 @@
 };
 
 }  // namespace internal
-}  // namespace classic
 }  // namespace l2cap
 }  // namespace bluetooth
diff --git a/gd/l2cap/classic/internal/dynamic_channel_allocator_fuzz_test.cc b/gd/l2cap/internal/dynamic_channel_allocator_fuzz_test.cc
similarity index 89%
rename from gd/l2cap/classic/internal/dynamic_channel_allocator_fuzz_test.cc
rename to gd/l2cap/internal/dynamic_channel_allocator_fuzz_test.cc
index 48d9121..c3821dc 100644
--- a/gd/l2cap/classic/internal/dynamic_channel_allocator_fuzz_test.cc
+++ b/gd/l2cap/internal/dynamic_channel_allocator_fuzz_test.cc
@@ -14,25 +14,24 @@
  * limitations under the License.
  */
 
-#include "l2cap/classic/internal/dynamic_channel_allocator.h"
 #include "l2cap/classic/internal/link_mock.h"
+#include "l2cap/internal/dynamic_channel_allocator.h"
 #include "l2cap/internal/parameter_provider_mock.h"
 
 #include <gmock/gmock.h>
 
 namespace bluetooth {
 namespace l2cap {
-namespace classic {
 namespace internal {
 
+using classic::internal::testing::MockLink;
 using hci::testing::MockAclConnection;
 using l2cap::internal::testing::MockParameterProvider;
 using l2cap::internal::testing::MockScheduler;
-using testing::MockLink;
 using ::testing::NiceMock;
 using ::testing::Return;
 
-const hci::Address device{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}};
+const hci::AddressWithType device{{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}}, hci::AddressType::PUBLIC_IDENTITY_ADDRESS};
 
 class L2capClassicDynamicChannelAllocatorFuzzTest {
  public:
@@ -78,11 +77,10 @@
 };
 
 }  // namespace internal
-}  // namespace classic
 }  // namespace l2cap
 }  // namespace bluetooth
 
 void RunL2capClassicDynamicChannelAllocatorFuzzTest(const uint8_t* data, size_t size) {
-  bluetooth::l2cap::classic::internal::L2capClassicDynamicChannelAllocatorFuzzTest test;
+  bluetooth::l2cap::internal::L2capClassicDynamicChannelAllocatorFuzzTest test;
   test.RunTests(data, size);
 }
\ No newline at end of file
diff --git a/gd/l2cap/classic/internal/dynamic_channel_allocator_test.cc b/gd/l2cap/internal/dynamic_channel_allocator_test.cc
similarity index 93%
rename from gd/l2cap/classic/internal/dynamic_channel_allocator_test.cc
rename to gd/l2cap/internal/dynamic_channel_allocator_test.cc
index 8e3f66b..4fc0160 100644
--- a/gd/l2cap/classic/internal/dynamic_channel_allocator_test.cc
+++ b/gd/l2cap/internal/dynamic_channel_allocator_test.cc
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "l2cap/classic/internal/dynamic_channel_allocator.h"
+#include "l2cap/internal/dynamic_channel_allocator.h"
 #include "l2cap/classic/internal/link_mock.h"
 #include "l2cap/internal/parameter_provider_mock.h"
 
@@ -23,14 +23,13 @@
 
 namespace bluetooth {
 namespace l2cap {
-namespace classic {
 namespace internal {
 
+using classic::internal::testing::MockLink;
 using l2cap::internal::testing::MockParameterProvider;
-using testing::MockLink;
 using ::testing::Return;
 
-const hci::Address device{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}};
+const hci::AddressWithType device{{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}}, hci::AddressType::PUBLIC_IDENTITY_ADDRESS};
 
 class L2capClassicDynamicChannelAllocatorTest : public ::testing::Test {
  protected:
@@ -89,6 +88,5 @@
 }
 
 }  // namespace internal
-}  // namespace classic
 }  // namespace l2cap
 }  // namespace bluetooth
diff --git a/gd/l2cap/classic/internal/dynamic_channel_impl.cc b/gd/l2cap/internal/dynamic_channel_impl.cc
similarity index 70%
rename from gd/l2cap/classic/internal/dynamic_channel_impl.cc
rename to gd/l2cap/internal/dynamic_channel_impl.cc
index c0614f9..947a32f 100644
--- a/gd/l2cap/classic/internal/dynamic_channel_impl.cc
+++ b/gd/l2cap/internal/dynamic_channel_impl.cc
@@ -17,8 +17,8 @@
 #include <unordered_map>
 
 #include "l2cap/cid.h"
-#include "l2cap/classic/internal/dynamic_channel_impl.h"
 #include "l2cap/classic/internal/link.h"
+#include "l2cap/internal/dynamic_channel_impl.h"
 #include "l2cap/internal/sender.h"
 #include "l2cap/psm.h"
 #include "l2cap/security_policy.h"
@@ -27,10 +27,10 @@
 
 namespace bluetooth {
 namespace l2cap {
-namespace classic {
 namespace internal {
 
-DynamicChannelImpl::DynamicChannelImpl(Psm psm, Cid cid, Cid remote_cid, Link* link, os::Handler* l2cap_handler)
+DynamicChannelImpl::DynamicChannelImpl(Psm psm, Cid cid, Cid remote_cid, l2cap::internal::ILink* link,
+                                       os::Handler* l2cap_handler)
     : psm_(psm), cid_(cid), remote_cid_(remote_cid), link_(link), l2cap_handler_(l2cap_handler),
       device_(link->GetDevice()) {
   ASSERT(IsPsmValid(psm_));
@@ -41,7 +41,7 @@
 }
 
 hci::Address DynamicChannelImpl::GetDevice() const {
-  return device_;
+  return device_.GetAddress();
 }
 
 void DynamicChannelImpl::RegisterOnCloseCallback(os::Handler* user_handler,
@@ -82,40 +82,6 @@
   return ss.str();
 }
 
-DynamicChannelImpl::ConfigurationStatus DynamicChannelImpl::GetOutgoingConfigurationStatus() const {
-  return outgoing_configuration_status_;
-}
-
-void DynamicChannelImpl::SetOutgoingConfigurationStatus(ConfigurationStatus status) {
-  outgoing_configuration_status_ = status;
-}
-
-DynamicChannelImpl::ConfigurationStatus DynamicChannelImpl::GetIncomingConfigurationStatus() const {
-  return incoming_configuration_status_;
-}
-
-void DynamicChannelImpl::SetIncomingConfigurationStatus(ConfigurationStatus status) {
-  incoming_configuration_status_ = status;
-}
-
-void DynamicChannelImpl::SetSender(l2cap::internal::Sender* sender) {
-  sender_ = sender;
-}
-
-void DynamicChannelImpl::SetIncomingMtu(Mtu mtu) {
-  sender_->SetIncomingMtu(mtu);
-}
-
-void DynamicChannelImpl::SetRetransmissionFlowControlConfig(
-    const RetransmissionAndFlowControlConfigurationOption& option) {
-  sender_->SetChannelRetransmissionFlowControlMode(option);
-}
-
-void DynamicChannelImpl::SetFcsType(FcsType fcs_type) {
-  sender_->SetFcsType(fcs_type);
-}
-
 }  // namespace internal
-}  // namespace classic
 }  // namespace l2cap
 }  // namespace bluetooth
diff --git a/gd/l2cap/classic/internal/dynamic_channel_impl.h b/gd/l2cap/internal/dynamic_channel_impl.h
similarity index 67%
rename from gd/l2cap/classic/internal/dynamic_channel_impl.h
rename to gd/l2cap/internal/dynamic_channel_impl.h
index 95be5c7..856e21d 100644
--- a/gd/l2cap/classic/internal/dynamic_channel_impl.h
+++ b/gd/l2cap/internal/dynamic_channel_impl.h
@@ -19,8 +19,9 @@
 #include "common/bidi_queue.h"
 #include "hci/address.h"
 #include "l2cap/cid.h"
-#include "l2cap/classic/dynamic_channel.h"
+#include "l2cap/dynamic_channel.h"
 #include "l2cap/internal/channel_impl.h"
+#include "l2cap/internal/ilink.h"
 #include "l2cap/l2cap_packets.h"
 #include "l2cap/mtu.h"
 #include "l2cap/psm.h"
@@ -29,14 +30,11 @@
 
 namespace bluetooth {
 namespace l2cap {
-namespace classic {
 namespace internal {
 
-class Link;
-
 class DynamicChannelImpl : public l2cap::internal::ChannelImpl {
  public:
-  DynamicChannelImpl(Psm psm, Cid cid, Cid remote_cid, Link* link, os::Handler* l2cap_handler);
+  DynamicChannelImpl(Psm psm, Cid cid, Cid remote_cid, l2cap::internal::ILink* link, os::Handler* l2cap_handler);
 
   virtual ~DynamicChannelImpl() = default;
 
@@ -68,26 +66,6 @@
     return psm_;
   }
 
-  enum class ConfigurationStatus { NOT_CONFIGURED, CONFIGURED };
-
-  virtual ConfigurationStatus GetOutgoingConfigurationStatus() const;
-  virtual void SetOutgoingConfigurationStatus(ConfigurationStatus status);
-
-  virtual ConfigurationStatus GetIncomingConfigurationStatus() const;
-  virtual void SetIncomingConfigurationStatus(ConfigurationStatus status);
-
-  /**
-   * Callback from the Scheduler to notify the Sender for this channel. On config update, channel might notify the
-   * configuration to Sender
-   */
-  void SetSender(l2cap::internal::Sender* sender) override;
-
-  virtual void SetIncomingMtu(Mtu mtu);
-
-  virtual void SetRetransmissionFlowControlConfig(const RetransmissionAndFlowControlConfigurationOption& mode);
-
-  virtual void SetFcsType(FcsType fcs_type);
-
   // TODO(cmanton) Do something a little bit better than this
   bool local_initiated_{false};
 
@@ -95,9 +73,9 @@
   const Psm psm_;
   const Cid cid_;
   const Cid remote_cid_;
-  Link* link_;
+  l2cap::internal::ILink* link_;
   os::Handler* l2cap_handler_;
-  const hci::Address device_;
+  const hci::AddressWithType device_;
 
   // User supported states
   os::Handler* user_handler_ = nullptr;
@@ -109,15 +87,10 @@
   static constexpr size_t kChannelQueueSize = 10;
   common::BidiQueue<packet::PacketView<packet::kLittleEndian>, packet::BasePacketBuilder> channel_queue_{
       kChannelQueueSize};
-  ConfigurationStatus outgoing_configuration_status_ = ConfigurationStatus::NOT_CONFIGURED;
-  ConfigurationStatus incoming_configuration_status_ = ConfigurationStatus::NOT_CONFIGURED;
-
-  l2cap::internal::Sender* sender_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(DynamicChannelImpl);
 };
 
 }  // namespace internal
-}  // namespace classic
 }  // namespace l2cap
 }  // namespace bluetooth
diff --git a/gd/l2cap/classic/internal/dynamic_channel_impl_test.cc b/gd/l2cap/internal/dynamic_channel_impl_test.cc
similarity index 89%
rename from gd/l2cap/classic/internal/dynamic_channel_impl_test.cc
rename to gd/l2cap/internal/dynamic_channel_impl_test.cc
index 2f6c649..677b504 100644
--- a/gd/l2cap/classic/internal/dynamic_channel_impl_test.cc
+++ b/gd/l2cap/internal/dynamic_channel_impl_test.cc
@@ -13,7 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include "l2cap/classic/internal/dynamic_channel_impl.h"
+
+#include "l2cap/internal/dynamic_channel_impl.h"
 
 #include "common/testing/bind_test_util.h"
 #include "l2cap/cid.h"
@@ -26,11 +27,10 @@
 
 namespace bluetooth {
 namespace l2cap {
-namespace classic {
 namespace internal {
 
+using classic::internal::testing::MockLink;
 using l2cap::internal::testing::MockParameterProvider;
-using testing::MockLink;
 using ::testing::Return;
 
 class L2capClassicDynamicChannelImplTest : public ::testing::Test {
@@ -61,17 +61,17 @@
 TEST_F(L2capClassicDynamicChannelImplTest, get_device) {
   MockParameterProvider mock_parameter_provider;
   MockLink mock_classic_link(l2cap_handler_, &mock_parameter_provider);
-  hci::Address device{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}};
+  const hci::AddressWithType device{{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}}, hci::AddressType::PUBLIC_IDENTITY_ADDRESS};
   EXPECT_CALL(mock_classic_link, GetDevice()).WillRepeatedly(Return(device));
   DynamicChannelImpl dynamic_channel_impl(0x01, kFirstDynamicChannel, kFirstDynamicChannel, &mock_classic_link,
                                           l2cap_handler_);
-  EXPECT_EQ(device, dynamic_channel_impl.GetDevice());
+  EXPECT_EQ(device.GetAddress(), dynamic_channel_impl.GetDevice());
 }
 
 TEST_F(L2capClassicDynamicChannelImplTest, close_triggers_callback) {
   MockParameterProvider mock_parameter_provider;
   MockLink mock_classic_link(l2cap_handler_, &mock_parameter_provider);
-  hci::Address device{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}};
+  const hci::AddressWithType device{{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}}, hci::AddressType::PUBLIC_IDENTITY_ADDRESS};
   EXPECT_CALL(mock_classic_link, GetDevice()).WillRepeatedly(Return(device));
   DynamicChannelImpl dynamic_channel_impl(0x01, kFirstDynamicChannel, kFirstDynamicChannel, &mock_classic_link,
                                           l2cap_handler_);
@@ -93,7 +93,7 @@
 TEST_F(L2capClassicDynamicChannelImplTest, register_callback_after_close_should_call_immediately) {
   MockParameterProvider mock_parameter_provider;
   MockLink mock_classic_link(l2cap_handler_, &mock_parameter_provider);
-  hci::Address device{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}};
+  const hci::AddressWithType device{{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}}, hci::AddressType::PUBLIC_IDENTITY_ADDRESS};
   EXPECT_CALL(mock_classic_link, GetDevice()).WillRepeatedly(Return(device));
   DynamicChannelImpl dynamic_channel_impl(0x01, kFirstDynamicChannel, kFirstDynamicChannel, &mock_classic_link,
                                           l2cap_handler_);
@@ -115,7 +115,7 @@
 TEST_F(L2capClassicDynamicChannelImplTest, close_twice_should_fail) {
   MockParameterProvider mock_parameter_provider;
   MockLink mock_classic_link(l2cap_handler_, &mock_parameter_provider);
-  hci::Address device{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}};
+  const hci::AddressWithType device{{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}}, hci::AddressType::PUBLIC_IDENTITY_ADDRESS};
   EXPECT_CALL(mock_classic_link, GetDevice()).WillRepeatedly(Return(device));
   DynamicChannelImpl dynamic_channel_impl(0x01, kFirstDynamicChannel, kFirstDynamicChannel, &mock_classic_link,
                                           l2cap_handler_);
@@ -140,7 +140,7 @@
 TEST_F(L2capClassicDynamicChannelImplTest, multiple_registeration_should_fail) {
   MockParameterProvider mock_parameter_provider;
   MockLink mock_classic_link(l2cap_handler_, &mock_parameter_provider);
-  hci::Address device{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}};
+  const hci::AddressWithType device{{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}}, hci::AddressType::PUBLIC_IDENTITY_ADDRESS};
   EXPECT_CALL(mock_classic_link, GetDevice()).WillRepeatedly(Return(device));
   DynamicChannelImpl dynamic_channel_impl(0x01, kFirstDynamicChannel, kFirstDynamicChannel, &mock_classic_link,
                                           l2cap_handler_);
@@ -159,6 +159,5 @@
 }
 
 }  // namespace internal
-}  // namespace classic
 }  // namespace l2cap
 }  // namespace bluetooth
diff --git a/gd/l2cap/internal/fixed_channel_allocator_test.cc b/gd/l2cap/internal/fixed_channel_allocator_test.cc
index 2162d36..38eac13 100644
--- a/gd/l2cap/internal/fixed_channel_allocator_test.cc
+++ b/gd/l2cap/internal/fixed_channel_allocator_test.cc
@@ -31,7 +31,7 @@
 using testing::MockParameterProvider;
 using ::testing::Return;
 
-const hci::Address device{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}};
+const hci::AddressWithType device{{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}}, hci::AddressType::PUBLIC_IDENTITY_ADDRESS};
 
 class L2capFixedChannelAllocatorTest : public ::testing::Test {
  protected:
diff --git a/gd/l2cap/internal/ilink.h b/gd/l2cap/internal/ilink.h
new file mode 100644
index 0000000..4f0b6f6
--- /dev/null
+++ b/gd/l2cap/internal/ilink.h
@@ -0,0 +1,37 @@
+/*
+ * 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/address_with_type.h"
+#include "l2cap/cid.h"
+
+namespace bluetooth {
+namespace l2cap {
+namespace internal {
+
+/**
+ * Common interface for link (Classic ACL and LE)
+ */
+class ILink {
+ public:
+  virtual void SendDisconnectionRequest(Cid local_cid, Cid remote_cid) = 0;
+  virtual ~ILink() = default;
+  virtual hci::AddressWithType GetDevice() = 0;
+};
+}  // namespace internal
+}  // namespace l2cap
+}  // namespace bluetooth
diff --git a/gd/l2cap/internal/scheduler_fifo.cc b/gd/l2cap/internal/scheduler_fifo.cc
index 5e89c01..a19b7a1 100644
--- a/gd/l2cap/internal/scheduler_fifo.cc
+++ b/gd/l2cap/internal/scheduler_fifo.cc
@@ -16,7 +16,7 @@
 
 #include "l2cap/internal/scheduler_fifo.h"
 
-#include "l2cap/classic/internal/dynamic_channel_impl.h"
+#include "dynamic_channel_impl.h"
 #include "l2cap/internal/data_pipeline_manager.h"
 #include "l2cap/l2cap_packets.h"
 #include "os/log.h"
diff --git a/gd/l2cap/internal/sender.cc b/gd/l2cap/internal/sender.cc
index 7fe1dd7..1c146cf 100644
--- a/gd/l2cap/internal/sender.cc
+++ b/gd/l2cap/internal/sender.cc
@@ -14,20 +14,15 @@
  * limitations under the License.
  */
 
-#include <string>
 #include <unordered_map>
 
 #include "common/bind.h"
-#include "l2cap/cid.h"
-#include "l2cap/classic/internal/dynamic_channel_impl.h"
 #include "l2cap/internal/basic_mode_channel_data_controller.h"
 #include "l2cap/internal/enhanced_retransmission_mode_channel_data_controller.h"
 #include "l2cap/internal/scheduler.h"
 #include "l2cap/internal/sender.h"
 #include "os/handler.h"
 #include "os/log.h"
-#include "os/queue.h"
-#include "packet/base_packet_builder.h"
 
 namespace bluetooth {
 namespace l2cap {
@@ -55,32 +50,6 @@
   return data_controller_->GetNextPacket();
 }
 
-void Sender::SetChannelRetransmissionFlowControlMode(const RetransmissionAndFlowControlConfigurationOption& option) {
-  if (mode_ == option.mode_) {
-    return;
-  }
-  if (option.mode_ == RetransmissionAndFlowControlModeOption::L2CAP_BASIC) {
-    data_controller_ =
-        std::make_unique<BasicModeDataController>(channel_id_, remote_channel_id_, queue_end_, handler_, scheduler_);
-    return;
-  }
-  if (option.mode_ == RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION) {
-    data_controller_ =
-        std::make_unique<ErtmController>(channel_id_, remote_channel_id_, queue_end_, handler_, scheduler_);
-    data_controller_->SetRetransmissionAndFlowControlOptions(option);
-    return;
-  }
-}
-
-void Sender::SetFcsType(FcsType fcs_type) {
-  // TODO: FCS is enabled when "not both side explicitly disable it".
-  data_controller_->EnableFcs(fcs_type == FcsType::DEFAULT);
-}
-
-void Sender::SetIncomingMtu(Mtu mtu) {
-  // TODO: Enforce MTU
-}
-
 DataController* Sender::GetDataController() {
   return data_controller_.get();
 }
@@ -101,6 +70,25 @@
   is_dequeue_registered_ = false;
 }
 
+void Sender::UpdateClassicConfiguration(classic::internal::ChannelConfigurationState config) {
+  auto mode = config.retransmission_and_flow_control_mode_;
+  if (mode == mode_) {
+    return;
+  }
+  if (mode == RetransmissionAndFlowControlModeOption::L2CAP_BASIC) {
+    data_controller_ =
+        std::make_unique<BasicModeDataController>(channel_id_, remote_channel_id_, queue_end_, handler_, scheduler_);
+    return;
+  }
+  if (mode == RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION) {
+    data_controller_ =
+        std::make_unique<ErtmController>(channel_id_, remote_channel_id_, queue_end_, handler_, scheduler_);
+    data_controller_->SetRetransmissionAndFlowControlOptions(config.local_retransmission_and_flow_control_);
+    data_controller_->EnableFcs(config.fcs_type_ == FcsType::DEFAULT);
+    return;
+  }
+}
+
 }  // namespace internal
 }  // namespace l2cap
 }  // namespace bluetooth
diff --git a/gd/l2cap/internal/sender.h b/gd/l2cap/internal/sender.h
index 850a88d..46e0006 100644
--- a/gd/l2cap/internal/sender.h
+++ b/gd/l2cap/internal/sender.h
@@ -23,6 +23,7 @@
 #include "common/bind.h"
 #include "data_controller.h"
 #include "l2cap/cid.h"
+#include "l2cap/classic/internal/channel_configuration_state.h"
 #include "l2cap/internal/channel_impl.h"
 #include "l2cap/internal/data_controller.h"
 #include "l2cap/l2cap_packets.h"
@@ -61,10 +62,7 @@
    */
   std::unique_ptr<UpperDequeue> GetNextPacket();
 
-  void SetChannelRetransmissionFlowControlMode(const RetransmissionAndFlowControlConfigurationOption& option);
-  void SetFcsType(FcsType fcs_type);
-  void SetIncomingMtu(Mtu mtu);
-
+  void UpdateClassicConfiguration(classic::internal::ChannelConfigurationState config);
   DataController* GetDataController();
 
  private:
diff --git a/gd/l2cap/le/internal/fixed_channel_impl.cc b/gd/l2cap/le/internal/fixed_channel_impl.cc
index 9ae4e1f..e09b80d 100644
--- a/gd/l2cap/le/internal/fixed_channel_impl.cc
+++ b/gd/l2cap/le/internal/fixed_channel_impl.cc
@@ -107,10 +107,6 @@
   return cid_;
 }
 
-void FixedChannelImpl::SetSender(l2cap::internal::Sender* sender) {
-  ASSERT_LOG(false, "Should not set sender for fixed channel");
-}
-
 }  // namespace internal
 }  // namespace le
 }  // namespace l2cap
diff --git a/gd/l2cap/le/internal/fixed_channel_impl.h b/gd/l2cap/le/internal/fixed_channel_impl.h
index 82a4125..5d6a11d 100644
--- a/gd/l2cap/le/internal/fixed_channel_impl.h
+++ b/gd/l2cap/le/internal/fixed_channel_impl.h
@@ -55,7 +55,6 @@
 
   Cid GetCid() const override;
   Cid GetRemoteCid() const override;
-  void SetSender(l2cap::internal::Sender* sender) override;
   virtual void OnClosed(hci::ErrorCode status);
 
   virtual std::string ToString() {
diff --git a/gd/l2cap/le/internal/link.h b/gd/l2cap/le/internal/link.h
index 3e75da6..2807353 100644
--- a/gd/l2cap/le/internal/link.h
+++ b/gd/l2cap/le/internal/link.h
@@ -22,6 +22,7 @@
 #include "hci/acl_manager.h"
 #include "l2cap/internal/data_pipeline_manager.h"
 #include "l2cap/internal/fixed_channel_allocator.h"
+#include "l2cap/internal/ilink.h"
 #include "l2cap/internal/parameter_provider.h"
 #include "l2cap/le/internal/fixed_channel_impl.h"
 #include "os/alarm.h"
@@ -31,7 +32,7 @@
 namespace le {
 namespace internal {
 
-class Link {
+class Link : public l2cap::internal::ILink {
  public:
   Link(os::Handler* l2cap_handler, std::unique_ptr<hci::AclConnection> acl_connection,
        l2cap::internal::ParameterProvider* parameter_provider)
@@ -94,6 +95,8 @@
     return GetDevice().ToString();
   }
 
+  void SendDisconnectionRequest(Cid local_cid, Cid remote_cid) override {}
+
  private:
   os::Handler* l2cap_handler_;
   l2cap::internal::FixedChannelAllocator<FixedChannelImpl, Link> fixed_channel_allocator_{this, l2cap_handler_};
diff --git a/gd/security/Android.bp b/gd/security/Android.bp
index 7762461..7407f6d 100644
--- a/gd/security/Android.bp
+++ b/gd/security/Android.bp
@@ -11,6 +11,7 @@
         "internal/security_manager_impl.cc",
         "security_module.cc",
         ":BluetoothSecurityChannelSources",
+        ":BluetoothSecurityPairingSources",
     ],
 }
 
@@ -22,5 +23,6 @@
         "test/fake_l2cap_test.cc",
         "test/pairing_handler_le_pair_test.cc",
         ":BluetoothSecurityChannelTestSources",
+        ":BluetoothSecurityPairingTestSources",
     ],
 }
diff --git a/gd/security/channel/security_manager_channel.cc b/gd/security/channel/security_manager_channel.cc
index 331bbec..fd6e9df 100644
--- a/gd/security/channel/security_manager_channel.cc
+++ b/gd/security/channel/security_manager_channel.cc
@@ -1,4 +1,4 @@
-/******************************************************************************
+/*
  *
  *  Copyright 2019 The Android Open Source Project
  *
@@ -14,80 +14,32 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- ******************************************************************************/
-#include "security_manager_channel.h"
+ */
+#include "security/channel/security_manager_channel.h"
 
 #include "security/smp_packets.h"
 
-using namespace bluetooth::hci;
-using namespace bluetooth::packet;
-using namespace bluetooth::security::channel;
+namespace bluetooth {
+namespace security {
+namespace channel {
 
-void SecurityManagerChannel::SendCommand(std::shared_ptr<hci::Device> device,
-                                         std::unique_ptr<SecurityCommandBuilder> command) {
+void SecurityManagerChannel::OnCommandComplete(hci::CommandCompleteView packet) {
+  ASSERT(packet.IsValid());
+  // TODO(optedoblivion): Verify HCI commands
+}
+
+void SecurityManagerChannel::SendCommand(std::unique_ptr<hci::SecurityCommandBuilder> command) {
   hci_security_interface_->EnqueueCommand(
       std::move(command), common::BindOnce(&SecurityManagerChannel::OnCommandComplete, common::Unretained(this)),
       handler_);
 }
 
-void SecurityManagerChannel::OnCommandComplete(CommandCompleteView packet) {
-  ASSERT_LOG(packet.IsValid(), "Received invalid packet: %hx", packet.GetCommandOpCode());
-  // TODO(optedoblivion): Verify HCI commands
+void SecurityManagerChannel::OnHciEventReceived(hci::EventPacketView packet) {
+  ASSERT_LOG(listener_ != nullptr, "No listener set!");
+  ASSERT(packet.IsValid());
+  listener_->OnHciEventReceived(packet);
 }
 
-void SecurityManagerChannel::OnHciEventReceived(EventPacketView packet) {
-  ASSERT_LOG(listener_ != nullptr, "No listener set!");
-  std::shared_ptr<Device> device = nullptr;
-  auto event = EventPacketView::Create(std::move(packet));
-  ASSERT_LOG(event.IsValid(), "Received invalid packet");
-  const hci::EventCode code = event.GetEventCode();
-  switch (code) {
-    case hci::EventCode::CHANGE_CONNECTION_LINK_KEY_COMPLETE:
-      listener_->OnChangeConnectionLinkKeyComplete(device,
-                                                   hci::ChangeConnectionLinkKeyCompleteView::Create(std::move(event)));
-      break;
-    case hci::EventCode::MASTER_LINK_KEY_COMPLETE:
-      listener_->OnMasterLinkKeyComplete(device, hci::MasterLinkKeyCompleteView::Create(std::move(event)));
-      break;
-    case hci::EventCode::PIN_CODE_REQUEST:
-      listener_->OnPinCodeRequest(device, hci::PinCodeRequestView::Create(std::move(event)));
-      break;
-    case hci::EventCode::LINK_KEY_REQUEST:
-      listener_->OnLinkKeyRequest(device, hci::LinkKeyRequestView::Create(std::move(event)));
-      break;
-    case hci::EventCode::LINK_KEY_NOTIFICATION:
-      listener_->OnLinkKeyNotification(device, hci::LinkKeyNotificationView::Create(std::move(event)));
-      break;
-    case hci::EventCode::IO_CAPABILITY_REQUEST:
-      listener_->OnIoCapabilityRequest(device, hci::IoCapabilityRequestView::Create(std::move(event)));
-      break;
-    case hci::EventCode::IO_CAPABILITY_RESPONSE:
-      listener_->OnIoCapabilityResponse(device, IoCapabilityResponseView::Create(std::move(event)));
-      break;
-    case hci::EventCode::SIMPLE_PAIRING_COMPLETE:
-      listener_->OnSimplePairingComplete(device, SimplePairingCompleteView::Create(std::move(event)));
-      break;
-    case hci::EventCode::RETURN_LINK_KEYS:
-      listener_->OnReturnLinkKeys(device, hci::ReturnLinkKeysView::Create(std::move(event)));
-      break;
-    case hci::EventCode::ENCRYPTION_CHANGE:
-      listener_->OnEncryptionChange(device, hci::EncryptionChangeView::Create(std::move(event)));
-      break;
-    case hci::EventCode::ENCRYPTION_KEY_REFRESH_COMPLETE:
-      listener_->OnEncryptionKeyRefreshComplete(device,
-                                                hci::EncryptionKeyRefreshCompleteView::Create(std::move(event)));
-      break;
-    case hci::EventCode::REMOTE_OOB_DATA_REQUEST:
-      listener_->OnRemoteOobDataRequest(device, hci::RemoteOobDataRequestView::Create(std::move(event)));
-      break;
-    case hci::EventCode::USER_PASSKEY_NOTIFICATION:
-      listener_->OnUserPasskeyNotification(device, hci::UserPasskeyNotificationView::Create(std::move(event)));
-      break;
-    case hci::EventCode::KEYPRESS_NOTIFICATION:
-      listener_->OnKeypressNotification(device, hci::KeypressNotificationView::Create(std::move(event)));
-      break;
-    default:
-      ASSERT_LOG(false, "Invalid packet received: %hhx", code);
-      break;
-  }
-}
+}  // namespace channel
+}  // namespace security
+}  // namespace bluetooth
diff --git a/gd/security/channel/security_manager_channel.h b/gd/security/channel/security_manager_channel.h
index 02d0357..e844a4c 100644
--- a/gd/security/channel/security_manager_channel.h
+++ b/gd/security/channel/security_manager_channel.h
@@ -1,4 +1,4 @@
-/******************************************************************************
+/*
  *
  *  Copyright 2019 The Android Open Source Project
  *
@@ -14,50 +14,28 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- ******************************************************************************/
+ */
 #pragma once
 
 #include <memory>
 #include <vector>
 
-#include "hci/classic_device.h"
+#include "hci/address_with_type.h"
 #include "hci/hci_layer.h"
+#include "hci/hci_packets.h"
 #include "hci/security_interface.h"
-#include "security/smp_packets.h"
 
 namespace bluetooth {
 namespace security {
 namespace channel {
 
-using hci::CommandCompleteView;
-using hci::EventPacketView;
-using hci::SecurityCommandBuilder;
-using hci::SecurityCommandView;
-
 /**
  * Interface for listening to the channel for SMP commands.
  */
 class ISecurityManagerChannelListener {
  public:
   virtual ~ISecurityManagerChannelListener() = default;
-
-  virtual void OnChangeConnectionLinkKeyComplete(std::shared_ptr<hci::Device> device,
-                                                 hci::ChangeConnectionLinkKeyCompleteView packet) = 0;
-  virtual void OnMasterLinkKeyComplete(std::shared_ptr<hci::Device> device, hci::MasterLinkKeyCompleteView packet) = 0;
-  virtual void OnPinCodeRequest(std::shared_ptr<hci::Device> device, hci::PinCodeRequestView packet) = 0;
-  virtual void OnLinkKeyRequest(std::shared_ptr<hci::Device> device, hci::LinkKeyRequestView packet) = 0;
-  virtual void OnLinkKeyNotification(std::shared_ptr<hci::Device> device, hci::LinkKeyNotificationView packet) = 0;
-  virtual void OnIoCapabilityRequest(std::shared_ptr<hci::Device> device, hci::IoCapabilityRequestView packet) = 0;
-  virtual void OnIoCapabilityResponse(std::shared_ptr<hci::Device> device, hci::IoCapabilityResponseView packet) = 0;
-  virtual void OnSimplePairingComplete(std::shared_ptr<hci::Device> device, hci::SimplePairingCompleteView packet) = 0;
-  virtual void OnReturnLinkKeys(std::shared_ptr<hci::Device> device, hci::ReturnLinkKeysView packet) = 0;
-  virtual void OnEncryptionChange(std::shared_ptr<hci::Device> device, hci::EncryptionChangeView packet) = 0;
-  virtual void OnEncryptionKeyRefreshComplete(std::shared_ptr<hci::Device> device,
-                                              hci::EncryptionKeyRefreshCompleteView packet) = 0;
-  virtual void OnRemoteOobDataRequest(std::shared_ptr<hci::Device> device, hci::RemoteOobDataRequestView packet) = 0;
-  virtual void OnUserPasskeyNotification(std::shared_ptr<hci::Device> device,
-                                         hci::UserPasskeyNotificationView packet) = 0;
-  virtual void OnKeypressNotification(std::shared_ptr<hci::Device> device, hci::KeypressNotificationView packet) = 0;
+  virtual void OnHciEventReceived(hci::EventPacketView packet) = 0;
 };
 
 /**
@@ -77,10 +55,9 @@
   /**
    * Send a given SMP command over the SecurityManagerChannel
    *
-   * @param device target where command will be sent
    * @param command smp command to send
    */
-  void SendCommand(std::shared_ptr<hci::Device> device, std::unique_ptr<SecurityCommandBuilder> command);
+  void SendCommand(std::unique_ptr<hci::SecurityCommandBuilder> command);
 
   /**
    * Sets the listener to listen for channel events
@@ -96,14 +73,14 @@
    *
    * @param event_packet
    */
-  void OnHciEventReceived(EventPacketView packet);
+  void OnHciEventReceived(hci::EventPacketView packet);
 
   /**
    * Called when an HCI command is completed
    *
    * @param on_complete
    */
-  void OnCommandComplete(CommandCompleteView packet);
+  void OnCommandComplete(hci::CommandCompleteView packet);
 
  private:
   ISecurityManagerChannelListener* listener_;
diff --git a/gd/security/channel/security_manager_channel_unittest.cc b/gd/security/channel/security_manager_channel_unittest.cc
index b111e7f..ee12b92 100644
--- a/gd/security/channel/security_manager_channel_unittest.cc
+++ b/gd/security/channel/security_manager_channel_unittest.cc
@@ -1,4 +1,4 @@
-/******************************************************************************
+/*
  *
  *  Copyright 2019 The Android Open Source Project
  *
@@ -14,13 +14,11 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- ******************************************************************************/
+ */
 #include "security_manager_channel.h"
 
 #include <gtest/gtest.h>
 
-#include "hci/device.h"
-#include "hci/device_database.h"
 #include "hci/hci_packets.h"
 #include "packet/raw_builder.h"
 #include "security/smp_packets.h"
@@ -32,10 +30,9 @@
 namespace {
 
 using bluetooth::security::channel::SecurityManagerChannel;
+using hci::Address;
 using hci::AuthenticationRequirements;
 using hci::CommandCompleteBuilder;
-using hci::Device;
-using hci::DeviceDatabase;
 using hci::IoCapabilityRequestReplyBuilder;
 using hci::IoCapabilityRequestView;
 using hci::OobDataPresent;
@@ -44,8 +41,6 @@
 using os::Thread;
 using packet::RawBuilder;
 
-static DeviceDatabase kDeviceDatabase;
-
 class SecurityManagerChannelCallback : public ISecurityManagerChannelListener {
  public:
   // HCI
@@ -62,71 +57,138 @@
   bool receivedEncryptionKeyRefreshComplete = false;
   bool receivedRemoteOobDataRequest = false;
   bool receivedUserPasskeyNotification = false;
+  bool receivedUserPasskeyRequest = false;
   bool receivedKeypressNotification = false;
+  bool receivedUserConfirmationRequest = false;
 
-  void OnChangeConnectionLinkKeyComplete(std::shared_ptr<hci::Device> device,
-                                         hci::ChangeConnectionLinkKeyCompleteView packet) {
-    EXPECT_TRUE(packet.IsValid());
+  void OnReceive(hci::AddressWithType device, hci::ChangeConnectionLinkKeyCompleteView packet) {
+    ASSERT_TRUE(packet.IsValid());
     receivedChangeConnectionLinkKeyComplete = true;
   }
-  void OnMasterLinkKeyComplete(std::shared_ptr<hci::Device> device, hci::MasterLinkKeyCompleteView packet) {
-    EXPECT_TRUE(packet.IsValid());
+  void OnReceive(hci::AddressWithType device, hci::MasterLinkKeyCompleteView packet) {
+    ASSERT_TRUE(packet.IsValid());
     receivedMasterLinkKeyComplete = true;
   }
-  void OnPinCodeRequest(std::shared_ptr<hci::Device> device, hci::PinCodeRequestView packet) {
-    EXPECT_TRUE(packet.IsValid());
+  void OnReceive(hci::AddressWithType device, hci::PinCodeRequestView packet) {
+    ASSERT_TRUE(packet.IsValid());
     receivedPinCodeRequest = true;
   }
-  void OnLinkKeyRequest(std::shared_ptr<hci::Device> device, hci::LinkKeyRequestView packet) {
-    EXPECT_TRUE(packet.IsValid());
+  void OnReceive(hci::AddressWithType device, hci::LinkKeyRequestView packet) {
+    ASSERT_TRUE(packet.IsValid());
     receivedLinkKeyRequest = true;
   }
-  void OnLinkKeyNotification(std::shared_ptr<hci::Device> device, hci::LinkKeyNotificationView packet) {
-    EXPECT_TRUE(packet.IsValid());
+  void OnReceive(hci::AddressWithType device, hci::LinkKeyNotificationView packet) {
+    ASSERT_TRUE(packet.IsValid());
     receivedLinkKeyNotification = true;
   }
-  void OnIoCapabilityRequest(std::shared_ptr<Device> device, hci::IoCapabilityRequestView packet) {
-    EXPECT_TRUE(packet.IsValid());
+  void OnReceive(hci::AddressWithType device, hci::IoCapabilityRequestView packet) {
+    ASSERT_TRUE(packet.IsValid());
     receivedIoCapabilityRequest = true;
   }
-  void OnIoCapabilityResponse(std::shared_ptr<Device> device, hci::IoCapabilityResponseView packet) {
-    EXPECT_TRUE(packet.IsValid());
+  void OnReceive(hci::AddressWithType device, hci::IoCapabilityResponseView packet) {
+    ASSERT_TRUE(packet.IsValid());
     receivedIoCapabilityResponse = true;
   }
-  void OnSimplePairingComplete(std::shared_ptr<Device> device, hci::SimplePairingCompleteView packet) {
-    EXPECT_TRUE(packet.IsValid());
+  void OnReceive(hci::AddressWithType device, hci::SimplePairingCompleteView packet) {
+    ASSERT_TRUE(packet.IsValid());
     receivedSimplePairingComplete = true;
   }
-  void OnReturnLinkKeys(std::shared_ptr<Device> device, hci::ReturnLinkKeysView packet) {
-    EXPECT_TRUE(packet.IsValid());
+  void OnReceive(hci::AddressWithType device, hci::ReturnLinkKeysView packet) {
+    ASSERT_TRUE(packet.IsValid());
     receivedReturnLinkKeys = true;
   }
-  void OnEncryptionChange(std::shared_ptr<Device> device, hci::EncryptionChangeView packet) {
-    EXPECT_TRUE(packet.IsValid());
+  void OnReceive(hci::AddressWithType device, hci::EncryptionChangeView packet) {
+    ASSERT_TRUE(packet.IsValid());
     receivedEncryptionChange = true;
   }
-  void OnEncryptionKeyRefreshComplete(std::shared_ptr<Device> device, hci::EncryptionKeyRefreshCompleteView packet) {
-    EXPECT_TRUE(packet.IsValid());
+  void OnReceive(hci::AddressWithType device, hci::EncryptionKeyRefreshCompleteView packet) {
+    ASSERT_TRUE(packet.IsValid());
     receivedEncryptionKeyRefreshComplete = true;
   }
-  void OnRemoteOobDataRequest(std::shared_ptr<Device> device, hci::RemoteOobDataRequestView packet) {
-    EXPECT_TRUE(packet.IsValid());
+  void OnReceive(hci::AddressWithType device, hci::RemoteOobDataRequestView packet) {
+    ASSERT_TRUE(packet.IsValid());
     receivedRemoteOobDataRequest = true;
   }
-  void OnUserPasskeyNotification(std::shared_ptr<hci::Device> device, hci::UserPasskeyNotificationView packet) {
-    EXPECT_TRUE(packet.IsValid());
+  void OnReceive(hci::AddressWithType device, hci::UserPasskeyNotificationView packet) {
+    ASSERT_TRUE(packet.IsValid());
     receivedUserPasskeyNotification = true;
   }
-  void OnKeypressNotification(std::shared_ptr<hci::Device> device, hci::KeypressNotificationView packet) {
-    EXPECT_TRUE(packet.IsValid());
+  void OnReceive(hci::AddressWithType device, hci::KeypressNotificationView packet) {
+    ASSERT_TRUE(packet.IsValid());
     receivedKeypressNotification = true;
   }
+  void OnReceive(hci::AddressWithType device, hci::UserConfirmationRequestView packet) {
+    ASSERT_TRUE(packet.IsValid());
+    receivedUserConfirmationRequest = true;
+  }
+  void OnReceive(hci::AddressWithType device, hci::UserPasskeyRequestView packet) {
+    ASSERT_TRUE(packet.IsValid());
+    receivedUserPasskeyRequest = true;
+  }
+
+  void OnHciEventReceived(EventPacketView packet) override {
+    auto event = EventPacketView::Create(packet);
+    ASSERT_LOG(event.IsValid(), "Received invalid packet");
+    const hci::EventCode code = event.GetEventCode();
+    switch (code) {
+      case hci::EventCode::CHANGE_CONNECTION_LINK_KEY_COMPLETE:
+        OnReceive(hci::AddressWithType(), hci::ChangeConnectionLinkKeyCompleteView::Create(event));
+        break;
+      case hci::EventCode::MASTER_LINK_KEY_COMPLETE:
+        OnReceive(hci::AddressWithType(), hci::MasterLinkKeyCompleteView::Create(event));
+        break;
+      case hci::EventCode::PIN_CODE_REQUEST:
+        OnReceive(hci::AddressWithType(), hci::PinCodeRequestView::Create(event));
+        break;
+      case hci::EventCode::LINK_KEY_REQUEST:
+        OnReceive(hci::AddressWithType(), hci::LinkKeyRequestView::Create(event));
+        break;
+      case hci::EventCode::LINK_KEY_NOTIFICATION:
+        OnReceive(hci::AddressWithType(), hci::LinkKeyNotificationView::Create(event));
+        break;
+      case hci::EventCode::IO_CAPABILITY_REQUEST:
+        OnReceive(hci::AddressWithType(), hci::IoCapabilityRequestView::Create(event));
+        break;
+      case hci::EventCode::IO_CAPABILITY_RESPONSE:
+        OnReceive(hci::AddressWithType(), hci::IoCapabilityResponseView::Create(event));
+        break;
+      case hci::EventCode::SIMPLE_PAIRING_COMPLETE:
+        OnReceive(hci::AddressWithType(), hci::SimplePairingCompleteView::Create(event));
+        break;
+      case hci::EventCode::RETURN_LINK_KEYS:
+        OnReceive(hci::AddressWithType(), hci::ReturnLinkKeysView::Create(event));
+        break;
+      case hci::EventCode::ENCRYPTION_CHANGE:
+        OnReceive(hci::AddressWithType(), hci::EncryptionChangeView::Create(event));
+        break;
+      case hci::EventCode::ENCRYPTION_KEY_REFRESH_COMPLETE:
+        OnReceive(hci::AddressWithType(), hci::EncryptionKeyRefreshCompleteView::Create(event));
+        break;
+      case hci::EventCode::REMOTE_OOB_DATA_REQUEST:
+        OnReceive(hci::AddressWithType(), hci::RemoteOobDataRequestView::Create(event));
+        break;
+      case hci::EventCode::USER_PASSKEY_NOTIFICATION:
+        OnReceive(hci::AddressWithType(), hci::UserPasskeyNotificationView::Create(event));
+        break;
+      case hci::EventCode::KEYPRESS_NOTIFICATION:
+        OnReceive(hci::AddressWithType(), hci::KeypressNotificationView::Create(event));
+        break;
+      case hci::EventCode::USER_CONFIRMATION_REQUEST:
+        OnReceive(hci::AddressWithType(), hci::UserConfirmationRequestView::Create(event));
+        break;
+      case hci::EventCode::USER_PASSKEY_REQUEST:
+        OnReceive(hci::AddressWithType(), hci::UserPasskeyRequestView::Create(event));
+        break;
+      default:
+        ASSERT_LOG(false, "Cannot handle received packet: %s", hci::EventCodeText(code).c_str());
+        break;
+    }
+  }
 };
 
 class SecurityManagerChannelTest : public ::testing::Test {
  protected:
   void SetUp() override {
-    device_ = kDeviceDatabase.CreateClassicDevice(hci::Address({0x01, 0x02, 0x03, 0x04, 0x05, 0x06}));
     handler_ = new Handler(&thread_);
     callback_ = new SecurityManagerChannelCallback();
     hci_layer_ = new FakeHciLayer();
@@ -152,14 +214,14 @@
   FakeHciLayer* hci_layer_ = nullptr;
   SecurityManagerChannel* channel_ = nullptr;
   SecurityManagerChannelCallback* callback_ = nullptr;
-  std::shared_ptr<Device> device_ = nullptr;
+  hci::AddressWithType device_;
 };
 
 TEST_F(SecurityManagerChannelTest, setup_teardown) {}
 
 TEST_F(SecurityManagerChannelTest, recv_io_cap_request) {
-  hci_layer_->IncomingEvent(hci::IoCapabilityRequestBuilder::Create(device_->GetAddress()));
-  EXPECT_TRUE(callback_->receivedIoCapabilityRequest);
+  hci_layer_->IncomingEvent(hci::IoCapabilityRequestBuilder::Create(device_.GetAddress()));
+  ASSERT_TRUE(callback_->receivedIoCapabilityRequest);
 }
 
 TEST_F(SecurityManagerChannelTest, send_io_cap_request_reply) {
@@ -167,153 +229,159 @@
   hci::IoCapability io_capability = (hci::IoCapability)0x00;
   OobDataPresent oob_present = (OobDataPresent)0x00;
   AuthenticationRequirements authentication_requirements = (AuthenticationRequirements)0x00;
-  auto packet = hci::IoCapabilityRequestReplyBuilder::Create(device_->GetAddress(), io_capability, oob_present,
+  auto packet = hci::IoCapabilityRequestReplyBuilder::Create(device_.GetAddress(), io_capability, oob_present,
                                                              authentication_requirements);
 
   // Act
-  channel_->SendCommand(device_, std::move(packet));
+  channel_->SendCommand(std::move(packet));
   auto last_command = std::move(hci_layer_->GetLastCommand()->command);
   auto command_packet = GetPacketView(std::move(last_command));
   hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet);
 
   // Assert
-  EXPECT_TRUE(packet_view.IsValid());
-  EXPECT_EQ(OpCode::IO_CAPABILITY_REQUEST_REPLY, packet_view.GetOpCode());
+  ASSERT_TRUE(packet_view.IsValid());
+  ASSERT_EQ(OpCode::IO_CAPABILITY_REQUEST_REPLY, packet_view.GetOpCode());
 }
 
 TEST_F(SecurityManagerChannelTest, send_io_cap_request_neg_reply) {
   // Arrange
   auto packet =
-      hci::IoCapabilityRequestNegativeReplyBuilder::Create(device_->GetAddress(), hci::ErrorCode::COMMAND_DISALLOWED);
+      hci::IoCapabilityRequestNegativeReplyBuilder::Create(device_.GetAddress(), hci::ErrorCode::COMMAND_DISALLOWED);
 
   // Act
-  channel_->SendCommand(device_, std::move(packet));
+  channel_->SendCommand(std::move(packet));
   auto last_command = std::move(hci_layer_->GetLastCommand()->command);
   auto command_packet = GetPacketView(std::move(last_command));
   hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet);
 
   // Assert
-  EXPECT_TRUE(packet_view.IsValid());
-  EXPECT_EQ(OpCode::IO_CAPABILITY_REQUEST_NEGATIVE_REPLY, packet_view.GetOpCode());
+  ASSERT_TRUE(packet_view.IsValid());
+  ASSERT_EQ(OpCode::IO_CAPABILITY_REQUEST_NEGATIVE_REPLY, packet_view.GetOpCode());
 }
 
 TEST_F(SecurityManagerChannelTest, recv_io_cap_response) {
   hci::IoCapability io_capability = (hci::IoCapability)0x00;
   OobDataPresent oob_present = (OobDataPresent)0x00;
   AuthenticationRequirements authentication_requirements = (AuthenticationRequirements)0x00;
-  hci_layer_->IncomingEvent(hci::IoCapabilityResponseBuilder::Create(device_->GetAddress(), io_capability, oob_present,
+  hci_layer_->IncomingEvent(hci::IoCapabilityResponseBuilder::Create(device_.GetAddress(), io_capability, oob_present,
                                                                      authentication_requirements));
-  EXPECT_TRUE(callback_->receivedIoCapabilityResponse);
+  ASSERT_TRUE(callback_->receivedIoCapabilityResponse);
 }
 
 TEST_F(SecurityManagerChannelTest, recv_pin_code_request) {
-  hci_layer_->IncomingEvent(hci::PinCodeRequestBuilder::Create(device_->GetAddress()));
-  EXPECT_TRUE(callback_->receivedPinCodeRequest);
+  hci_layer_->IncomingEvent(hci::PinCodeRequestBuilder::Create(device_.GetAddress()));
+  ASSERT_TRUE(callback_->receivedPinCodeRequest);
 }
 
 TEST_F(SecurityManagerChannelTest, send_pin_code_request_reply) {
   // Arrange
   uint8_t pin_code_length = 6;
   std::array<uint8_t, 16> pin_code = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5};
-  auto packet = hci::PinCodeRequestReplyBuilder::Create(device_->GetAddress(), pin_code_length, pin_code);
+  auto packet = hci::PinCodeRequestReplyBuilder::Create(device_.GetAddress(), pin_code_length, pin_code);
 
   // Act
-  channel_->SendCommand(device_, std::move(packet));
+  channel_->SendCommand(std::move(packet));
   auto last_command = std::move(hci_layer_->GetLastCommand()->command);
   auto command_packet = GetPacketView(std::move(last_command));
   hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet);
 
   // Assert
-  EXPECT_TRUE(packet_view.IsValid());
-  EXPECT_EQ(OpCode::PIN_CODE_REQUEST_REPLY, packet_view.GetOpCode());
+  ASSERT_TRUE(packet_view.IsValid());
+  ASSERT_EQ(OpCode::PIN_CODE_REQUEST_REPLY, packet_view.GetOpCode());
 }
 
 TEST_F(SecurityManagerChannelTest, send_pin_code_request_neg_reply) {
   // Arrange
-  auto packet = hci::PinCodeRequestNegativeReplyBuilder::Create(device_->GetAddress());
+  auto packet = hci::PinCodeRequestNegativeReplyBuilder::Create(device_.GetAddress());
 
   // Act
-  channel_->SendCommand(device_, std::move(packet));
+  channel_->SendCommand(std::move(packet));
   auto last_command = std::move(hci_layer_->GetLastCommand()->command);
   auto command_packet = GetPacketView(std::move(last_command));
   hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet);
 
   // Assert
-  EXPECT_TRUE(packet_view.IsValid());
-  EXPECT_EQ(OpCode::PIN_CODE_REQUEST_NEGATIVE_REPLY, packet_view.GetOpCode());
+  ASSERT_TRUE(packet_view.IsValid());
+  ASSERT_EQ(OpCode::PIN_CODE_REQUEST_NEGATIVE_REPLY, packet_view.GetOpCode());
 }
 
 TEST_F(SecurityManagerChannelTest, recv_user_passkey_notification) {
   uint32_t passkey = 0x00;
-  hci_layer_->IncomingEvent(hci::UserPasskeyNotificationBuilder::Create(device_->GetAddress(), passkey));
-  EXPECT_TRUE(callback_->receivedUserPasskeyNotification);
+  hci_layer_->IncomingEvent(hci::UserPasskeyNotificationBuilder::Create(device_.GetAddress(), passkey));
+  ASSERT_TRUE(callback_->receivedUserPasskeyNotification);
+}
+
+TEST_F(SecurityManagerChannelTest, recv_user_confirmation_request) {
+  uint32_t numeric_value = 0x0;
+  hci_layer_->IncomingEvent(hci::UserConfirmationRequestBuilder::Create(device_.GetAddress(), numeric_value));
+  ASSERT_TRUE(callback_->receivedUserConfirmationRequest);
 }
 
 TEST_F(SecurityManagerChannelTest, send_user_confirmation_request_reply) {
   // Arrange
-  auto packet = hci::UserConfirmationRequestReplyBuilder::Create(device_->GetAddress());
+  auto packet = hci::UserConfirmationRequestReplyBuilder::Create(device_.GetAddress());
 
   // Act
-  channel_->SendCommand(device_, std::move(packet));
+  channel_->SendCommand(std::move(packet));
   auto last_command = std::move(hci_layer_->GetLastCommand()->command);
   auto command_packet = GetPacketView(std::move(last_command));
   hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet);
 
   // Assert
-  EXPECT_TRUE(packet_view.IsValid());
-  EXPECT_EQ(OpCode::USER_CONFIRMATION_REQUEST_REPLY, packet_view.GetOpCode());
+  ASSERT_TRUE(packet_view.IsValid());
+  ASSERT_EQ(OpCode::USER_CONFIRMATION_REQUEST_REPLY, packet_view.GetOpCode());
 }
 
-TEST_F(SecurityManagerChannelTest, send_user_confirmation_request_neg_reply) {
+TEST_F(SecurityManagerChannelTest, send_user_confirmation_request_negative_reply) {
   // Arrange
-  auto packet = hci::UserConfirmationRequestNegativeReplyBuilder::Create(device_->GetAddress());
+  auto packet = hci::UserConfirmationRequestNegativeReplyBuilder::Create(device_.GetAddress());
 
   // Act
-  channel_->SendCommand(device_, std::move(packet));
+  channel_->SendCommand(std::move(packet));
   auto last_command = std::move(hci_layer_->GetLastCommand()->command);
   auto command_packet = GetPacketView(std::move(last_command));
   hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet);
 
   // Assert
-  EXPECT_TRUE(packet_view.IsValid());
-  EXPECT_EQ(OpCode::USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY, packet_view.GetOpCode());
+  ASSERT_TRUE(packet_view.IsValid());
+  ASSERT_EQ(OpCode::USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY, packet_view.GetOpCode());
 }
 
 TEST_F(SecurityManagerChannelTest, recv_remote_oob_data_request) {
-  hci_layer_->IncomingEvent(hci::RemoteOobDataRequestBuilder::Create(device_->GetAddress()));
-  EXPECT_TRUE(callback_->receivedRemoteOobDataRequest);
+  hci_layer_->IncomingEvent(hci::RemoteOobDataRequestBuilder::Create(device_.GetAddress()));
+  ASSERT_TRUE(callback_->receivedRemoteOobDataRequest);
 }
 
 TEST_F(SecurityManagerChannelTest, send_remote_oob_data_request_reply) {
   // Arrange
   std::array<uint8_t, 16> c = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5};
   std::array<uint8_t, 16> r = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5};
-  auto packet = hci::RemoteOobDataRequestReplyBuilder::Create(device_->GetAddress(), c, r);
+  auto packet = hci::RemoteOobDataRequestReplyBuilder::Create(device_.GetAddress(), c, r);
 
   // Act
-  channel_->SendCommand(device_, std::move(packet));
+  channel_->SendCommand(std::move(packet));
   auto last_command = std::move(hci_layer_->GetLastCommand()->command);
   auto command_packet = GetPacketView(std::move(last_command));
   hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet);
 
   // Assert
-  EXPECT_TRUE(packet_view.IsValid());
-  EXPECT_EQ(OpCode::REMOTE_OOB_DATA_REQUEST_REPLY, packet_view.GetOpCode());
+  ASSERT_TRUE(packet_view.IsValid());
+  ASSERT_EQ(OpCode::REMOTE_OOB_DATA_REQUEST_REPLY, packet_view.GetOpCode());
 }
 
 TEST_F(SecurityManagerChannelTest, send_remote_oob_data_request_neg_reply) {
   // Arrange
-  auto packet = hci::RemoteOobDataRequestNegativeReplyBuilder::Create(device_->GetAddress());
+  auto packet = hci::RemoteOobDataRequestNegativeReplyBuilder::Create(device_.GetAddress());
 
   // Act
-  channel_->SendCommand(device_, std::move(packet));
+  channel_->SendCommand(std::move(packet));
   auto last_command = std::move(hci_layer_->GetLastCommand()->command);
   auto command_packet = GetPacketView(std::move(last_command));
   hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet);
 
   // Assert
-  EXPECT_TRUE(packet_view.IsValid());
-  EXPECT_EQ(OpCode::REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY, packet_view.GetOpCode());
+  ASSERT_TRUE(packet_view.IsValid());
+  ASSERT_EQ(OpCode::REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY, packet_view.GetOpCode());
 }
 
 TEST_F(SecurityManagerChannelTest, send_read_local_oob_data) {
@@ -321,14 +389,14 @@
   auto packet = hci::ReadLocalOobDataBuilder::Create();
 
   // Act
-  channel_->SendCommand(device_, std::move(packet));
+  channel_->SendCommand(std::move(packet));
   auto last_command = std::move(hci_layer_->GetLastCommand()->command);
   auto command_packet = GetPacketView(std::move(last_command));
   hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet);
 
   // Assert
-  EXPECT_TRUE(packet_view.IsValid());
-  EXPECT_EQ(OpCode::READ_LOCAL_OOB_DATA, packet_view.GetOpCode());
+  ASSERT_TRUE(packet_view.IsValid());
+  ASSERT_EQ(OpCode::READ_LOCAL_OOB_DATA, packet_view.GetOpCode());
 }
 
 TEST_F(SecurityManagerChannelTest, send_read_local_oob_extended_data) {
@@ -336,92 +404,92 @@
   auto packet = hci::ReadLocalOobExtendedDataBuilder::Create();
 
   // Act
-  channel_->SendCommand(device_, std::move(packet));
+  channel_->SendCommand(std::move(packet));
   auto last_command = std::move(hci_layer_->GetLastCommand()->command);
   auto command_packet = GetPacketView(std::move(last_command));
   hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet);
 
   // Assert
-  EXPECT_TRUE(packet_view.IsValid());
-  EXPECT_EQ(OpCode::READ_LOCAL_OOB_EXTENDED_DATA, packet_view.GetOpCode());
+  ASSERT_TRUE(packet_view.IsValid());
+  ASSERT_EQ(OpCode::READ_LOCAL_OOB_EXTENDED_DATA, packet_view.GetOpCode());
 }
 
 TEST_F(SecurityManagerChannelTest, recv_link_key_request) {
-  hci_layer_->IncomingEvent(hci::LinkKeyRequestBuilder::Create(device_->GetAddress()));
-  EXPECT_TRUE(callback_->receivedLinkKeyRequest);
+  hci_layer_->IncomingEvent(hci::LinkKeyRequestBuilder::Create(device_.GetAddress()));
+  ASSERT_TRUE(callback_->receivedLinkKeyRequest);
 }
 
 TEST_F(SecurityManagerChannelTest, recv_link_key_notification) {
   std::array<uint8_t, 16> link_key = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5};
   hci_layer_->IncomingEvent(
-      hci::LinkKeyNotificationBuilder::Create(device_->GetAddress(), link_key, hci::KeyType::DEBUG_COMBINATION));
-  EXPECT_TRUE(callback_->receivedLinkKeyNotification);
+      hci::LinkKeyNotificationBuilder::Create(device_.GetAddress(), link_key, hci::KeyType::DEBUG_COMBINATION));
+  ASSERT_TRUE(callback_->receivedLinkKeyNotification);
 }
 
 TEST_F(SecurityManagerChannelTest, recv_master_link_key_complete) {
   uint16_t connection_handle = 0x0;
   hci_layer_->IncomingEvent(
       hci::MasterLinkKeyCompleteBuilder::Create(hci::ErrorCode::SUCCESS, connection_handle, hci::KeyFlag::TEMPORARY));
-  EXPECT_TRUE(callback_->receivedMasterLinkKeyComplete);
+  ASSERT_TRUE(callback_->receivedMasterLinkKeyComplete);
 }
 
 TEST_F(SecurityManagerChannelTest, recv_change_connection_link_key_complete) {
   uint16_t connection_handle = 0x0;
   hci_layer_->IncomingEvent(
       hci::ChangeConnectionLinkKeyCompleteBuilder::Create(hci::ErrorCode::SUCCESS, connection_handle));
-  EXPECT_TRUE(callback_->receivedChangeConnectionLinkKeyComplete);
+  ASSERT_TRUE(callback_->receivedChangeConnectionLinkKeyComplete);
 }
 
 TEST_F(SecurityManagerChannelTest, recv_return_link_keys) {
   std::vector<hci::ZeroKeyAndAddress> keys;
   hci_layer_->IncomingEvent(hci::ReturnLinkKeysBuilder::Create(keys));
-  EXPECT_TRUE(callback_->receivedReturnLinkKeys);
+  ASSERT_TRUE(callback_->receivedReturnLinkKeys);
 }
 
 TEST_F(SecurityManagerChannelTest, send_link_key_request_reply) {
   // Arrange
   std::array<uint8_t, 16> link_key = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5};
-  auto packet = hci::LinkKeyRequestReplyBuilder::Create(device_->GetAddress(), link_key);
+  auto packet = hci::LinkKeyRequestReplyBuilder::Create(device_.GetAddress(), link_key);
 
   // Act
-  channel_->SendCommand(device_, std::move(packet));
+  channel_->SendCommand(std::move(packet));
   auto last_command = std::move(hci_layer_->GetLastCommand()->command);
   auto command_packet = GetPacketView(std::move(last_command));
   hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet);
 
   // Assert
-  EXPECT_TRUE(packet_view.IsValid());
-  EXPECT_EQ(OpCode::LINK_KEY_REQUEST_REPLY, packet_view.GetOpCode());
+  ASSERT_TRUE(packet_view.IsValid());
+  ASSERT_EQ(OpCode::LINK_KEY_REQUEST_REPLY, packet_view.GetOpCode());
 }
 
 TEST_F(SecurityManagerChannelTest, send_link_key_request_neg_reply) {
   // Arrange
-  auto packet = hci::LinkKeyRequestNegativeReplyBuilder::Create(device_->GetAddress());
+  auto packet = hci::LinkKeyRequestNegativeReplyBuilder::Create(device_.GetAddress());
 
   // Act
-  channel_->SendCommand(device_, std::move(packet));
+  channel_->SendCommand(std::move(packet));
   auto last_command = std::move(hci_layer_->GetLastCommand()->command);
   auto command_packet = GetPacketView(std::move(last_command));
   hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet);
 
   // Assert
-  EXPECT_TRUE(packet_view.IsValid());
-  EXPECT_EQ(OpCode::LINK_KEY_REQUEST_NEGATIVE_REPLY, packet_view.GetOpCode());
+  ASSERT_TRUE(packet_view.IsValid());
+  ASSERT_EQ(OpCode::LINK_KEY_REQUEST_NEGATIVE_REPLY, packet_view.GetOpCode());
 }
 
 TEST_F(SecurityManagerChannelTest, send_read_stored_link_key) {
   // Arrange
-  auto packet = hci::ReadStoredLinkKeyBuilder::Create(device_->GetAddress(), hci::ReadStoredLinkKeyReadAllFlag::ALL);
+  auto packet = hci::ReadStoredLinkKeyBuilder::Create(device_.GetAddress(), hci::ReadStoredLinkKeyReadAllFlag::ALL);
 
   // Act
-  channel_->SendCommand(device_, std::move(packet));
+  channel_->SendCommand(std::move(packet));
   auto last_command = std::move(hci_layer_->GetLastCommand()->command);
   auto command_packet = GetPacketView(std::move(last_command));
   hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet);
 
   // Assert
-  EXPECT_TRUE(packet_view.IsValid());
-  EXPECT_EQ(OpCode::READ_STORED_LINK_KEY, packet_view.GetOpCode());
+  ASSERT_TRUE(packet_view.IsValid());
+  ASSERT_EQ(OpCode::READ_STORED_LINK_KEY, packet_view.GetOpCode());
 }
 
 TEST_F(SecurityManagerChannelTest, send_write_stored_link_key) {
@@ -430,37 +498,44 @@
   auto packet = hci::WriteStoredLinkKeyBuilder::Create(keys_to_write);
 
   // Act
-  channel_->SendCommand(device_, std::move(packet));
+  channel_->SendCommand(std::move(packet));
   auto last_command = std::move(hci_layer_->GetLastCommand()->command);
   auto command_packet = GetPacketView(std::move(last_command));
   hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet);
 
   // Assert
-  EXPECT_TRUE(packet_view.IsValid());
-  EXPECT_EQ(OpCode::WRITE_STORED_LINK_KEY, packet_view.GetOpCode());
+  ASSERT_TRUE(packet_view.IsValid());
+  ASSERT_EQ(OpCode::WRITE_STORED_LINK_KEY, packet_view.GetOpCode());
 }
 
 TEST_F(SecurityManagerChannelTest, send_delete_stored_link_key) {
   // Arrange
   auto packet =
-      hci::DeleteStoredLinkKeyBuilder::Create(device_->GetAddress(), hci::DeleteStoredLinkKeyDeleteAllFlag::ALL);
+      hci::DeleteStoredLinkKeyBuilder::Create(device_.GetAddress(), hci::DeleteStoredLinkKeyDeleteAllFlag::ALL);
 
   // Act
-  channel_->SendCommand(device_, std::move(packet));
+  channel_->SendCommand(std::move(packet));
   auto last_command = std::move(hci_layer_->GetLastCommand()->command);
   auto command_packet = GetPacketView(std::move(last_command));
   hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet);
 
   // Assert
-  EXPECT_TRUE(packet_view.IsValid());
-  EXPECT_EQ(OpCode::DELETE_STORED_LINK_KEY, packet_view.GetOpCode());
+  ASSERT_TRUE(packet_view.IsValid());
+  ASSERT_EQ(OpCode::DELETE_STORED_LINK_KEY, packet_view.GetOpCode());
 }
 
 TEST_F(SecurityManagerChannelTest, recv_encryption_change) {
   uint16_t connection_handle = 0x0;
   hci_layer_->IncomingEvent(
       hci::EncryptionChangeBuilder::Create(hci::ErrorCode::SUCCESS, connection_handle, hci::EncryptionEnabled::ON));
-  EXPECT_TRUE(callback_->receivedEncryptionChange);
+  ASSERT_TRUE(callback_->receivedEncryptionChange);
+}
+
+TEST_F(SecurityManagerChannelTest, recv_encryption_key_refresh) {
+  uint16_t connection_handle = 0x0;
+  hci_layer_->IncomingEvent(
+      hci::EncryptionKeyRefreshCompleteBuilder::Create(hci::ErrorCode::SUCCESS, connection_handle));
+  ASSERT_TRUE(callback_->receivedEncryptionKeyRefreshComplete);
 }
 
 TEST_F(SecurityManagerChannelTest, send_refresh_encryption_key) {
@@ -469,14 +544,14 @@
   auto packet = hci::RefreshEncryptionKeyBuilder::Create(connection_handle);
 
   // Act
-  channel_->SendCommand(device_, std::move(packet));
+  channel_->SendCommand(std::move(packet));
   auto last_command = std::move(hci_layer_->GetLastCommand()->command);
   auto command_packet = GetPacketView(std::move(last_command));
   hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet);
 
   // Assert
-  EXPECT_TRUE(packet_view.IsValid());
-  EXPECT_EQ(OpCode::REFRESH_ENCRYPTION_KEY, packet_view.GetOpCode());
+  ASSERT_TRUE(packet_view.IsValid());
+  ASSERT_EQ(OpCode::REFRESH_ENCRYPTION_KEY, packet_view.GetOpCode());
 }
 
 TEST_F(SecurityManagerChannelTest, send_read_encryption_key_size) {
@@ -485,19 +560,19 @@
   auto packet = hci::ReadEncryptionKeySizeBuilder::Create(connection_handle);
 
   // Act
-  channel_->SendCommand(device_, std::move(packet));
+  channel_->SendCommand(std::move(packet));
   auto last_command = std::move(hci_layer_->GetLastCommand()->command);
   auto command_packet = GetPacketView(std::move(last_command));
   hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet);
 
   // Assert
-  EXPECT_TRUE(packet_view.IsValid());
-  EXPECT_EQ(OpCode::READ_ENCRYPTION_KEY_SIZE, packet_view.GetOpCode());
+  ASSERT_TRUE(packet_view.IsValid());
+  ASSERT_EQ(OpCode::READ_ENCRYPTION_KEY_SIZE, packet_view.GetOpCode());
 }
 
 TEST_F(SecurityManagerChannelTest, recv_simple_pairing_complete) {
-  hci_layer_->IncomingEvent(hci::SimplePairingCompleteBuilder::Create(hci::ErrorCode::SUCCESS, device_->GetAddress()));
-  EXPECT_TRUE(callback_->receivedSimplePairingComplete);
+  hci_layer_->IncomingEvent(hci::SimplePairingCompleteBuilder::Create(hci::ErrorCode::SUCCESS, device_.GetAddress()));
+  ASSERT_TRUE(callback_->receivedSimplePairingComplete);
 }
 
 TEST_F(SecurityManagerChannelTest, send_read_simple_pairing_mode) {
@@ -505,14 +580,14 @@
   auto packet = hci::ReadSimplePairingModeBuilder::Create();
 
   // Act
-  channel_->SendCommand(device_, std::move(packet));
+  channel_->SendCommand(std::move(packet));
   auto last_command = std::move(hci_layer_->GetLastCommand()->command);
   auto command_packet = GetPacketView(std::move(last_command));
   hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet);
 
   // Assert
-  EXPECT_TRUE(packet_view.IsValid());
-  EXPECT_EQ(OpCode::READ_SIMPLE_PAIRING_MODE, packet_view.GetOpCode());
+  ASSERT_TRUE(packet_view.IsValid());
+  ASSERT_EQ(OpCode::READ_SIMPLE_PAIRING_MODE, packet_view.GetOpCode());
 }
 
 TEST_F(SecurityManagerChannelTest, send_write_simple_pairing_mode) {
@@ -520,36 +595,41 @@
   auto packet = hci::WriteSimplePairingModeBuilder::Create(hci::Enable::ENABLED);
 
   // Act
-  channel_->SendCommand(device_, std::move(packet));
+  channel_->SendCommand(std::move(packet));
   auto last_command = std::move(hci_layer_->GetLastCommand()->command);
   auto command_packet = GetPacketView(std::move(last_command));
   hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet);
 
   // Assert
-  EXPECT_TRUE(packet_view.IsValid());
-  EXPECT_EQ(OpCode::WRITE_SIMPLE_PAIRING_MODE, packet_view.GetOpCode());
+  ASSERT_TRUE(packet_view.IsValid());
+  ASSERT_EQ(OpCode::WRITE_SIMPLE_PAIRING_MODE, packet_view.GetOpCode());
 }
 
 TEST_F(SecurityManagerChannelTest, recv_keypress_notification) {
   hci_layer_->IncomingEvent(
-      hci::KeypressNotificationBuilder::Create(device_->GetAddress(), hci::KeypressNotificationType::ENTRY_COMPLETED));
-  EXPECT_TRUE(callback_->receivedKeypressNotification);
+      hci::KeypressNotificationBuilder::Create(device_.GetAddress(), hci::KeypressNotificationType::ENTRY_COMPLETED));
+  ASSERT_TRUE(callback_->receivedKeypressNotification);
 }
 
 TEST_F(SecurityManagerChannelTest, send_keypress_notification) {
   // Arrange
   auto packet =
-      hci::SendKeypressNotificationBuilder::Create(device_->GetAddress(), hci::KeypressNotificationType::ENTRY_STARTED);
+      hci::SendKeypressNotificationBuilder::Create(device_.GetAddress(), hci::KeypressNotificationType::ENTRY_STARTED);
 
   // Act
-  channel_->SendCommand(device_, std::move(packet));
+  channel_->SendCommand(std::move(packet));
   auto last_command = std::move(hci_layer_->GetLastCommand()->command);
   auto command_packet = GetPacketView(std::move(last_command));
   hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet);
 
   // Assert
-  EXPECT_TRUE(packet_view.IsValid());
-  EXPECT_EQ(OpCode::SEND_KEYPRESS_NOTIFICATION, packet_view.GetOpCode());
+  ASSERT_TRUE(packet_view.IsValid());
+  ASSERT_EQ(OpCode::SEND_KEYPRESS_NOTIFICATION, packet_view.GetOpCode());
+}
+
+TEST_F(SecurityManagerChannelTest, recv_user_passkey_request) {
+  hci_layer_->IncomingEvent(hci::UserPasskeyRequestBuilder::Create(device_.GetAddress()));
+  ASSERT_TRUE(callback_->receivedUserPasskeyRequest);
 }
 
 }  // namespace
diff --git a/gd/security/internal/security_manager_impl.cc b/gd/security/internal/security_manager_impl.cc
index b245ff9..92556c3 100644
--- a/gd/security/internal/security_manager_impl.cc
+++ b/gd/security/internal/security_manager_impl.cc
@@ -1,4 +1,4 @@
-/******************************************************************************
+/*
  *
  *  Copyright 2019 The Android Open Source Project
  *
@@ -14,88 +14,96 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- ******************************************************************************/
+ */
 #include "security_manager_impl.h"
 
 #include <iostream>
-#include <unordered_map>
 
+#include "hci/address_with_type.h"
 #include "os/log.h"
-#include "security/pairing/classic_pairing_handler.h"
 #include "security/security_manager.h"
 
-using namespace bluetooth::security::internal;
-using bluetooth::hci::Device;
-using bluetooth::hci::DeviceType;
-using bluetooth::security::ISecurityManagerListener;
-using bluetooth::security::pairing::PairingHandler;
+namespace bluetooth {
+namespace security {
+namespace internal {
 
-namespace {
-std::unordered_map<std::shared_ptr<Device>, std::unique_ptr<PairingHandler>> pairing_handler_map_;
+std::shared_ptr<bluetooth::security::record::SecurityRecord> SecurityManagerImpl::CreateSecurityRecord(
+    hci::Address address) {
+  hci::AddressWithType device(address, hci::AddressType::PUBLIC_DEVICE_ADDRESS);
+  // Security record check
+  auto entry = security_record_map_.find(device.GetAddress());
+  if (entry == security_record_map_.end()) {
+    LOG_INFO("No security record for device: %s ", device.ToString().c_str());
+    // Create one
+    std::shared_ptr<security::record::SecurityRecord> record =
+        std::make_shared<security::record::SecurityRecord>(device);
+    auto new_entry = std::pair<hci::Address, std::shared_ptr<security::record::SecurityRecord>>(
+        record->GetDevice().GetAddress(), record);
+    // Keep track of it
+    security_record_map_.insert(new_entry);
+    return record;
+  }
+  return entry->second;
+}
 
-void dispatch_new_pairing_handler(std::shared_ptr<bluetooth::security::record::SecurityRecord> record) {
-  auto entry = pairing_handler_map_.find(record->GetDevice());
+void SecurityManagerImpl::DispatchPairingHandler(std::shared_ptr<security::record::SecurityRecord> record,
+                                                 bool locally_initiated) {
+  common::OnceCallback<void(hci::Address)> callback =
+      common::BindOnce(&SecurityManagerImpl::OnPairingHandlerComplete, common::Unretained(this));
+  auto entry = pairing_handler_map_.find(record->GetDevice().GetAddress());
   if (entry != pairing_handler_map_.end()) {
     LOG_WARN("Device already has a pairing handler, and is in the middle of pairing!");
     return;
   }
-  std::unique_ptr<PairingHandler> pairing_handler = nullptr;
-  switch (record->GetDevice()->GetDeviceType()) {
-    case DeviceType::CLASSIC:
-      pairing_handler = std::make_unique<bluetooth::security::pairing::ClassicPairingHandler>(record);
+  std::shared_ptr<pairing::PairingHandler> pairing_handler = nullptr;
+  switch (record->GetDevice().GetAddressType()) {
+    case hci::AddressType::PUBLIC_DEVICE_ADDRESS:
+      pairing_handler = std::make_shared<security::pairing::ClassicPairingHandler>(
+          l2cap_classic_module_->GetFixedChannelManager(), security_manager_channel_, record, security_handler_,
+          std::move(callback));
       break;
     default:
-      ASSERT_LOG(false, "Pairing type %d not implemented!", record->GetDevice()->GetDeviceType());
+      ASSERT_LOG(false, "Pairing type %hhu not implemented!", record->GetDevice().GetAddressType());
   }
-  auto new_entry = std::pair<std::shared_ptr<Device>, std::unique_ptr<PairingHandler>>(record->GetDevice(),
-                                                                                       std::move(pairing_handler));
+  auto new_entry = std::pair<hci::Address, std::shared_ptr<pairing::PairingHandler>>(record->GetDevice().GetAddress(),
+                                                                                     pairing_handler);
   pairing_handler_map_.insert(std::move(new_entry));
+  pairing_handler->Initiate(locally_initiated, pairing::kDefaultIoCapability, pairing::kDefaultOobDataPresent,
+                            pairing::kDefaultAuthenticationRequirements);
 }
-}  // namespace
 
 void SecurityManagerImpl::Init() {
+  security_manager_channel_->SetChannelListener(this);
+  security_manager_channel_->SendCommand(hci::WriteSimplePairingModeBuilder::Create(hci::Enable::ENABLED));
+  security_manager_channel_->SendCommand(hci::WriteSecureConnectionsHostSupportBuilder::Create(hci::Enable::ENABLED));
   // TODO(optedoblivion): Populate security record memory map from disk
-  //  security_manager_channel_->SetChannelListener(this);
 }
 
-void SecurityManagerImpl::CreateBond(std::shared_ptr<hci::ClassicDevice> device) {
-  std::string uuid = device->GetUuid();
-  // Security record check
-  //  if (device_database_->GetDeviceById(uuid) != nullptr) {
-  //    LOG_WARN("Device already exists in the database");
-  // TODO(optedoblivion): Check security record if device is already bonded
-  // if no security record, need to initiate bonding
-  // if security record and not bonded, need to initiate bonding
-  // if security record and is bonded, then do nothing
-  //  }
-
-  // device_database_->AddDevice(device);
-  // Create security record
-  // Pass to pairing handler
-  std::shared_ptr<record::SecurityRecord> record = std::make_shared<record::SecurityRecord>(device);
-  dispatch_new_pairing_handler(record);
-  // init the pairing handler
-  // Update bonded flag on security record
-  // Update bonded flag on device to BONDING (pairing handler does this)
-}
-
-void SecurityManagerImpl::CancelBond(std::shared_ptr<hci::ClassicDevice> device) {
-  auto entry = pairing_handler_map_.find(device);
-  if (entry != pairing_handler_map_.end()) {
-    pairing_handler_map_.erase(device);
+void SecurityManagerImpl::CreateBond(hci::AddressWithType device) {
+  auto record = CreateSecurityRecord(device.GetAddress());
+  if (record->IsBonded()) {
+    NotifyDeviceBonded(device);
+  } else {
+    // Dispatch pairing handler, if we are calling create we are the initiator
+    DispatchPairingHandler(record, true);
   }
-  // Remove from DB
-  // device_database_->RemoveDevice(device);
-  // Remove from map, no longer will the event queue use it
-  // If currently bonding, cancel pairing handler job
-  // else, cancel fails
 }
 
-void SecurityManagerImpl::RemoveBond(std::shared_ptr<hci::ClassicDevice> device) {
+void SecurityManagerImpl::CancelBond(hci::AddressWithType device) {
+  auto entry = pairing_handler_map_.find(device.GetAddress());
+  if (entry != pairing_handler_map_.end()) {
+    pairing_handler_map_.erase(entry);
+    entry->second->Cancel();
+  }
+}
+
+void SecurityManagerImpl::RemoveBond(hci::AddressWithType device) {
   CancelBond(device);
-  // Update bonded flag on device to UNBONDED
+  auto entry = security_record_map_.find(device.GetAddress());
+  if (entry != security_record_map_.end()) {
+    security_record_map_.erase(entry);
+  }
   // Signal disconnect
-  // Signal unbonding
   // Remove security record
   // Signal Remove from database
 }
@@ -140,3 +148,82 @@
         common::Bind(&ISecurityManagerListener::OnDeviceUnbonded, common::Unretained(iter.first), device));
   }
 }
+
+template <class T>
+void SecurityManagerImpl::HandleEvent(T packet) {
+  ASSERT(packet.IsValid());
+  auto entry = pairing_handler_map_.find(packet.GetBdAddr());
+  if (entry != pairing_handler_map_.end()) {
+    entry->second->OnReceive(packet);
+  } else {
+    auto event = hci::EventPacketView::Create(std::move(packet));
+    ASSERT_LOG(event.IsValid(), "Received invalid packet");
+    const hci::EventCode code = event.GetEventCode();
+    auto record = CreateSecurityRecord(packet.GetBdAddr());
+    switch (code) {
+      case hci::EventCode::LINK_KEY_REQUEST:
+        DispatchPairingHandler(record, true);
+        break;
+      default:
+        LOG_ERROR("No classic pairing handler for device '%s' ready for command '%hhx' ",
+                  packet.GetBdAddr().ToString().c_str(), packet.GetEventCode());
+        break;
+    }
+  }
+}
+
+void SecurityManagerImpl::OnHciEventReceived(hci::EventPacketView packet) {
+  auto event = hci::EventPacketView::Create(packet);
+  ASSERT_LOG(event.IsValid(), "Received invalid packet");
+  const hci::EventCode code = event.GetEventCode();
+  switch (code) {
+    case hci::EventCode::PIN_CODE_REQUEST:
+      HandleEvent<hci::PinCodeRequestView>(hci::PinCodeRequestView::Create(event));
+      break;
+    case hci::EventCode::LINK_KEY_REQUEST:
+      HandleEvent(hci::LinkKeyRequestView::Create(event));
+      break;
+    case hci::EventCode::LINK_KEY_NOTIFICATION:
+      HandleEvent(hci::LinkKeyNotificationView::Create(event));
+      break;
+    case hci::EventCode::IO_CAPABILITY_REQUEST:
+      HandleEvent(hci::IoCapabilityRequestView::Create(event));
+      break;
+    case hci::EventCode::IO_CAPABILITY_RESPONSE:
+      HandleEvent(hci::IoCapabilityResponseView::Create(event));
+      break;
+    case hci::EventCode::SIMPLE_PAIRING_COMPLETE:
+      HandleEvent(hci::SimplePairingCompleteView::Create(event));
+      break;
+    case hci::EventCode::REMOTE_OOB_DATA_REQUEST:
+      HandleEvent(hci::RemoteOobDataRequestView::Create(event));
+      break;
+    case hci::EventCode::USER_PASSKEY_NOTIFICATION:
+      HandleEvent<hci::UserPasskeyNotificationView>(hci::UserPasskeyNotificationView::Create(event));
+      break;
+    case hci::EventCode::KEYPRESS_NOTIFICATION:
+      HandleEvent(hci::KeypressNotificationView::Create(event));
+      break;
+    case hci::EventCode::USER_CONFIRMATION_REQUEST:
+      HandleEvent(hci::UserConfirmationRequestView::Create(event));
+      break;
+    case hci::EventCode::USER_PASSKEY_REQUEST:
+      HandleEvent(hci::UserPasskeyRequestView::Create(event));
+      break;
+    default:
+      ASSERT_LOG(false, "Cannot handle received packet: %s", hci::EventCodeText(code).c_str());
+      break;
+  }
+}
+
+void SecurityManagerImpl::OnPairingHandlerComplete(hci::Address address) {
+  auto entry = pairing_handler_map_.find(address);
+  if (entry != pairing_handler_map_.end()) {
+    pairing_handler_map_.erase(entry);
+  }
+  NotifyDeviceBonded(hci::AddressWithType(address, hci::AddressType::PUBLIC_DEVICE_ADDRESS));
+}
+
+}  // namespace internal
+}  // namespace security
+}  // namespace bluetooth
diff --git a/gd/security/internal/security_manager_impl.h b/gd/security/internal/security_manager_impl.h
index d6768c9..fc43935 100644
--- a/gd/security/internal/security_manager_impl.h
+++ b/gd/security/internal/security_manager_impl.h
@@ -16,13 +16,16 @@
 
 #pragma once
 
+#include <unordered_map>
+#include <utility>
+
 #include "hci/classic_device.h"
 #include "l2cap/classic/l2cap_classic_module.h"
 #include "l2cap/le/l2cap_le_module.h"
 #include "os/handler.h"
 #include "security/channel/security_manager_channel.h"
-
-#include <utility>
+#include "security/pairing/classic_pairing_handler.h"
+#include "security/record/security_record.h"
 
 namespace bluetooth {
 namespace security {
@@ -31,7 +34,7 @@
 
 namespace internal {
 
-class SecurityManagerImpl /*: public channel::ISecurityManagerChannelListener*/ {
+class SecurityManagerImpl : public channel::ISecurityManagerChannelListener {
  public:
   explicit SecurityManagerImpl(os::Handler* security_handler, l2cap::le::L2capLeModule* l2cap_le_module,
                                l2cap::classic::L2capClassicModule* l2cap_classic_module,
@@ -53,7 +56,7 @@
    * @param device pointer to device we want to bond with
    * @return true if bonded or pairing started successfully, false if currently pairing
    */
-  void CreateBond(std::shared_ptr<hci::ClassicDevice> device);
+  void CreateBond(hci::AddressWithType device);
 
   /* void CreateBond(std::shared_ptr<hci::LeDevice> device); */
 
@@ -63,7 +66,7 @@
    * @param device pointer to device with which we want to cancel our bond
    * @return <code>true</code> if successfully stopped
    */
-  void CancelBond(std::shared_ptr<bluetooth::hci::ClassicDevice> device);
+  void CancelBond(hci::AddressWithType device);
 
   /* void CancelBond(std::shared_ptr<hci::LeDevice> device); */
 
@@ -73,7 +76,7 @@
    * @param device pointer to device we want to forget
    * @return true if removed
    */
-  void RemoveBond(std::shared_ptr<bluetooth::hci::ClassicDevice> device);
+  void RemoveBond(hci::AddressWithType device);
 
   /* void RemoveBond(std::shared_ptr<hci::LeDevice> device); */
 
@@ -91,33 +94,30 @@
    */
   void UnregisterCallbackListener(ISecurityManagerListener* listener);
 
+  // ISecurityManagerChannel
+  void OnHciEventReceived(hci::EventPacketView packet) override;
+
+  void OnPairingHandlerComplete(hci::Address address);
+
  protected:
   std::vector<std::pair<ISecurityManagerListener*, os::Handler*>> listeners_;
   void NotifyDeviceBonded(hci::AddressWithType device);
   void NotifyDeviceBondFailed(hci::AddressWithType device);
   void NotifyDeviceUnbonded(hci::AddressWithType device);
 
-  // ISecurityManagerChannel
-  void OnChangeConnectionLinkKeyComplete(std::shared_ptr<hci::Device> device,
-                                         hci::ChangeConnectionLinkKeyCompleteView packet);
-  void OnMasterLinkKeyComplete(std::shared_ptr<hci::Device> device, hci::MasterLinkKeyCompleteView packet);
-  void OnPinCodeRequest(std::shared_ptr<hci::Device> device, hci::PinCodeRequestView packet);
-  void OnLinkKeyRequest(std::shared_ptr<hci::Device> device, hci::LinkKeyRequestView packet);
-  void OnLinkKeyNotification(std::shared_ptr<hci::Device> device, hci::LinkKeyNotificationView packet);
-  void OnIoCapabilityRequest(std::shared_ptr<hci::Device> device, hci::IoCapabilityRequestView packet);
-  void OnIoCapabilityResponse(std::shared_ptr<hci::Device> device, hci::IoCapabilityResponseView packet);
-  void OnSimplePairingComplete(std::shared_ptr<hci::Device> device, hci::SimplePairingCompleteView packet);
-  void OnReturnLinkKeys(std::shared_ptr<hci::Device> device, hci::ReturnLinkKeysView packet);
-  void OnEncryptionChange(std::shared_ptr<hci::Device> device, hci::EncryptionChangeView packet);
-  void OnEncryptionKeyRefreshComplete(std::shared_ptr<hci::Device> device,
-                                      hci::EncryptionKeyRefreshCompleteView packet);
-  void OnRemoteOobDataRequest(std::shared_ptr<hci::Device> device, hci::RemoteOobDataRequestView packet);
-
  private:
+  template <class T>
+  void HandleEvent(T packet);
+
+  std::shared_ptr<record::SecurityRecord> CreateSecurityRecord(hci::Address address);
+  void DispatchPairingHandler(std::shared_ptr<record::SecurityRecord> record, bool locally_initiated);
+
   os::Handler* security_handler_ __attribute__((unused));
   l2cap::le::L2capLeModule* l2cap_le_module_ __attribute__((unused));
   l2cap::classic::L2capClassicModule* l2cap_classic_module_ __attribute__((unused));
   channel::SecurityManagerChannel* security_manager_channel_ __attribute__((unused));
+  std::unordered_map<hci::Address, std::shared_ptr<record::SecurityRecord>> security_record_map_;
+  std::unordered_map<hci::Address, std::shared_ptr<pairing::PairingHandler>> pairing_handler_map_;
 };
 }  // namespace internal
 }  // namespace security
diff --git a/gd/security/pairing/Android.bp b/gd/security/pairing/Android.bp
new file mode 100644
index 0000000..350c10e
--- /dev/null
+++ b/gd/security/pairing/Android.bp
@@ -0,0 +1,13 @@
+filegroup {
+    name: "BluetoothSecurityPairingSources",
+    srcs: [
+        "classic_pairing_handler.cc",
+    ]
+}
+
+filegroup {
+    name: "BluetoothSecurityPairingTestSources",
+    srcs: [
+        "classic_pairing_handler_unittest.cc",
+    ]
+}
diff --git a/gd/security/pairing/classic_pairing_handler.cc b/gd/security/pairing/classic_pairing_handler.cc
new file mode 100644
index 0000000..e854efe
--- /dev/null
+++ b/gd/security/pairing/classic_pairing_handler.cc
@@ -0,0 +1,343 @@
+/*
+ *
+ *  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 "security/pairing/classic_pairing_handler.h"
+
+namespace bluetooth {
+namespace security {
+namespace pairing {
+
+void ClassicPairingHandler::OnRegistrationComplete(
+    l2cap::classic::FixedChannelManager::RegistrationResult result,
+    std::unique_ptr<l2cap::classic::FixedChannelService> fixed_channel_service) {
+  fixed_channel_service_ = std::move(fixed_channel_service);
+  fixed_channel_manager_->ConnectServices(
+      GetRecord()->GetDevice().GetAddress(),
+      common::Bind(&ClassicPairingHandler::OnConnectionFail, common::Unretained(this)), security_handler_);
+}
+
+void ClassicPairingHandler::OnUnregistered() {
+  std::move(complete_callback_).Run(GetRecord()->GetDevice().GetAddress());
+}
+
+void ClassicPairingHandler::OnConnectionOpen(std::unique_ptr<l2cap::classic::FixedChannel> fixed_channel) {
+  ASSERT(fixed_channel_ == nullptr);
+  fixed_channel_ = std::move(fixed_channel);
+  fixed_channel_->Acquire();
+  fixed_channel_->RegisterOnCloseCallback(
+      security_handler_, common::BindOnce(&ClassicPairingHandler::OnConnectionClose, common::Unretained(this)));
+}
+
+void ClassicPairingHandler::OnConnectionFail(l2cap::classic::FixedChannelManager::ConnectionResult result) {
+  Cancel();
+}
+void ClassicPairingHandler::OnConnectionClose(hci::ErrorCode error_code) {
+  // Called when the connection gets closed
+  LOG_ERROR("Connection closed due to: %s", hci::ErrorCodeText(error_code).c_str());
+  ASSERT(fixed_channel_ != nullptr);
+  Cancel();
+}
+
+void ClassicPairingHandler::Initiate(bool locally_initiated, hci::IoCapability io_capability,
+                                     hci::OobDataPresent oob_present,
+                                     hci::AuthenticationRequirements auth_requirements) {
+  locally_initiated_ = locally_initiated;
+  local_io_capability_ = io_capability;
+  local_oob_present_ = oob_present;
+  local_authentication_requirements_ = auth_requirements;
+
+  // TODO(optedoblivion): Read OOB data
+  // if host and controller support secure connections used HCIREADLOCALOOBEXTENDEDDATA vs HCIREADLOCALOOBDATA
+
+  fixed_channel_manager_->RegisterService(
+      l2cap::kClassicPairingTriggerCid, security_policy_,
+      common::Bind(&ClassicPairingHandler::OnRegistrationComplete, common::Unretained(this)),
+      common::Bind(&ClassicPairingHandler::OnConnectionOpen, common::Unretained(this)), security_handler_);
+}
+
+void ClassicPairingHandler::Cancel() {
+  if (fixed_channel_ != nullptr) {
+    fixed_channel_->Release();
+  }
+  if (fixed_channel_service_ != nullptr) {
+    fixed_channel_service_->Unregister(common::Bind(&ClassicPairingHandler::OnUnregistered, common::Unretained(this)),
+                                       security_handler_);
+  }
+}
+
+void ClassicPairingHandler::OnReceive(hci::ChangeConnectionLinkKeyCompleteView packet) {
+  ASSERT(packet.IsValid());
+  LOG_INFO("Received unsupported event: %s", hci::EventCodeText(packet.GetEventCode()).c_str());
+}
+
+void ClassicPairingHandler::OnReceive(hci::MasterLinkKeyCompleteView packet) {
+  ASSERT(packet.IsValid());
+  LOG_INFO("Received unsupported event: %s", hci::EventCodeText(packet.GetEventCode()).c_str());
+}
+
+void ClassicPairingHandler::OnReceive(hci::PinCodeRequestView packet) {
+  ASSERT(packet.IsValid());
+  LOG_INFO("Received: %s", hci::EventCodeText(packet.GetEventCode()).c_str());
+  ASSERT_LOG(GetRecord()->GetDevice().GetAddress() == packet.GetBdAddr(), "Address mismatch");
+}
+
+void ClassicPairingHandler::OnReceive(hci::LinkKeyRequestView packet) {
+  ASSERT(packet.IsValid());
+  // TODO(optedoblivion): Add collision detection here
+  LOG_INFO("Received: %s", hci::EventCodeText(packet.GetEventCode()).c_str());
+  ASSERT_LOG(GetRecord()->GetDevice().GetAddress() == packet.GetBdAddr(), "Address mismatch");
+  if (GetRecord()->IsBonded() || GetRecord()->IsPaired()) {
+    auto packet =
+        hci::LinkKeyRequestReplyBuilder::Create(GetRecord()->GetDevice().GetAddress(), GetRecord()->GetLinkKey());
+    this->GetChannel()->SendCommand(std::move(packet));
+  } else {
+    auto packet = hci::LinkKeyRequestNegativeReplyBuilder::Create(GetRecord()->GetDevice().GetAddress());
+    this->GetChannel()->SendCommand(std::move(packet));
+  }
+}
+
+void ClassicPairingHandler::OnReceive(hci::LinkKeyNotificationView packet) {
+  ASSERT(packet.IsValid());
+  LOG_INFO("Received: %s", hci::EventCodeText(packet.GetEventCode()).c_str());
+  ASSERT_LOG(GetRecord()->GetDevice().GetAddress() == packet.GetBdAddr(), "Address mismatch");
+  GetRecord()->SetLinkKey(packet.GetLinkKey(), packet.GetKeyType());
+}
+
+void ClassicPairingHandler::OnReceive(hci::IoCapabilityRequestView packet) {
+  ASSERT(packet.IsValid());
+  LOG_INFO("Received: %s", hci::EventCodeText(packet.GetEventCode()).c_str());
+  ASSERT_LOG(GetRecord()->GetDevice().GetAddress() == packet.GetBdAddr(), "Address mismatch");
+  hci::IoCapability io_capability = local_io_capability_;
+  hci::OobDataPresent oob_present = hci::OobDataPresent::NOT_PRESENT;
+  hci::AuthenticationRequirements authentication_requirements = local_authentication_requirements_;
+  auto reply_packet = hci::IoCapabilityRequestReplyBuilder::Create(GetRecord()->GetDevice().GetAddress(), io_capability,
+                                                                   oob_present, authentication_requirements);
+  this->GetChannel()->SendCommand(std::move(reply_packet));
+}
+
+void ClassicPairingHandler::OnReceive(hci::IoCapabilityResponseView packet) {
+  ASSERT(packet.IsValid());
+  LOG_INFO("Received: %s", hci::EventCodeText(packet.GetEventCode()).c_str());
+  ASSERT_LOG(GetRecord()->GetDevice().GetAddress() == packet.GetBdAddr(), "Address mismatch");
+
+  // Using local variable until device database pointer is ready
+  remote_io_capability_ = packet.GetIoCapability();
+  // TODO(optedoblivion): device->SetIoCapability(packet.GetIoCapability);
+}
+
+void ClassicPairingHandler::OnReceive(hci::SimplePairingCompleteView packet) {
+  ASSERT(packet.IsValid());
+  LOG_INFO("Received: %s", hci::EventCodeText(packet.GetEventCode()).c_str());
+  ASSERT_LOG(GetRecord()->GetDevice().GetAddress() == packet.GetBdAddr(), "Address mismatch");
+  Cancel();
+}
+
+void ClassicPairingHandler::OnReceive(hci::ReturnLinkKeysView packet) {
+  ASSERT(packet.IsValid());
+  LOG_INFO("Received: %s", hci::EventCodeText(packet.GetEventCode()).c_str());
+}
+
+void ClassicPairingHandler::OnReceive(hci::EncryptionChangeView packet) {
+  ASSERT(packet.IsValid());
+  LOG_INFO("Received: %s", hci::EventCodeText(packet.GetEventCode()).c_str());
+}
+
+void ClassicPairingHandler::OnReceive(hci::EncryptionKeyRefreshCompleteView packet) {
+  ASSERT(packet.IsValid());
+  LOG_INFO("Received: %s", hci::EventCodeText(packet.GetEventCode()).c_str());
+}
+
+void ClassicPairingHandler::OnReceive(hci::RemoteOobDataRequestView packet) {
+  ASSERT(packet.IsValid());
+  LOG_INFO("Received: %s", hci::EventCodeText(packet.GetEventCode()).c_str());
+  ASSERT_LOG(GetRecord()->GetDevice().GetAddress() == packet.GetBdAddr(), "Address mismatch");
+}
+
+void ClassicPairingHandler::OnReceive(hci::UserPasskeyNotificationView packet) {
+  ASSERT(packet.IsValid());
+  LOG_INFO("Received: %s", hci::EventCodeText(packet.GetEventCode()).c_str());
+  ASSERT_LOG(GetRecord()->GetDevice().GetAddress() == packet.GetBdAddr(), "Address mismatch");
+}
+
+void ClassicPairingHandler::OnReceive(hci::KeypressNotificationView packet) {
+  ASSERT(packet.IsValid());
+  LOG_INFO("Received: %s", hci::EventCodeText(packet.GetEventCode()).c_str());
+  LOG_INFO("Notification Type: %s", hci::KeypressNotificationTypeText(packet.GetNotificationType()).c_str());
+  switch (packet.GetNotificationType()) {
+    case hci::KeypressNotificationType::ENTRY_STARTED:
+      // Get ready to keep track of key input
+      break;
+    case hci::KeypressNotificationType::DIGIT_ENTERED:
+      // Append digit to key
+      break;
+    case hci::KeypressNotificationType::DIGIT_ERASED:
+      // erase last digit from key
+      break;
+    case hci::KeypressNotificationType::CLEARED:
+      // erase all digits from key
+      break;
+    case hci::KeypressNotificationType::ENTRY_COMPLETED:
+      // set full key to security record
+      break;
+  }
+}
+
+/**
+ * Here we decide what type of pairing authentication method we will use
+ *
+ * The table is on pg 2133 of the Core v5.1 spec.
+ */
+void ClassicPairingHandler::OnReceive(hci::UserConfirmationRequestView packet) {
+  ASSERT(packet.IsValid());
+  LOG_INFO("Received: %s", hci::EventCodeText(packet.GetEventCode()).c_str());
+  ASSERT_LOG(GetRecord()->GetDevice().GetAddress() == packet.GetBdAddr(), "Address mismatch");
+  // if locally_initialized, use default, otherwise us remote io caps
+  hci::IoCapability initiator_io_capability = (locally_initiated_) ? local_io_capability_ : remote_io_capability_;
+  hci::IoCapability responder_io_capability = (!locally_initiated_) ? local_io_capability_ : remote_io_capability_;
+  // TODO(optedoblivion): Check for TEMPORARY pairing case
+  switch (initiator_io_capability) {
+    case hci::IoCapability::DISPLAY_ONLY:
+      switch (responder_io_capability) {
+        case hci::IoCapability::DISPLAY_ONLY:
+          // NumericComparison, Both auto confirm
+          LOG_INFO("Numeric Comparison: A and B auto confirm");
+          GetChannel()->SendCommand(
+              hci::UserConfirmationRequestReplyBuilder::Create(GetRecord()->GetDevice().GetAddress()));
+          // Unauthenticated
+          break;
+        case hci::IoCapability::DISPLAY_YES_NO:
+          // NumericComparison, Initiator auto confirm, Responder display
+          GetChannel()->SendCommand(
+              hci::UserConfirmationRequestReplyBuilder::Create(GetRecord()->GetDevice().GetAddress()));
+          LOG_INFO("Numeric Comparison: A auto confirm");
+          // Unauthenticated
+          break;
+        case hci::IoCapability::KEYBOARD_ONLY:
+          // PassKey Entry, Initiator display, Responder input
+          // TODO(optedoblivion): Notify UI
+          LOG_INFO("Notify UI");
+          // Authenticated
+          break;
+        case hci::IoCapability::NO_INPUT_NO_OUTPUT:
+          // NumericComparison, Both auto confirm
+          LOG_INFO("Numeric Comparison: A and B auto confirm");
+          GetChannel()->SendCommand(
+              hci::UserConfirmationRequestReplyBuilder::Create(GetRecord()->GetDevice().GetAddress()));
+          // Unauthenticated
+          break;
+      }
+      break;
+    case hci::IoCapability::DISPLAY_YES_NO:
+      switch (responder_io_capability) {
+        case hci::IoCapability::DISPLAY_ONLY:
+          // NumericComparison, Initiator display, Responder auto confirm
+          // TODO(optedoblivion): Notify UI
+          LOG_INFO("Notify UI");
+          // Unauthenticated
+          break;
+        case hci::IoCapability::DISPLAY_YES_NO:
+          // NumericComparison Both Display, Both confirm
+          // TODO(optedoblivion): Notify UI
+          LOG_INFO("Notify UI");
+          // Authenticated
+          break;
+        case hci::IoCapability::KEYBOARD_ONLY:
+          // PassKey Entry, Initiator display, Responder input
+          // TODO(optedoblivion): Notify UI
+          LOG_INFO("Notify UI");
+          // Authenticated
+          break;
+        case hci::IoCapability::NO_INPUT_NO_OUTPUT:
+          // NumericComparison, auto confirm Responder, Yes/No confirm Initiator. Don't show confirmation value
+          // TODO(optedoblivion): Notify UI
+          LOG_INFO("Notify UI");
+          // Unauthenticated
+          break;
+      }
+      break;
+    case hci::IoCapability::KEYBOARD_ONLY:
+      switch (responder_io_capability) {
+        case hci::IoCapability::DISPLAY_ONLY:
+          // PassKey Entry, Responder display, Initiator input
+          // TODO(optedoblivion): Notify UI
+          LOG_INFO("Notify UI");
+          // Authenticated
+          break;
+        case hci::IoCapability::DISPLAY_YES_NO:
+          // PassKey Entry, Responder display, Initiator input
+          // TODO(optedoblivion): Notify UI
+          LOG_INFO("Notify UI");
+          // Authenticated
+          break;
+        case hci::IoCapability::KEYBOARD_ONLY:
+          // PassKey Entry, both input
+          // TODO(optedoblivion): Notify UI
+          LOG_INFO("Notify UI");
+          // Authenticated
+          break;
+        case hci::IoCapability::NO_INPUT_NO_OUTPUT:
+          // NumericComparison, both auto confirm
+          LOG_INFO("Numeric Comparison: A and B auto confirm");
+          GetChannel()->SendCommand(
+              hci::UserConfirmationRequestReplyBuilder::Create(GetRecord()->GetDevice().GetAddress()));
+          // Unauthenticated
+          break;
+      }
+      break;
+    case hci::IoCapability::NO_INPUT_NO_OUTPUT:
+      switch (responder_io_capability) {
+        case hci::IoCapability::DISPLAY_ONLY:
+          // NumericComparison, both auto confirm
+          LOG_INFO("Numeric Comparison: A and B auto confirm");
+          GetChannel()->SendCommand(
+              hci::UserConfirmationRequestReplyBuilder::Create(GetRecord()->GetDevice().GetAddress()));
+          // Unauthenticated
+          break;
+        case hci::IoCapability::DISPLAY_YES_NO:
+          // NumericComparison, Initiator auto confirm, Responder Yes/No confirm, no show conf val
+          LOG_INFO("Numeric Comparison: A auto confirm");
+          GetChannel()->SendCommand(
+              hci::UserConfirmationRequestReplyBuilder::Create(GetRecord()->GetDevice().GetAddress()));
+          // Unauthenticated
+          break;
+        case hci::IoCapability::KEYBOARD_ONLY:
+          // NumericComparison, both auto confirm
+          LOG_INFO("Numeric Comparison: A and B auto confirm");
+          GetChannel()->SendCommand(
+              hci::UserConfirmationRequestReplyBuilder::Create(GetRecord()->GetDevice().GetAddress()));
+          // Unauthenticated
+          break;
+        case hci::IoCapability::NO_INPUT_NO_OUTPUT:
+          // NumericComparison, both auto confirm
+          LOG_INFO("Numeric Comparison: A and B auto confirm");
+          GetChannel()->SendCommand(
+              hci::UserConfirmationRequestReplyBuilder::Create(GetRecord()->GetDevice().GetAddress()));
+          // Unauthenticated
+          break;
+      }
+      break;
+  }
+}
+
+void ClassicPairingHandler::OnReceive(hci::UserPasskeyRequestView packet) {
+  ASSERT(packet.IsValid());
+  ASSERT_LOG(GetRecord()->GetDevice().GetAddress() == packet.GetBdAddr(), "Address mismatch");
+}
+
+}  // namespace pairing
+}  // namespace security
+}  // namespace bluetooth
\ No newline at end of file
diff --git a/gd/security/pairing/classic_pairing_handler.h b/gd/security/pairing/classic_pairing_handler.h
index fc8eed4..f8a9d39 100644
--- a/gd/security/pairing/classic_pairing_handler.h
+++ b/gd/security/pairing/classic_pairing_handler.h
@@ -1,4 +1,4 @@
-/******************************************************************************
+/*
  *
  *  Copyright 2019 The Android Open Source Project
  *
@@ -14,27 +14,79 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- ******************************************************************************/
+ */
 #pragma once
 
-#include "pairing_handler.h"
+#include "security/pairing/pairing_handler.h"
 
-#include "security/smp_packets.h"
+#include <utility>
 
-using namespace bluetooth::security::pairing;
+#include "l2cap/classic/l2cap_classic_module.h"
 
 namespace bluetooth {
 namespace security {
 namespace pairing {
 
+static constexpr hci::IoCapability kDefaultIoCapability = hci::IoCapability::DISPLAY_YES_NO;
+static constexpr hci::OobDataPresent kDefaultOobDataPresent = hci::OobDataPresent::NOT_PRESENT;
+static constexpr hci::AuthenticationRequirements kDefaultAuthenticationRequirements =
+    hci::AuthenticationRequirements::DEDICATED_BONDING_MITM_PROTECTION;
+
 class ClassicPairingHandler : public PairingHandler {
  public:
-  explicit ClassicPairingHandler(std::shared_ptr<record::SecurityRecord> record) : PairingHandler(record) {}
+  ClassicPairingHandler(std::shared_ptr<l2cap::classic::FixedChannelManager> fixed_channel_manager,
+                        channel::SecurityManagerChannel* security_manager_channel,
+                        std::shared_ptr<record::SecurityRecord> record, os::Handler* security_handler,
+                        common::OnceCallback<void(hci::Address)> complete_callback)
+      : PairingHandler(security_manager_channel, std::move(record)),
+        fixed_channel_manager_(std::move(fixed_channel_manager)), security_policy_(),
+        security_handler_(security_handler), remote_io_capability_(kDefaultIoCapability),
+        local_io_capability_(kDefaultIoCapability), local_oob_present_(kDefaultOobDataPresent),
+        local_authentication_requirements_(kDefaultAuthenticationRequirements),
+        complete_callback_(std::move(complete_callback)) {}
 
-  void Init() {
-    // Set auth required
-    // Connect to device
-  }
+  ~ClassicPairingHandler() override = default;
+
+  void Initiate(bool locally_initiated, hci::IoCapability io_capability, hci::OobDataPresent oob_present,
+                hci::AuthenticationRequirements auth_requirements) override;
+  void Cancel() override;
+
+  void OnReceive(hci::ChangeConnectionLinkKeyCompleteView packet) override;
+  void OnReceive(hci::MasterLinkKeyCompleteView packet) override;
+  void OnReceive(hci::PinCodeRequestView packet) override;
+  void OnReceive(hci::LinkKeyRequestView packet) override;
+  void OnReceive(hci::LinkKeyNotificationView packet) override;
+  void OnReceive(hci::IoCapabilityRequestView packet) override;
+  void OnReceive(hci::IoCapabilityResponseView packet) override;
+  void OnReceive(hci::SimplePairingCompleteView packet) override;
+  void OnReceive(hci::ReturnLinkKeysView packet) override;
+  void OnReceive(hci::EncryptionChangeView packet) override;
+  void OnReceive(hci::EncryptionKeyRefreshCompleteView packet) override;
+  void OnReceive(hci::RemoteOobDataRequestView packet) override;
+  void OnReceive(hci::UserPasskeyNotificationView packet) override;
+  void OnReceive(hci::KeypressNotificationView packet) override;
+  void OnReceive(hci::UserConfirmationRequestView packet) override;
+  void OnReceive(hci::UserPasskeyRequestView packet) override;
+
+ private:
+  void OnRegistrationComplete(l2cap::classic::FixedChannelManager::RegistrationResult result,
+                              std::unique_ptr<l2cap::classic::FixedChannelService> fixed_channel_service);
+  void OnUnregistered();
+  void OnConnectionOpen(std::unique_ptr<l2cap::classic::FixedChannel> fixed_channel);
+  void OnConnectionFail(l2cap::classic::FixedChannelManager::ConnectionResult result);
+  void OnConnectionClose(hci::ErrorCode error_code);
+
+  std::shared_ptr<l2cap::classic::FixedChannelManager> fixed_channel_manager_;
+  std::unique_ptr<l2cap::classic::FixedChannelService> fixed_channel_service_{nullptr};
+  l2cap::SecurityPolicy security_policy_ __attribute__((unused));
+  os::Handler* security_handler_ __attribute__((unused));
+  hci::IoCapability remote_io_capability_ __attribute__((unused));
+  hci::IoCapability local_io_capability_ __attribute__((unused));
+  hci::OobDataPresent local_oob_present_ __attribute__((unused));
+  hci::AuthenticationRequirements local_authentication_requirements_ __attribute__((unused));
+  std::unique_ptr<l2cap::classic::FixedChannel> fixed_channel_{nullptr};
+  common::OnceCallback<void(hci::Address)> complete_callback_;
+  bool locally_initiated_ = false;
 };
 
 }  // namespace pairing
diff --git a/gd/security/pairing/classic_pairing_handler_unittest.cc b/gd/security/pairing/classic_pairing_handler_unittest.cc
new file mode 100644
index 0000000..9266303
--- /dev/null
+++ b/gd/security/pairing/classic_pairing_handler_unittest.cc
@@ -0,0 +1,503 @@
+/*
+ *
+ *  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 "security/pairing/classic_pairing_handler.h"
+
+#include <gtest/gtest.h>
+#include <memory>
+
+#include "hci/hci_packets.h"
+#include "l2cap/classic/fixed_channel_manager_mock.h"
+#include "packet/raw_builder.h"
+#include "security/channel/security_manager_channel.h"
+#include "security/smp_packets.h"
+#include "security/test/fake_hci_layer.h"
+
+namespace bluetooth {
+namespace security {
+namespace channel {
+namespace {
+
+using bluetooth::security::channel::SecurityManagerChannel;
+using hci::Address;
+using hci::AuthenticationRequirements;
+using hci::CommandCompleteBuilder;
+using hci::IoCapabilityRequestReplyBuilder;
+using hci::IoCapabilityRequestView;
+using hci::OobDataPresent;
+using hci::OpCode;
+using os::Handler;
+using os::Thread;
+using packet::RawBuilder;
+
+class SecurityManagerChannelCallback : public ISecurityManagerChannelListener {
+ public:
+  explicit SecurityManagerChannelCallback(pairing::ClassicPairingHandler* pairing_handler)
+      : pairing_handler_(pairing_handler) {}
+  void OnHciEventReceived(hci::EventPacketView packet) override {
+    auto event = hci::EventPacketView::Create(packet);
+    ASSERT_LOG(event.IsValid(), "Received invalid packet");
+    const hci::EventCode code = event.GetEventCode();
+    switch (code) {
+      case hci::EventCode::PIN_CODE_REQUEST:
+        pairing_handler_->OnReceive(hci::PinCodeRequestView::Create(event));
+        break;
+      case hci::EventCode::LINK_KEY_REQUEST:
+        pairing_handler_->OnReceive(hci::LinkKeyRequestView::Create(event));
+        break;
+      case hci::EventCode::LINK_KEY_NOTIFICATION:
+        pairing_handler_->OnReceive(hci::LinkKeyNotificationView::Create(event));
+        break;
+      case hci::EventCode::IO_CAPABILITY_REQUEST:
+        pairing_handler_->OnReceive(hci::IoCapabilityRequestView::Create(event));
+        break;
+      case hci::EventCode::IO_CAPABILITY_RESPONSE:
+        pairing_handler_->OnReceive(hci::IoCapabilityResponseView::Create(event));
+        break;
+      case hci::EventCode::SIMPLE_PAIRING_COMPLETE:
+        pairing_handler_->OnReceive(hci::SimplePairingCompleteView::Create(event));
+        break;
+      case hci::EventCode::RETURN_LINK_KEYS:
+        pairing_handler_->OnReceive(hci::ReturnLinkKeysView::Create(event));
+        break;
+      case hci::EventCode::REMOTE_OOB_DATA_REQUEST:
+        pairing_handler_->OnReceive(hci::RemoteOobDataRequestView::Create(event));
+        break;
+      case hci::EventCode::USER_PASSKEY_NOTIFICATION:
+        pairing_handler_->OnReceive(hci::UserPasskeyNotificationView::Create(event));
+        break;
+      case hci::EventCode::KEYPRESS_NOTIFICATION:
+        pairing_handler_->OnReceive(hci::KeypressNotificationView::Create(event));
+        break;
+      case hci::EventCode::USER_CONFIRMATION_REQUEST:
+        pairing_handler_->OnReceive(hci::UserConfirmationRequestView::Create(event));
+        break;
+      case hci::EventCode::USER_PASSKEY_REQUEST:
+        pairing_handler_->OnReceive(hci::UserPasskeyRequestView::Create(event));
+        break;
+      default:
+        ASSERT_LOG(false, "Cannot handle received packet: %s", hci::EventCodeText(code).c_str());
+        break;
+    }
+  }
+
+ private:
+  pairing::ClassicPairingHandler* pairing_handler_ = nullptr;
+};
+
+static void pairing_complete_callback(bluetooth::hci::Address address) {}
+
+class ClassicPairingHandlerTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    handler_ = new Handler(&thread_);
+    hci_layer_ = new FakeHciLayer();
+    channel_ = new channel::SecurityManagerChannel(handler_, hci_layer_);
+    fake_registry_.InjectTestModule(&FakeHciLayer::Factory, hci_layer_);
+    fake_registry_.Start<FakeHciLayer>(&thread_);
+    security_record_ = std::make_shared<record::SecurityRecord>(device_);
+    std::shared_ptr<l2cap::classic::testing::MockFixedChannelManager> sptr =
+        std::shared_ptr<l2cap::classic::testing::MockFixedChannelManager>(
+            new l2cap::classic::testing::MockFixedChannelManager);
+    EXPECT_CALL(*sptr, RegisterService(::testing::_, ::testing::_, ::testing::_, ::testing::_, ::testing::_))
+        .Times(::testing::AnyNumber());
+    pairing_handler_ = new pairing::ClassicPairingHandler(sptr, channel_, security_record_, handler_,
+                                                          common::Bind(&pairing_complete_callback));
+    channel_callback_ = new SecurityManagerChannelCallback(pairing_handler_);
+    channel_->SetChannelListener(channel_callback_);
+  }
+
+  void TearDown() override {
+    channel_->SetChannelListener(nullptr);
+    handler_->Clear();
+    fake_registry_.SynchronizeModuleHandler(&FakeHciLayer::Factory, std::chrono::milliseconds(20));
+    fake_registry_.StopAll();
+    delete pairing_handler_;
+    delete handler_;
+    delete channel_;
+    delete channel_callback_;
+  }
+
+  TestModuleRegistry fake_registry_;
+  Thread& thread_ = fake_registry_.GetTestThread();
+  Handler* handler_ = nullptr;
+  FakeHciLayer* hci_layer_ = nullptr;
+  hci::AddressWithType device_;
+  SecurityManagerChannelCallback* channel_callback_ = nullptr;
+  channel::SecurityManagerChannel* channel_ = nullptr;
+  pairing::ClassicPairingHandler* pairing_handler_ = nullptr;
+  std::shared_ptr<record::SecurityRecord> security_record_ = nullptr;
+};
+
+// Security Manager Boot Sequence (Required for SSP, these are already set at boot time)
+//  - WriteSimplePairingMode
+//  - WriteSecureConnectionsHostSupport
+//  - WriteAuthenticatedPayloadTimeout
+
+/*** Locally initiated ***/
+// Security Pairing Sequence (JustWorks)
+//  -> *Establish L2CAP connection*
+//  -> AuthenticationRequested (should L2CAP request secure service which causes this?)
+//  <- LinkKeyRequest
+//  -> LinkKeyRequestNegativeReply
+//  <- IoCapabilityRequest
+//  -> IoCapabilityRequestReply
+//  <- IoCapabilityResponse
+//  <- UserConfirmationRequest
+//  -> UserConfirmationRequestReply (auto)
+//  <- SimplePairingComplete
+//  <- LinkKeyNotification
+//  <- AuthenticationComplete
+//  -> SetConnectionEncryption
+//  <- EncryptionChange
+//  -> L2capConnectionResponse (if triggered by L2cap connection request)
+
+void ReceiveLinkKeyRequest(FakeHciLayer* hci_layer, hci::AddressWithType device) {
+  hci_layer->IncomingEvent(hci::LinkKeyRequestBuilder::Create(device.GetAddress()));
+}
+
+void ReceiveIoCapabilityRequest(FakeHciLayer* hci_layer, hci::AddressWithType device) {
+  hci_layer->IncomingEvent(hci::IoCapabilityRequestBuilder::Create(device.GetAddress()));
+}
+
+void ReceiveIoCapabilityResponse(FakeHciLayer* hci_layer, hci::AddressWithType device, hci::IoCapability io_cap,
+                                 hci::OobDataPresent oob_present, hci::AuthenticationRequirements auth_reqs) {
+  hci_layer->IncomingEvent(
+      hci::IoCapabilityResponseBuilder::Create(device.GetAddress(), io_cap, oob_present, auth_reqs));
+}
+
+void ReceiveUserConfirmationRequest(FakeHciLayer* hci_layer, hci::AddressWithType device, uint32_t numeric_value) {
+  hci_layer->IncomingEvent(hci::UserConfirmationRequestBuilder::Create(device.GetAddress(), numeric_value));
+}
+
+void ReceiveSimplePairingComplete(FakeHciLayer* hci_layer, hci::ErrorCode status, hci::AddressWithType device) {
+  hci_layer->IncomingEvent(hci::SimplePairingCompleteBuilder::Create(status, device.GetAddress()));
+}
+
+void ReceiveLinkKeyNotification(FakeHciLayer* hci_layer, hci::AddressWithType device, std::array<uint8_t, 16> link_key,
+                                hci::KeyType key_type) {
+  hci_layer->IncomingEvent(hci::LinkKeyNotificationBuilder::Create(device.GetAddress(), link_key, key_type));
+}
+
+hci::SecurityCommandView GetLastCommand(FakeHciLayer* hci_layer) {
+  auto last_command = std::move(hci_layer->GetLastCommand()->command);
+  auto command_packet = GetPacketView(std::move(last_command));
+  auto command_packet_view = hci::CommandPacketView::Create(command_packet);
+  ASSERT(command_packet_view.IsValid());
+  auto security_command_view = hci::SecurityCommandView::Create(command_packet_view);
+  ASSERT(security_command_view.IsValid());
+  return security_command_view;
+}
+
+TEST_F(ClassicPairingHandlerTest, setup_teardown) {}
+
+// display_only + display_only is JustWorks no confirmation
+// Needs dialog as per security a bug unless pairing is temporary
+TEST_F(ClassicPairingHandlerTest, locally_initiatied_display_only_display_only_temp) {
+  hci::IoCapability injected_io_capability = hci::IoCapability::DISPLAY_ONLY;
+  hci::AuthenticationRequirements injected_authentication_requirements = hci::AuthenticationRequirements::NO_BONDING;
+  pairing_handler_->Initiate(true, injected_io_capability, hci::OobDataPresent::NOT_PRESENT,
+                             injected_authentication_requirements);
+  ReceiveLinkKeyRequest(hci_layer_, device_);
+  auto security_command_view = GetLastCommand(hci_layer_);
+  auto link_key_neg_reply = hci::LinkKeyRequestNegativeReplyView::Create(security_command_view);
+  ASSERT_TRUE(link_key_neg_reply.IsValid());
+  ASSERT_EQ(OpCode::LINK_KEY_REQUEST_NEGATIVE_REPLY, link_key_neg_reply.GetOpCode());
+  ReceiveIoCapabilityRequest(hci_layer_, device_);
+  security_command_view = GetLastCommand(hci_layer_);
+  ASSERT_EQ(OpCode::IO_CAPABILITY_REQUEST_REPLY, security_command_view.GetOpCode());
+  auto io_cap_request_reply = hci::IoCapabilityRequestReplyView::Create(security_command_view);
+  ASSERT_TRUE(io_cap_request_reply.IsValid());
+  ASSERT_EQ(injected_io_capability, io_cap_request_reply.GetIoCapability());
+  ASSERT_EQ(hci::OobDataPresent::NOT_PRESENT, io_cap_request_reply.GetOobPresent());
+  ASSERT_EQ(injected_authentication_requirements, io_cap_request_reply.GetAuthenticationRequirements());
+  ReceiveIoCapabilityResponse(hci_layer_, device_, hci::IoCapability::DISPLAY_ONLY, hci::OobDataPresent::NOT_PRESENT,
+                              hci::AuthenticationRequirements::NO_BONDING);
+  uint32_t numeric_value = 0x123;
+  ReceiveUserConfirmationRequest(hci_layer_, device_, numeric_value);
+  security_command_view = GetLastCommand(hci_layer_);
+  ASSERT_EQ(OpCode::USER_CONFIRMATION_REQUEST_REPLY, security_command_view.GetOpCode());
+  auto user_conf_request_reply = hci::UserConfirmationRequestReplyView::Create(security_command_view);
+  ASSERT_TRUE(user_conf_request_reply.IsValid());
+  ReceiveSimplePairingComplete(hci_layer_, hci::ErrorCode::SUCCESS, device_);
+  std::array<uint8_t, 16> link_key = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5};
+  hci::KeyType key_type = hci::KeyType::DEBUG_COMBINATION;
+  ReceiveLinkKeyNotification(hci_layer_, device_, link_key, key_type);
+  ASSERT_EQ(link_key, security_record_->GetLinkKey());
+  ASSERT_EQ(key_type, security_record_->GetKeyType());
+}
+
+// display_only + display_yes_no is JustWorks no confirmation
+// Needs dialog as per security a bug unless pairing is temporary
+TEST_F(ClassicPairingHandlerTest, locally_initiatied_display_only_display_yes_no_temp) {
+  hci::IoCapability injected_io_capability = hci::IoCapability::DISPLAY_ONLY;
+  hci::AuthenticationRequirements injected_authentication_requirements = hci::AuthenticationRequirements::NO_BONDING;
+  pairing_handler_->Initiate(true, injected_io_capability, hci::OobDataPresent::NOT_PRESENT,
+                             injected_authentication_requirements);
+  ReceiveLinkKeyRequest(hci_layer_, device_);
+  auto security_command_view = GetLastCommand(hci_layer_);
+  auto link_key_neg_reply = hci::LinkKeyRequestNegativeReplyView::Create(security_command_view);
+  ASSERT_TRUE(link_key_neg_reply.IsValid());
+  ASSERT_EQ(OpCode::LINK_KEY_REQUEST_NEGATIVE_REPLY, link_key_neg_reply.GetOpCode());
+  ReceiveIoCapabilityRequest(hci_layer_, device_);
+  security_command_view = GetLastCommand(hci_layer_);
+  ASSERT_EQ(OpCode::IO_CAPABILITY_REQUEST_REPLY, security_command_view.GetOpCode());
+  auto io_cap_request_reply = hci::IoCapabilityRequestReplyView::Create(security_command_view);
+  ASSERT_TRUE(io_cap_request_reply.IsValid());
+  ASSERT_EQ(injected_io_capability, io_cap_request_reply.GetIoCapability());
+  ASSERT_EQ(hci::OobDataPresent::NOT_PRESENT, io_cap_request_reply.GetOobPresent());
+  ASSERT_EQ(injected_authentication_requirements, io_cap_request_reply.GetAuthenticationRequirements());
+  ReceiveIoCapabilityResponse(hci_layer_, device_, hci::IoCapability::DISPLAY_YES_NO, hci::OobDataPresent::NOT_PRESENT,
+                              hci::AuthenticationRequirements::NO_BONDING);
+  uint32_t numeric_value = 0x123;
+  ReceiveUserConfirmationRequest(hci_layer_, device_, numeric_value);
+  security_command_view = GetLastCommand(hci_layer_);
+  ASSERT_EQ(OpCode::USER_CONFIRMATION_REQUEST_REPLY, security_command_view.GetOpCode());
+  auto user_conf_request_reply = hci::UserConfirmationRequestReplyView::Create(security_command_view);
+  ASSERT_TRUE(user_conf_request_reply.IsValid());
+  ReceiveSimplePairingComplete(hci_layer_, hci::ErrorCode::SUCCESS, device_);
+  std::array<uint8_t, 16> link_key = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5};
+  hci::KeyType key_type = hci::KeyType::DEBUG_COMBINATION;
+  ReceiveLinkKeyNotification(hci_layer_, device_, link_key, key_type);
+  ASSERT_EQ(link_key, security_record_->GetLinkKey());
+  ASSERT_EQ(key_type, security_record_->GetKeyType());
+}
+
+// display_only + no_input_no_output is JustWorks no confirmation
+// Needs dialog as per security a bug unless pairing is temporary
+TEST_F(ClassicPairingHandlerTest, locally_initiatied_display_only_no_input_no_output_temp) {
+  hci::IoCapability injected_io_capability = hci::IoCapability::DISPLAY_ONLY;
+  hci::AuthenticationRequirements injected_authentication_requirements = hci::AuthenticationRequirements::NO_BONDING;
+  pairing_handler_->Initiate(true, injected_io_capability, hci::OobDataPresent::NOT_PRESENT,
+                             injected_authentication_requirements);
+  ReceiveLinkKeyRequest(hci_layer_, device_);
+  auto security_command_view = GetLastCommand(hci_layer_);
+  auto link_key_neg_reply = hci::LinkKeyRequestNegativeReplyView::Create(security_command_view);
+  ASSERT_TRUE(link_key_neg_reply.IsValid());
+  ASSERT_EQ(OpCode::LINK_KEY_REQUEST_NEGATIVE_REPLY, link_key_neg_reply.GetOpCode());
+  ReceiveIoCapabilityRequest(hci_layer_, device_);
+  security_command_view = GetLastCommand(hci_layer_);
+  ASSERT_EQ(OpCode::IO_CAPABILITY_REQUEST_REPLY, security_command_view.GetOpCode());
+  auto io_cap_request_reply = hci::IoCapabilityRequestReplyView::Create(security_command_view);
+  ASSERT_TRUE(io_cap_request_reply.IsValid());
+  ASSERT_EQ(injected_io_capability, io_cap_request_reply.GetIoCapability());
+  ASSERT_EQ(hci::OobDataPresent::NOT_PRESENT, io_cap_request_reply.GetOobPresent());
+  ASSERT_EQ(injected_authentication_requirements, io_cap_request_reply.GetAuthenticationRequirements());
+  ReceiveIoCapabilityResponse(hci_layer_, device_, hci::IoCapability::NO_INPUT_NO_OUTPUT,
+                              hci::OobDataPresent::NOT_PRESENT, hci::AuthenticationRequirements::NO_BONDING);
+  uint32_t numeric_value = 0x123;
+  ReceiveUserConfirmationRequest(hci_layer_, device_, numeric_value);
+  security_command_view = GetLastCommand(hci_layer_);
+  ASSERT_EQ(OpCode::USER_CONFIRMATION_REQUEST_REPLY, security_command_view.GetOpCode());
+  auto user_conf_request_reply = hci::UserConfirmationRequestReplyView::Create(security_command_view);
+  ASSERT_TRUE(user_conf_request_reply.IsValid());
+  ReceiveSimplePairingComplete(hci_layer_, hci::ErrorCode::SUCCESS, device_);
+  std::array<uint8_t, 16> link_key = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5};
+  hci::KeyType key_type = hci::KeyType::DEBUG_COMBINATION;
+  ReceiveLinkKeyNotification(hci_layer_, device_, link_key, key_type);
+  ASSERT_EQ(link_key, security_record_->GetLinkKey());
+  ASSERT_EQ(key_type, security_record_->GetKeyType());
+}
+
+// keyboard_only + no_input_no_output is JustWorks no confirmation
+// Needs dialog as per security a bug unless pairing is temporary
+TEST_F(ClassicPairingHandlerTest, locally_initiatied_keyboard_only_no_input_no_output_temp) {
+  hci::IoCapability injected_io_capability = hci::IoCapability::KEYBOARD_ONLY;
+  hci::AuthenticationRequirements injected_authentication_requirements = hci::AuthenticationRequirements::NO_BONDING;
+  pairing_handler_->Initiate(true, injected_io_capability, hci::OobDataPresent::NOT_PRESENT,
+                             injected_authentication_requirements);
+  ReceiveLinkKeyRequest(hci_layer_, device_);
+  auto security_command_view = GetLastCommand(hci_layer_);
+  auto link_key_neg_reply = hci::LinkKeyRequestNegativeReplyView::Create(security_command_view);
+  ASSERT_TRUE(link_key_neg_reply.IsValid());
+  ASSERT_EQ(OpCode::LINK_KEY_REQUEST_NEGATIVE_REPLY, link_key_neg_reply.GetOpCode());
+  ReceiveIoCapabilityRequest(hci_layer_, device_);
+  security_command_view = GetLastCommand(hci_layer_);
+  ASSERT_EQ(OpCode::IO_CAPABILITY_REQUEST_REPLY, security_command_view.GetOpCode());
+  auto io_cap_request_reply = hci::IoCapabilityRequestReplyView::Create(security_command_view);
+  ASSERT_TRUE(io_cap_request_reply.IsValid());
+  ASSERT_EQ(injected_io_capability, io_cap_request_reply.GetIoCapability());
+  ASSERT_EQ(hci::OobDataPresent::NOT_PRESENT, io_cap_request_reply.GetOobPresent());
+  ASSERT_EQ(injected_authentication_requirements, io_cap_request_reply.GetAuthenticationRequirements());
+  ReceiveIoCapabilityResponse(hci_layer_, device_, hci::IoCapability::NO_INPUT_NO_OUTPUT,
+                              hci::OobDataPresent::NOT_PRESENT, hci::AuthenticationRequirements::NO_BONDING);
+  uint32_t numeric_value = 0x123;
+  ReceiveUserConfirmationRequest(hci_layer_, device_, numeric_value);
+  security_command_view = GetLastCommand(hci_layer_);
+  ASSERT_EQ(OpCode::USER_CONFIRMATION_REQUEST_REPLY, security_command_view.GetOpCode());
+  auto user_conf_request_reply = hci::UserConfirmationRequestReplyView::Create(security_command_view);
+  ASSERT_TRUE(user_conf_request_reply.IsValid());
+  ReceiveSimplePairingComplete(hci_layer_, hci::ErrorCode::SUCCESS, device_);
+  std::array<uint8_t, 16> link_key = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5};
+  hci::KeyType key_type = hci::KeyType::DEBUG_COMBINATION;
+  ReceiveLinkKeyNotification(hci_layer_, device_, link_key, key_type);
+  ASSERT_EQ(link_key, security_record_->GetLinkKey());
+  ASSERT_EQ(key_type, security_record_->GetKeyType());
+}
+
+// no_input_no_output + display_only is JustWorks no confirmation
+// Needs dialog as per security a bug unless pairing is temporary
+TEST_F(ClassicPairingHandlerTest, locally_initiatied_no_input_no_output_display_only_temp) {
+  hci::IoCapability injected_io_capability = hci::IoCapability::NO_INPUT_NO_OUTPUT;
+  hci::AuthenticationRequirements injected_authentication_requirements = hci::AuthenticationRequirements::NO_BONDING;
+  pairing_handler_->Initiate(true, injected_io_capability, hci::OobDataPresent::NOT_PRESENT,
+                             injected_authentication_requirements);
+  ReceiveLinkKeyRequest(hci_layer_, device_);
+  auto security_command_view = GetLastCommand(hci_layer_);
+  auto link_key_neg_reply = hci::LinkKeyRequestNegativeReplyView::Create(security_command_view);
+  ASSERT_TRUE(link_key_neg_reply.IsValid());
+  ASSERT_EQ(OpCode::LINK_KEY_REQUEST_NEGATIVE_REPLY, link_key_neg_reply.GetOpCode());
+  ReceiveIoCapabilityRequest(hci_layer_, device_);
+  security_command_view = GetLastCommand(hci_layer_);
+  ASSERT_EQ(OpCode::IO_CAPABILITY_REQUEST_REPLY, security_command_view.GetOpCode());
+  auto io_cap_request_reply = hci::IoCapabilityRequestReplyView::Create(security_command_view);
+  ASSERT_TRUE(io_cap_request_reply.IsValid());
+  ASSERT_EQ(injected_io_capability, io_cap_request_reply.GetIoCapability());
+  ASSERT_EQ(hci::OobDataPresent::NOT_PRESENT, io_cap_request_reply.GetOobPresent());
+  ASSERT_EQ(injected_authentication_requirements, io_cap_request_reply.GetAuthenticationRequirements());
+  ReceiveIoCapabilityResponse(hci_layer_, device_, hci::IoCapability::DISPLAY_ONLY, hci::OobDataPresent::NOT_PRESENT,
+                              hci::AuthenticationRequirements::NO_BONDING);
+  uint32_t numeric_value = 0x123;
+  ReceiveUserConfirmationRequest(hci_layer_, device_, numeric_value);
+  security_command_view = GetLastCommand(hci_layer_);
+  ASSERT_EQ(OpCode::USER_CONFIRMATION_REQUEST_REPLY, security_command_view.GetOpCode());
+  auto user_conf_request_reply = hci::UserConfirmationRequestReplyView::Create(security_command_view);
+  ASSERT_TRUE(user_conf_request_reply.IsValid());
+  ReceiveSimplePairingComplete(hci_layer_, hci::ErrorCode::SUCCESS, device_);
+  std::array<uint8_t, 16> link_key = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5};
+  hci::KeyType key_type = hci::KeyType::DEBUG_COMBINATION;
+  ReceiveLinkKeyNotification(hci_layer_, device_, link_key, key_type);
+  ASSERT_EQ(link_key, security_record_->GetLinkKey());
+  ASSERT_EQ(key_type, security_record_->GetKeyType());
+}
+
+// no_input_no_output + display_yes_no is JustWorks no confirmation
+// Needs dialog as per security a bug unless pairing is temporary
+TEST_F(ClassicPairingHandlerTest, locally_initiatied_no_input_no_output_display_yes_no_temp) {
+  hci::IoCapability injected_io_capability = hci::IoCapability::NO_INPUT_NO_OUTPUT;
+  hci::AuthenticationRequirements injected_authentication_requirements = hci::AuthenticationRequirements::NO_BONDING;
+  pairing_handler_->Initiate(true, injected_io_capability, hci::OobDataPresent::NOT_PRESENT,
+                             injected_authentication_requirements);
+  ReceiveLinkKeyRequest(hci_layer_, device_);
+  auto security_command_view = GetLastCommand(hci_layer_);
+  auto link_key_neg_reply = hci::LinkKeyRequestNegativeReplyView::Create(security_command_view);
+  ASSERT_TRUE(link_key_neg_reply.IsValid());
+  ASSERT_EQ(OpCode::LINK_KEY_REQUEST_NEGATIVE_REPLY, link_key_neg_reply.GetOpCode());
+  ReceiveIoCapabilityRequest(hci_layer_, device_);
+  security_command_view = GetLastCommand(hci_layer_);
+  ASSERT_EQ(OpCode::IO_CAPABILITY_REQUEST_REPLY, security_command_view.GetOpCode());
+  auto io_cap_request_reply = hci::IoCapabilityRequestReplyView::Create(security_command_view);
+  ASSERT_TRUE(io_cap_request_reply.IsValid());
+  ASSERT_EQ(injected_io_capability, io_cap_request_reply.GetIoCapability());
+  ASSERT_EQ(hci::OobDataPresent::NOT_PRESENT, io_cap_request_reply.GetOobPresent());
+  ASSERT_EQ(injected_authentication_requirements, io_cap_request_reply.GetAuthenticationRequirements());
+  ReceiveIoCapabilityResponse(hci_layer_, device_, hci::IoCapability::DISPLAY_YES_NO, hci::OobDataPresent::NOT_PRESENT,
+                              hci::AuthenticationRequirements::NO_BONDING);
+  uint32_t numeric_value = 0x123;
+  ReceiveUserConfirmationRequest(hci_layer_, device_, numeric_value);
+  security_command_view = GetLastCommand(hci_layer_);
+  ASSERT_EQ(OpCode::USER_CONFIRMATION_REQUEST_REPLY, security_command_view.GetOpCode());
+  auto user_conf_request_reply = hci::UserConfirmationRequestReplyView::Create(security_command_view);
+  ASSERT_TRUE(user_conf_request_reply.IsValid());
+  ReceiveSimplePairingComplete(hci_layer_, hci::ErrorCode::SUCCESS, device_);
+  std::array<uint8_t, 16> link_key = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5};
+  hci::KeyType key_type = hci::KeyType::DEBUG_COMBINATION;
+  ReceiveLinkKeyNotification(hci_layer_, device_, link_key, key_type);
+  ASSERT_EQ(link_key, security_record_->GetLinkKey());
+  ASSERT_EQ(key_type, security_record_->GetKeyType());
+}
+
+// no_input_no_output + keyboard_only is JustWorks no confirmation
+// Needs dialog as per security a bug unless pairing is temporary
+TEST_F(ClassicPairingHandlerTest, locally_initiatied_no_input_no_output_keyboard_only_temp) {
+  hci::IoCapability injected_io_capability = hci::IoCapability::NO_INPUT_NO_OUTPUT;
+  hci::AuthenticationRequirements injected_authentication_requirements = hci::AuthenticationRequirements::NO_BONDING;
+  pairing_handler_->Initiate(true, injected_io_capability, hci::OobDataPresent::NOT_PRESENT,
+                             injected_authentication_requirements);
+  ReceiveLinkKeyRequest(hci_layer_, device_);
+  auto security_command_view = GetLastCommand(hci_layer_);
+  auto link_key_neg_reply = hci::LinkKeyRequestNegativeReplyView::Create(security_command_view);
+  ASSERT_TRUE(link_key_neg_reply.IsValid());
+  ASSERT_EQ(OpCode::LINK_KEY_REQUEST_NEGATIVE_REPLY, link_key_neg_reply.GetOpCode());
+  ReceiveIoCapabilityRequest(hci_layer_, device_);
+  security_command_view = GetLastCommand(hci_layer_);
+  ASSERT_EQ(OpCode::IO_CAPABILITY_REQUEST_REPLY, security_command_view.GetOpCode());
+  auto io_cap_request_reply = hci::IoCapabilityRequestReplyView::Create(security_command_view);
+  ASSERT_TRUE(io_cap_request_reply.IsValid());
+  ASSERT_EQ(injected_io_capability, io_cap_request_reply.GetIoCapability());
+  ASSERT_EQ(hci::OobDataPresent::NOT_PRESENT, io_cap_request_reply.GetOobPresent());
+  ASSERT_EQ(injected_authentication_requirements, io_cap_request_reply.GetAuthenticationRequirements());
+  ReceiveIoCapabilityResponse(hci_layer_, device_, hci::IoCapability::KEYBOARD_ONLY, hci::OobDataPresent::NOT_PRESENT,
+                              hci::AuthenticationRequirements::NO_BONDING);
+  uint32_t numeric_value = 0x123;
+  ReceiveUserConfirmationRequest(hci_layer_, device_, numeric_value);
+  security_command_view = GetLastCommand(hci_layer_);
+  ASSERT_EQ(OpCode::USER_CONFIRMATION_REQUEST_REPLY, security_command_view.GetOpCode());
+  auto user_conf_request_reply = hci::UserConfirmationRequestReplyView::Create(security_command_view);
+  ASSERT_TRUE(user_conf_request_reply.IsValid());
+  ReceiveSimplePairingComplete(hci_layer_, hci::ErrorCode::SUCCESS, device_);
+  std::array<uint8_t, 16> link_key = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5};
+  hci::KeyType key_type = hci::KeyType::DEBUG_COMBINATION;
+  ReceiveLinkKeyNotification(hci_layer_, device_, link_key, key_type);
+  ASSERT_EQ(link_key, security_record_->GetLinkKey());
+  ASSERT_EQ(key_type, security_record_->GetKeyType());
+}
+
+// no_input_no_output + no_input_no_output is JustWorks no confirmation
+// Needs dialog as per security a bug unless pairing is temporary
+TEST_F(ClassicPairingHandlerTest, locally_initiatied_no_input_no_output_no_input_no_output_temp) {
+  hci::IoCapability injected_io_capability = hci::IoCapability::NO_INPUT_NO_OUTPUT;
+  hci::AuthenticationRequirements injected_authentication_requirements = hci::AuthenticationRequirements::NO_BONDING;
+  pairing_handler_->Initiate(true, injected_io_capability, hci::OobDataPresent::NOT_PRESENT,
+                             injected_authentication_requirements);
+  ReceiveLinkKeyRequest(hci_layer_, device_);
+  auto security_command_view = GetLastCommand(hci_layer_);
+  auto link_key_neg_reply = hci::LinkKeyRequestNegativeReplyView::Create(security_command_view);
+  ASSERT_TRUE(link_key_neg_reply.IsValid());
+  ASSERT_EQ(OpCode::LINK_KEY_REQUEST_NEGATIVE_REPLY, link_key_neg_reply.GetOpCode());
+  ReceiveIoCapabilityRequest(hci_layer_, device_);
+  security_command_view = GetLastCommand(hci_layer_);
+  ASSERT_EQ(OpCode::IO_CAPABILITY_REQUEST_REPLY, security_command_view.GetOpCode());
+  auto io_cap_request_reply = hci::IoCapabilityRequestReplyView::Create(security_command_view);
+  ASSERT_TRUE(io_cap_request_reply.IsValid());
+  ASSERT_EQ(injected_io_capability, io_cap_request_reply.GetIoCapability());
+  ASSERT_EQ(hci::OobDataPresent::NOT_PRESENT, io_cap_request_reply.GetOobPresent());
+  ASSERT_EQ(injected_authentication_requirements, io_cap_request_reply.GetAuthenticationRequirements());
+  ReceiveIoCapabilityResponse(hci_layer_, device_, hci::IoCapability::NO_INPUT_NO_OUTPUT,
+                              hci::OobDataPresent::NOT_PRESENT, hci::AuthenticationRequirements::NO_BONDING);
+  uint32_t numeric_value = 0x123;
+  ReceiveUserConfirmationRequest(hci_layer_, device_, numeric_value);
+  security_command_view = GetLastCommand(hci_layer_);
+  ASSERT_EQ(OpCode::USER_CONFIRMATION_REQUEST_REPLY, security_command_view.GetOpCode());
+  auto user_conf_request_reply = hci::UserConfirmationRequestReplyView::Create(security_command_view);
+  ASSERT_TRUE(user_conf_request_reply.IsValid());
+  ReceiveSimplePairingComplete(hci_layer_, hci::ErrorCode::SUCCESS, device_);
+  std::array<uint8_t, 16> link_key = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5};
+  hci::KeyType key_type = hci::KeyType::DEBUG_COMBINATION;
+  ReceiveLinkKeyNotification(hci_layer_, device_, link_key, key_type);
+  ASSERT_EQ(link_key, security_record_->GetLinkKey());
+  ASSERT_EQ(key_type, security_record_->GetKeyType());
+}
+
+// Remotely initiated
+
+// Collisions
+
+}  // namespace
+}  // namespace channel
+}  // namespace security
+}  // namespace bluetooth
diff --git a/gd/security/pairing/pairing_handler.h b/gd/security/pairing/pairing_handler.h
index 61cad62..886b1a4 100644
--- a/gd/security/pairing/pairing_handler.h
+++ b/gd/security/pairing/pairing_handler.h
@@ -1,4 +1,4 @@
-/******************************************************************************
+/*
  *
  *  Copyright 2019 The Android Open Source Project
  *
@@ -14,13 +14,13 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- ******************************************************************************/
+ */
 #pragma once
 
-#include <memory>
-#include <vector>
+#include <utility>
 
-#include "hci/device.h"
+#include "hci/address_with_type.h"
+#include "hci/hci_packets.h"
 #include "security/channel/security_manager_channel.h"
 #include "security/record/security_record.h"
 #include "security/smp_packets.h"
@@ -36,14 +36,42 @@
  */
 class PairingHandler {
  public:
-  PairingHandler(std::shared_ptr<record::SecurityRecord> record) : record_(record){};
+  PairingHandler(channel::SecurityManagerChannel* security_manager_channel,
+                 std::shared_ptr<record::SecurityRecord> record)
+      : security_manager_channel_(security_manager_channel), record_(std::move(record)) {}
   virtual ~PairingHandler() = default;
 
+  // Classic
+  virtual void Initiate(bool locally_initiated, hci::IoCapability io_capability, hci::OobDataPresent oob_present,
+                        hci::AuthenticationRequirements auth_requirements) = 0;  // This is for local initiated only
+  virtual void Cancel() = 0;
+  virtual void OnReceive(hci::ChangeConnectionLinkKeyCompleteView packet) = 0;
+  virtual void OnReceive(hci::MasterLinkKeyCompleteView packet) = 0;
+  virtual void OnReceive(hci::PinCodeRequestView packet) = 0;
+  virtual void OnReceive(hci::LinkKeyRequestView packet) = 0;
+  virtual void OnReceive(hci::LinkKeyNotificationView packet) = 0;
+  virtual void OnReceive(hci::IoCapabilityRequestView packet) = 0;
+  virtual void OnReceive(hci::IoCapabilityResponseView packet) = 0;
+  virtual void OnReceive(hci::SimplePairingCompleteView packet) = 0;
+  virtual void OnReceive(hci::ReturnLinkKeysView packet) = 0;
+  virtual void OnReceive(hci::EncryptionChangeView packet) = 0;
+  virtual void OnReceive(hci::EncryptionKeyRefreshCompleteView packet) = 0;
+  virtual void OnReceive(hci::RemoteOobDataRequestView packet) = 0;
+  virtual void OnReceive(hci::UserPasskeyNotificationView packet) = 0;
+  virtual void OnReceive(hci::KeypressNotificationView packet) = 0;
+  virtual void OnReceive(hci::UserConfirmationRequestView packet) = 0;
+  virtual void OnReceive(hci::UserPasskeyRequestView packet) = 0;
+
+ protected:
   std::shared_ptr<record::SecurityRecord> GetRecord() {
     return record_;
   }
+  channel::SecurityManagerChannel* GetChannel() {
+    return security_manager_channel_;
+  }
 
  private:
+  channel::SecurityManagerChannel* security_manager_channel_ __attribute__((unused));
   std::shared_ptr<record::SecurityRecord> record_ __attribute__((unused));
 };
 
diff --git a/gd/security/record/security_record.h b/gd/security/record/security_record.h
index 0c78113..58f047b 100644
--- a/gd/security/record/security_record.h
+++ b/gd/security/record/security_record.h
@@ -1,4 +1,4 @@
-/******************************************************************************
+/*
  *
  *  Copyright 2019 The Android Open Source Project
  *
@@ -14,23 +14,24 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- ******************************************************************************/
+ */
 
 #pragma once
 
 #include <memory>
+#include <utility>
 
-#include "hci/device.h"
+#include "hci/address_with_type.h"
 
 namespace bluetooth {
 namespace security {
 namespace record {
 
-enum BondState { NOT_BONDED, PAIRING, BONDED };
+enum BondState { NOT_BONDED, PAIRING, PAIRED, BONDED };
 
 class SecurityRecord {
  public:
-  SecurityRecord(std::shared_ptr<hci::Device> device) : device_(device), state_(NOT_BONDED) {}
+  explicit SecurityRecord(hci::AddressWithType device) : device_(device), state_(NOT_BONDED) {}
 
   /**
    * Returns true if the device is bonded to another device
@@ -39,6 +40,10 @@
     return state_ == BONDED;
   }
 
+  bool IsPaired() {
+    return state_ == PAIRED;
+  }
+
   /**
    * Returns true if a device is currently pairing to another device
    */
@@ -46,13 +51,28 @@
     return state_ == PAIRING;
   }
 
-  std::shared_ptr<hci::Device> GetDevice() {
+  void SetLinkKey(std::array<uint8_t, 16> link_key, hci::KeyType key_type) {
+    link_key_ = link_key;
+    key_type_ = key_type;
+  }
+
+  std::array<uint8_t, 16> GetLinkKey() {
+    return link_key_;
+  }
+
+  hci::KeyType GetKeyType() {
+    return key_type_;
+  }
+
+  hci::AddressWithType GetDevice() {
     return device_;
   }
 
  private:
-  const std::shared_ptr<hci::Device> device_;
+  const hci::AddressWithType device_;
   BondState state_;
+  std::array<uint8_t, 16> link_key_ = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+  hci::KeyType key_type_ = hci::KeyType::DEBUG_COMBINATION;
 };
 
 }  // namespace record
diff --git a/gd/security/security_manager.cc b/gd/security/security_manager.cc
index 40858a9..f9c1440 100644
--- a/gd/security/security_manager.cc
+++ b/gd/security/security_manager.cc
@@ -1,4 +1,4 @@
-/******************************************************************************
+/*
  *
  *  Copyright 2019 The Android Open Source Project
  *
@@ -14,7 +14,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- ******************************************************************************/
+ */
 #include "security_manager.h"
 
 #include "os/log.h"
@@ -29,22 +29,22 @@
       common::BindOnce(&internal::SecurityManagerImpl::Init, common::Unretained(security_manager_impl_)));
 }
 
-void SecurityManager::CreateBond(std::shared_ptr<hci::ClassicDevice> device) {
+void SecurityManager::CreateBond(hci::AddressWithType device) {
   security_handler_->Post(common::BindOnce(&internal::SecurityManagerImpl::CreateBond,
                                            common::Unretained(security_manager_impl_),
-                                           std::forward<std::shared_ptr<hci::ClassicDevice>>(device)));
+                                           std::forward<hci::AddressWithType>(device)));
 }
 
-void SecurityManager::CancelBond(std::shared_ptr<hci::ClassicDevice> device) {
+void SecurityManager::CancelBond(hci::AddressWithType device) {
   security_handler_->Post(common::BindOnce(&internal::SecurityManagerImpl::CancelBond,
                                            common::Unretained(security_manager_impl_),
-                                           std::forward<std::shared_ptr<hci::ClassicDevice>>(device)));
+                                           std::forward<hci::AddressWithType>(device)));
 }
 
-void SecurityManager::RemoveBond(std::shared_ptr<hci::ClassicDevice> device) {
+void SecurityManager::RemoveBond(hci::AddressWithType device) {
   security_handler_->Post(common::BindOnce(&internal::SecurityManagerImpl::RemoveBond,
                                            common::Unretained(security_manager_impl_),
-                                           std::forward<std::shared_ptr<hci::ClassicDevice>>(device)));
+                                           std::forward<hci::AddressWithType>(device)));
 }
 
 void SecurityManager::RegisterCallbackListener(ISecurityManagerListener* listener, os::Handler* handler) {
diff --git a/gd/security/security_manager.h b/gd/security/security_manager.h
index d83c8d3..2a9f2e3 100644
--- a/gd/security/security_manager.h
+++ b/gd/security/security_manager.h
@@ -1,4 +1,4 @@
-/******************************************************************************
+/*
  *
  *  Copyright 2019 The Android Open Source Project
  *
@@ -14,7 +14,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- ******************************************************************************/
+ */
 
 #pragma once
 
@@ -22,7 +22,6 @@
 #include <vector>
 
 #include "hci/address_with_type.h"
-#include "hci/device.h"
 #include "security/internal/security_manager_impl.h"
 
 namespace bluetooth {
@@ -75,21 +74,21 @@
    *
    * @param device pointer to device we want to bond with
    */
-  void CreateBond(std::shared_ptr<hci::ClassicDevice> device);
+  void CreateBond(hci::AddressWithType device);
 
   /**
    * Cancels the pairing process for this device.
    *
    * @param device pointer to device with which we want to cancel our bond
    */
-  void CancelBond(std::shared_ptr<bluetooth::hci::ClassicDevice> device);
+  void CancelBond(hci::AddressWithType device);
 
   /**
    * Disassociates the device and removes the persistent LTK
    *
    * @param device pointer to device we want to forget
    */
-  void RemoveBond(std::shared_ptr<bluetooth::hci::ClassicDevice> device);
+  void RemoveBond(hci::AddressWithType device);
 
   /**
    * Register to listen for callback events from SecurityManager
diff --git a/gd/security/security_module.cc b/gd/security/security_module.cc
index 58b1f8c..b1f7c66 100644
--- a/gd/security/security_module.cc
+++ b/gd/security/security_module.cc
@@ -45,6 +45,9 @@
   channel::SecurityManagerChannel* security_manager_channel_;
   internal::SecurityManagerImpl security_manager_impl{security_handler_, l2cap_le_module_, l2cap_classic_module_,
                                                       security_manager_channel_};
+  ~impl() {
+    delete security_manager_channel_;
+  }
 };
 
 void SecurityModule::ListDependencies(ModuleList* list) {
diff --git a/gd/security/test/fake_hci_layer.h b/gd/security/test/fake_hci_layer.h
index 84eff90..6866b34 100644
--- a/gd/security/test/fake_hci_layer.h
+++ b/gd/security/test/fake_hci_layer.h
@@ -1,4 +1,4 @@
-/******************************************************************************
+/*
  *
  *  Copyright 2019 The Android Open Source Project
  *
@@ -14,7 +14,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- ******************************************************************************/
+ */
 
 #include "common/bind.h"
 #include "hci/hci_layer.h"
@@ -98,7 +98,7 @@
     EventPacketView event = EventPacketView::Create(packet);
     ASSERT_TRUE(event.IsValid());
     EventCode event_code = event.GetEventCode();
-    EXPECT_TRUE(registered_events_.find(event_code) != registered_events_.end());
+    ASSERT_TRUE(registered_events_.find(event_code) != registered_events_.end());
     registered_events_[event_code].Run(event);
   }
 
diff --git a/gd/shim/l2cap.cc b/gd/shim/l2cap.cc
index d703972..7af8f77 100644
--- a/gd/shim/l2cap.cc
+++ b/gd/shim/l2cap.cc
@@ -50,8 +50,7 @@
 
 using ServiceInterfaceCallback =
     std::function<void(l2cap::Psm psm, l2cap::classic::DynamicChannelManager::RegistrationResult result)>;
-using ConnectionInterfaceCallback =
-    std::function<void(l2cap::Psm psm, std::unique_ptr<l2cap::classic::DynamicChannel>)>;
+using ConnectionInterfaceCallback = std::function<void(l2cap::Psm psm, std::unique_ptr<l2cap::DynamicChannel>)>;
 
 std::unique_ptr<packet::RawBuilder> MakeUniquePacket(const uint8_t* data, size_t len) {
   packet::RawBuilder builder;
@@ -63,7 +62,7 @@
 
 class ConnectionInterface {
  public:
-  ConnectionInterface(ConnectionInterfaceDescriptor cid, std::unique_ptr<l2cap::classic::DynamicChannel> channel,
+  ConnectionInterface(ConnectionInterfaceDescriptor cid, std::unique_ptr<l2cap::DynamicChannel> channel,
                       os::Handler* handler)
       : cid_(cid), channel_(std::move(channel)), handler_(handler), on_data_ready_callback_(nullptr),
         on_connection_closed_callback_(nullptr), address_(channel_->GetDevice()) {
@@ -139,7 +138,7 @@
 
  private:
   const ConnectionInterfaceDescriptor cid_;
-  const std::unique_ptr<l2cap::classic::DynamicChannel> channel_;
+  const std::unique_ptr<l2cap::DynamicChannel> channel_;
   os::Handler* handler_;
 
   ReadDataReadyCallback on_data_ready_callback_;
@@ -155,7 +154,7 @@
 
 struct ConnectionInterfaceManager {
  public:
-  ConnectionInterfaceDescriptor AddChannel(std::unique_ptr<l2cap::classic::DynamicChannel> channel);
+  ConnectionInterfaceDescriptor AddChannel(std::unique_ptr<l2cap::DynamicChannel> channel);
   void RemoveConnection(ConnectionInterfaceDescriptor cid);
 
   void SetReadDataReadyCallback(ConnectionInterfaceDescriptor cid, ReadDataReadyCallback on_data_ready);
@@ -218,8 +217,7 @@
   return current_connection_interface_descriptor_++;
 }
 
-ConnectionInterfaceDescriptor ConnectionInterfaceManager::AddChannel(
-    std::unique_ptr<l2cap::classic::DynamicChannel> channel) {
+ConnectionInterfaceDescriptor ConnectionInterfaceManager::AddChannel(std::unique_ptr<l2cap::DynamicChannel> channel) {
   if (!HasResources()) {
     return kInvalidConnectionInterfaceDescriptor;
   }
@@ -267,7 +265,7 @@
       : connection_interface_manager_(connection_interface_manager), psm_(psm), address_(address),
         on_open_(std::move(on_open)), completed_(std::move(completed)) {}
 
-  void OnConnectionOpen(std::unique_ptr<l2cap::classic::DynamicChannel> channel) {
+  void OnConnectionOpen(std::unique_ptr<l2cap::DynamicChannel> channel) {
     LOG_DEBUG("Local initiated connection is open to device:%s for psm:%hd", address_.ToString().c_str(), psm_);
     ConnectionInterfaceDescriptor cid = connection_interface_manager_->AddChannel(std::move(channel));
     completed_.set_value(cid);
@@ -322,7 +320,7 @@
     completed_.set_value();
   }
 
-  void OnConnectionOpen(std::unique_ptr<l2cap::classic::DynamicChannel> channel) {
+  void OnConnectionOpen(std::unique_ptr<l2cap::DynamicChannel> channel) {
     LOG_DEBUG("Remote initiated connection is open from device:%s for psm:%hd", channel->GetDevice().ToString().c_str(),
               psm_);
     hci::Address address = channel->GetDevice();
diff --git a/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.cc b/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.cc
index bb3ba63..95bb202 100644
--- a/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.cc
+++ b/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.cc
@@ -25,6 +25,8 @@
 #include "os/log.h"
 #include "packet/raw_builder.h"
 
+using bluetooth::hci::ErrorCode;
+using bluetooth::hci::LoopbackMode;
 using bluetooth::hci::OpCode;
 using std::vector;
 
@@ -77,7 +79,7 @@
   raw_builder_ptr->AddOctets1(kNumCommandPackets);
   raw_builder_ptr->AddOctets2(command_opcode);
   raw_builder_ptr->AddOctets1(
-      static_cast<uint8_t>(bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND));
+      static_cast<uint8_t>(ErrorCode::UNKNOWN_HCI_COMMAND));
 
   auto packet = bluetooth::hci::EventPacketBuilder::Create(
       bluetooth::hci::EventCode::COMMAND_COMPLETE, std::move(raw_builder_ptr));
@@ -86,7 +88,7 @@
 
 DualModeController::DualModeController(const std::string& properties_filename, uint16_t num_keys)
     : Device(properties_filename), security_manager_(num_keys) {
-  loopback_mode_ = bluetooth::hci::LoopbackMode::NO_LOOPBACK;
+  loopback_mode_ = LoopbackMode::NO_LOOPBACK;
 
   Address public_address;
   ASSERT(Address::FromString("3C:5A:B4:04:05:06", public_address));
@@ -100,7 +102,7 @@
 
 #define SET_HANDLER(opcode, method)                     \
   active_hci_commands_[static_cast<uint16_t>(opcode)] = \
-      [this](bluetooth::packet::PacketView<true> param) { method(param); };
+      [this](PacketView<true> param) { method(param); };
   SET_HANDLER(OpCode::RESET, HciReset);
   SET_HANDLER(OpCode::READ_BUFFER_SIZE, HciReadBufferSize);
   SET_HANDLER(OpCode::HOST_BUFFER_SIZE, HciHostBufferSize);
@@ -203,14 +205,13 @@
 #undef SET_HANDLER
 }
 
-void DualModeController::HciSniffSubrating(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciSniffSubrating(PacketView<true> args) {
   ASSERT_LOG(args.size() == 8, "%s size=%zu", __func__, args.size());
 
   uint16_t handle = args.begin().extract<uint16_t>();
 
   auto packet = bluetooth::hci::SniffSubratingCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, handle);
+      kNumCommandPackets, ErrorCode::SUCCESS, handle);
   send_event_(std::move(packet));
 }
 
@@ -233,7 +234,7 @@
   bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian> raw_packet(packet);
   auto acl_packet = bluetooth::hci::AclPacketView::Create(raw_packet);
   ASSERT(acl_packet.IsValid());
-  if (loopback_mode_ == bluetooth::hci::LoopbackMode::ENABLE_LOCAL) {
+  if (loopback_mode_ == LoopbackMode::ENABLE_LOCAL) {
     uint16_t handle = acl_packet.GetHandle();
 
     std::vector<bluetooth::hci::CompletedPackets> completed_packets;
@@ -253,7 +254,7 @@
 void DualModeController::HandleSco(std::shared_ptr<std::vector<uint8_t>> packet) {
   bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian> raw_packet(packet);
   auto sco_packet = bluetooth::hci::ScoPacketView::Create(raw_packet);
-  if (loopback_mode_ == bluetooth::hci::LoopbackMode::ENABLE_LOCAL) {
+  if (loopback_mode_ == LoopbackMode::ENABLE_LOCAL) {
     uint16_t handle = sco_packet.GetHandle();
     send_sco_(packet);
     std::vector<bluetooth::hci::CompletedPackets> completed_packets;
@@ -280,15 +281,14 @@
   auto op = command_packet.GetOpCode();
   uint16_t opcode = static_cast<uint16_t>(op);
 
-  if (loopback_mode_ == bluetooth::hci::LoopbackMode::ENABLE_LOCAL &&
+  if (loopback_mode_ == LoopbackMode::ENABLE_LOCAL &&
       // Loopback exceptions.
-      op != bluetooth::hci::OpCode::RESET &&
-      op != bluetooth::hci::OpCode::SET_CONTROLLER_TO_HOST_FLOW_CONTROL &&
-      op != bluetooth::hci::OpCode::HOST_BUFFER_SIZE &&
-      op != bluetooth::hci::OpCode::HOST_NUM_COMPLETED_PACKETS &&
-      op != bluetooth::hci::OpCode::READ_BUFFER_SIZE &&
-      op != bluetooth::hci::OpCode::READ_LOOPBACK_MODE &&
-      op != bluetooth::hci::OpCode::WRITE_LOOPBACK_MODE) {
+      op != OpCode::RESET &&
+      op != OpCode::SET_CONTROLLER_TO_HOST_FLOW_CONTROL &&
+      op != OpCode::HOST_BUFFER_SIZE &&
+      op != OpCode::HOST_NUM_COMPLETED_PACKETS &&
+      op != OpCode::READ_BUFFER_SIZE && op != OpCode::READ_LOOPBACK_MODE &&
+      op != OpCode::WRITE_LOOPBACK_MODE) {
     std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
         std::make_unique<bluetooth::packet::RawBuilder>();
     raw_builder_ptr->AddOctets(*packet);
@@ -343,23 +343,22 @@
   send_iso_ = callback;
 }
 
-void DualModeController::HciReset(bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciReset(PacketView<true> args) {
   ASSERT_LOG(args.size() == 0, "%s  size=%zu", __func__, args.size());
   link_layer_controller_.Reset();
-  if (loopback_mode_ == bluetooth::hci::LoopbackMode::ENABLE_LOCAL) {
-    loopback_mode_ = bluetooth::hci::LoopbackMode::NO_LOOPBACK;
+  if (loopback_mode_ == LoopbackMode::ENABLE_LOCAL) {
+    loopback_mode_ = LoopbackMode::NO_LOOPBACK;
   }
 
-  send_event_(bluetooth::hci::ResetCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS));
+  send_event_(bluetooth::hci::ResetCompleteBuilder::Create(kNumCommandPackets,
+                                                           ErrorCode::SUCCESS));
 }
 
-void DualModeController::HciReadBufferSize(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciReadBufferSize(PacketView<true> args) {
   ASSERT_LOG(args.size() == 0, "%s  size=%zu", __func__, args.size());
 
   auto packet = bluetooth::hci::ReadBufferSizeCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
+      kNumCommandPackets, ErrorCode::SUCCESS,
       properties_.GetAclDataPacketSize(),
       properties_.GetSynchronousDataPacketSize(),
       properties_.GetTotalNumAclDataPackets(),
@@ -367,28 +366,25 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciReadEncryptionKeySize(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciReadEncryptionKeySize(PacketView<true> args) {
   ASSERT_LOG(args.size() == 2, "%s  size=%zu", __func__, args.size());
 
   uint16_t handle = args.begin().extract<uint16_t>();
 
   auto packet = bluetooth::hci::ReadEncryptionKeySizeCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, handle,
+      kNumCommandPackets, ErrorCode::SUCCESS, handle,
       properties_.GetEncryptionKeySize());
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciHostBufferSize(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciHostBufferSize(PacketView<true> args) {
   ASSERT_LOG(args.size() == 7, "%s  size=%zu", __func__, args.size());
   auto packet = bluetooth::hci::HostBufferSizeCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciReadLocalVersionInformation(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciReadLocalVersionInformation(PacketView<true> args) {
   ASSERT_LOG(args.size() == 0, "%s  size=%zu", __func__, args.size());
 
   bluetooth::hci::LocalVersionInformation local_version_information;
@@ -402,19 +398,18 @@
   local_version_information.lmp_subversion_ = properties_.GetLmpPalSubversion();
   auto packet =
       bluetooth::hci::ReadLocalVersionInformationCompleteBuilder::Create(
-          kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
-          local_version_information);
+          kNumCommandPackets, ErrorCode::SUCCESS, local_version_information);
   send_event_(std::move(packet));
 }
 
 void DualModeController::HciReadRemoteVersionInformation(
-    bluetooth::packet::PacketView<true> args) {
+    PacketView<true> args) {
   ASSERT_LOG(args.size() == 2, "%s  size=%zu", __func__, args.size());
 
   uint16_t handle = args.begin().extract<uint16_t>();
 
   auto status = link_layer_controller_.SendCommandToRemoteByHandle(
-      bluetooth::hci::OpCode::READ_REMOTE_VERSION_INFORMATION, args, handle);
+      OpCode::READ_REMOTE_VERSION_INFORMATION, args, handle);
 
   auto packet =
       bluetooth::hci::ReadRemoteVersionInformationStatusBuilder::Create(
@@ -422,17 +417,14 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciReadBdAddr(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciReadBdAddr(PacketView<true> args) {
   ASSERT_LOG(args.size() == 0, "%s  size=%zu", __func__, args.size());
   auto packet = bluetooth::hci::ReadBdAddrCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
-      properties_.GetAddress());
+      kNumCommandPackets, ErrorCode::SUCCESS, properties_.GetAddress());
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciReadLocalSupportedCommands(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciReadLocalSupportedCommands(PacketView<true> args) {
   ASSERT_LOG(args.size() == 0, "%s  size=%zu", __func__, args.size());
 
   std::array<uint8_t, 64> supported_commands;
@@ -446,59 +438,53 @@
 
   auto packet =
       bluetooth::hci::ReadLocalSupportedCommandsCompleteBuilder::Create(
-          kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
-          supported_commands);
+          kNumCommandPackets, ErrorCode::SUCCESS, supported_commands);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciReadLocalSupportedFeatures(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciReadLocalSupportedFeatures(PacketView<true> args) {
   ASSERT_LOG(args.size() == 0, "%s  size=%zu", __func__, args.size());
   auto packet =
       bluetooth::hci::ReadLocalSupportedFeaturesCompleteBuilder::Create(
-          kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
+          kNumCommandPackets, ErrorCode::SUCCESS,
           properties_.GetSupportedFeatures());
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciReadLocalSupportedCodecs(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciReadLocalSupportedCodecs(PacketView<true> args) {
   ASSERT_LOG(args.size() == 0, "%s  size=%zu", __func__, args.size());
   auto packet = bluetooth::hci::ReadLocalSupportedCodecsCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
-      properties_.GetSupportedCodecs(), properties_.GetVendorSpecificCodecs());
+      kNumCommandPackets, ErrorCode::SUCCESS, properties_.GetSupportedCodecs(),
+      properties_.GetVendorSpecificCodecs());
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciReadLocalExtendedFeatures(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciReadLocalExtendedFeatures(PacketView<true> args) {
   ASSERT_LOG(args.size() == 1, "%s  size=%zu", __func__, args.size());
   uint8_t page_number = args.begin().extract<uint8_t>();
 
   auto pakcet =
       bluetooth::hci::ReadLocalExtendedFeaturesCompleteBuilder::Create(
-          kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, page_number,
+          kNumCommandPackets, ErrorCode::SUCCESS, page_number,
           properties_.GetExtendedFeaturesMaximumPageNumber(),
           properties_.GetExtendedFeatures(page_number));
   send_event_(std::move(pakcet));
 }
 
-void DualModeController::HciReadRemoteExtendedFeatures(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciReadRemoteExtendedFeatures(PacketView<true> args) {
   ASSERT_LOG(args.size() == 3, "%s  size=%zu", __func__, args.size());
 
   uint16_t handle = args.begin().extract<uint16_t>();
 
   auto status = link_layer_controller_.SendCommandToRemoteByHandle(
-      bluetooth::hci::OpCode::READ_REMOTE_EXTENDED_FEATURES, args, handle);
+      OpCode::READ_REMOTE_EXTENDED_FEATURES, args, handle);
 
   auto packet = bluetooth::hci::ReadRemoteExtendedFeaturesStatusBuilder::Create(
       status, kNumCommandPackets);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciSwitchRole(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciSwitchRole(PacketView<true> args) {
   ASSERT_LOG(args.size() == 7, "%s  size=%zu", __func__, args.size());
 
   Address address = args.begin().extract<Address>();
@@ -511,14 +497,13 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciReadRemoteSupportedFeatures(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciReadRemoteSupportedFeatures(PacketView<true> args) {
   ASSERT_LOG(args.size() == 2, "%s  size=%zu", __func__, args.size());
 
   uint16_t handle = args.begin().extract<uint16_t>();
 
   auto status = link_layer_controller_.SendCommandToRemoteByHandle(
-      bluetooth::hci::OpCode::READ_REMOTE_SUPPORTED_FEATURES, args, handle);
+      OpCode::READ_REMOTE_SUPPORTED_FEATURES, args, handle);
 
   auto packet =
       bluetooth::hci::ReadRemoteSupportedFeaturesStatusBuilder::Create(
@@ -526,22 +511,20 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciReadClockOffset(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciReadClockOffset(PacketView<true> args) {
   ASSERT_LOG(args.size() == 2, "%s  size=%zu", __func__, args.size());
 
   uint16_t handle = args.begin().extract<uint16_t>();
 
   auto status = link_layer_controller_.SendCommandToRemoteByHandle(
-      bluetooth::hci::OpCode::READ_CLOCK_OFFSET, args, handle);
+      OpCode::READ_CLOCK_OFFSET, args, handle);
 
   auto packet = bluetooth::hci::ReadClockOffsetStatusBuilder::Create(
       status, kNumCommandPackets);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciIoCapabilityRequestReply(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciIoCapabilityRequestReply(PacketView<true> args) {
   ASSERT_LOG(args.size() == 9, "%s  size=%zu", __func__, args.size());
 
   auto args_itr = args.begin();
@@ -559,7 +542,7 @@
 }
 
 void DualModeController::HciUserConfirmationRequestReply(
-    bluetooth::packet::PacketView<true> args) {
+    PacketView<true> args) {
   ASSERT_LOG(args.size() == 6, "%s  size=%zu", __func__, args.size());
 
   Address peer = args.begin().extract<Address>();
@@ -573,7 +556,7 @@
 }
 
 void DualModeController::HciUserConfirmationRequestNegativeReply(
-    bluetooth::packet::PacketView<true> args) {
+    PacketView<true> args) {
   ASSERT_LOG(args.size() == 6, "%s  size=%zu", __func__, args.size());
 
   Address peer = args.begin().extract<Address>();
@@ -587,8 +570,7 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciUserPasskeyRequestReply(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciUserPasskeyRequestReply(PacketView<true> args) {
   ASSERT_LOG(args.size() == 10, "%s  size=%zu", __func__, args.size());
 
   auto args_itr = args.begin();
@@ -604,7 +586,7 @@
 }
 
 void DualModeController::HciUserPasskeyRequestNegativeReply(
-    bluetooth::packet::PacketView<true> args) {
+    PacketView<true> args) {
   ASSERT_LOG(args.size() == 6, "%s  size=%zu", __func__, args.size());
 
   Address peer = args.begin().extract<Address>();
@@ -617,8 +599,7 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciRemoteOobDataRequestReply(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciRemoteOobDataRequestReply(PacketView<true> args) {
   ASSERT_LOG(args.size() == 38, "%s  size=%zu", __func__, args.size());
 
   auto args_itr = args.begin();
@@ -640,7 +621,7 @@
 }
 
 void DualModeController::HciRemoteOobDataRequestNegativeReply(
-    bluetooth::packet::PacketView<true> args) {
+    PacketView<true> args) {
   ASSERT_LOG(args.size() == 6, "%s  size=%zu", __func__, args.size());
 
   Address peer = args.begin().extract<Address>();
@@ -654,13 +635,12 @@
 }
 
 void DualModeController::HciIoCapabilityRequestNegativeReply(
-    bluetooth::packet::PacketView<true> args) {
+    PacketView<true> args) {
   ASSERT_LOG(args.size() == 7, "%s  size=%zu", __func__, args.size());
 
   auto args_itr = args.begin();
   Address peer = args_itr.extract<Address>();
-  bluetooth::hci::ErrorCode reason =
-      args_itr.extract<bluetooth::hci::ErrorCode>();
+  ErrorCode reason = args_itr.extract<ErrorCode>();
 
   auto status =
       link_layer_controller_.IoCapabilityRequestNegativeReply(peer, reason);
@@ -671,18 +651,16 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciWriteSimplePairingMode(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciWriteSimplePairingMode(PacketView<true> args) {
   ASSERT_LOG(args.size() == 1, "%s  size=%zu", __func__, args.size());
   ASSERT(args[0] == 1 || args[0] == 0);
   link_layer_controller_.WriteSimplePairingMode(args[0] == 1);
   auto packet = bluetooth::hci::WriteSimplePairingModeCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciChangeConnectionPacketType(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciChangeConnectionPacketType(PacketView<true> args) {
   ASSERT_LOG(args.size() == 4, "%s  size=%zu", __func__, args.size());
   auto args_itr = args.begin();
   uint16_t handle = args_itr.extract<uint16_t>();
@@ -696,59 +674,53 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciWriteLeHostSupport(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciWriteLeHostSupport(PacketView<true> args) {
   ASSERT_LOG(args.size() == 2, "%s  size=%zu", __func__, args.size());
   auto packet = bluetooth::hci::WriteLeHostSupportCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
 void DualModeController::HciWriteSecureConnectionsHostSupport(
-    bluetooth::packet::PacketView<true> args) {
+    PacketView<true> args) {
   ASSERT_LOG(args.size() == 1, "%s  size=%zu", __func__, args.size());
   properties_.SetExtendedFeatures(properties_.GetExtendedFeatures(1) | 0x8, 1);
   auto packet =
       bluetooth::hci::WriteSecureConnectionsHostSupportCompleteBuilder::Create(
-          kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+          kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciSetEventMask(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciSetEventMask(PacketView<true> args) {
   ASSERT_LOG(args.size() == 8, "%s  size=%zu", __func__, args.size());
   auto packet = bluetooth::hci::SetEventMaskCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciWriteInquiryMode(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciWriteInquiryMode(PacketView<true> args) {
   ASSERT_LOG(args.size() == 1, "%s  size=%zu", __func__, args.size());
   link_layer_controller_.SetInquiryMode(args[0]);
   auto packet = bluetooth::hci::WriteInquiryModeCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciWritePageScanType(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciWritePageScanType(PacketView<true> args) {
   ASSERT_LOG(args.size() == 1, "%s  size=%zu", __func__, args.size());
   auto packet = bluetooth::hci::WritePageScanTypeCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciWriteInquiryScanType(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciWriteInquiryScanType(PacketView<true> args) {
   ASSERT_LOG(args.size() == 1, "%s  size=%zu", __func__, args.size());
   auto packet = bluetooth::hci::WriteInquiryScanTypeCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciAuthenticationRequested(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciAuthenticationRequested(PacketView<true> args) {
   ASSERT_LOG(args.size() == 2, "%s  size=%zu", __func__, args.size());
   uint16_t handle = args.begin().extract<uint16_t>();
   auto status = link_layer_controller_.AuthenticationRequested(handle);
@@ -758,8 +730,7 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciSetConnectionEncryption(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciSetConnectionEncryption(PacketView<true> args) {
   ASSERT_LOG(args.size() == 3, "%s  size=%zu", __func__, args.size());
   auto args_itr = args.begin();
   uint16_t handle = args_itr.extract<uint16_t>();
@@ -772,8 +743,7 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciChangeConnectionLinkKey(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciChangeConnectionLinkKey(PacketView<true> args) {
   ASSERT_LOG(args.size() == 2, "%s  size=%zu", __func__, args.size());
   auto args_itr = args.begin();
   uint16_t handle = args_itr.extract<uint16_t>();
@@ -785,8 +755,7 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciMasterLinkKey(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciMasterLinkKey(PacketView<true> args) {
   ASSERT_LOG(args.size() == 1, "%s  size=%zu", __func__, args.size());
   auto args_itr = args.begin();
   uint8_t key_flag = args_itr.extract<uint8_t>();
@@ -798,44 +767,40 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciWriteAuthenticationEnable(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciWriteAuthenticationEnable(PacketView<true> args) {
   ASSERT_LOG(args.size() == 1, "%s  size=%zu", __func__, args.size());
   properties_.SetAuthenticationEnable(args[0]);
   auto packet =
       bluetooth::hci::WriteAuthenticationEnableCompleteBuilder::Create(
-          kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+          kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciReadAuthenticationEnable(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciReadAuthenticationEnable(PacketView<true> args) {
   ASSERT_LOG(args.size() == 0, "%s  size=%zu", __func__, args.size());
   auto packet = bluetooth::hci::ReadAuthenticationEnableCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
+      kNumCommandPackets, ErrorCode::SUCCESS,
       static_cast<bluetooth::hci::AuthenticationEnable>(
           properties_.GetAuthenticationEnable()));
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciWriteClassOfDevice(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciWriteClassOfDevice(PacketView<true> args) {
   ASSERT_LOG(args.size() == 3, "%s  size=%zu", __func__, args.size());
   properties_.SetClassOfDevice(args[0], args[1], args[2]);
   auto packet = bluetooth::hci::WriteClassOfDeviceCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciWritePageTimeout(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciWritePageTimeout(PacketView<true> args) {
   ASSERT_LOG(args.size() == 2, "%s  size=%zu", __func__, args.size());
   auto packet = bluetooth::hci::WritePageTimeoutCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciHoldMode(bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciHoldMode(PacketView<true> args) {
   ASSERT_LOG(args.size() == 6, "%s  size=%zu", __func__, args.size());
   auto args_itr = args.begin();
   uint16_t handle = args_itr.extract<uint16_t>();
@@ -850,8 +815,7 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciSniffMode(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciSniffMode(PacketView<true> args) {
   ASSERT_LOG(args.size() == 10, "%s  size=%zu", __func__, args.size());
   auto args_itr = args.begin();
   uint16_t handle = args_itr.extract<uint16_t>();
@@ -869,8 +833,7 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciExitSniffMode(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciExitSniffMode(PacketView<true> args) {
   ASSERT_LOG(args.size() == 2, "%s  size=%zu", __func__, args.size());
   auto args_itr = args.begin();
   uint16_t handle = args_itr.extract<uint16_t>();
@@ -882,7 +845,7 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciQosSetup(bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciQosSetup(PacketView<true> args) {
   ASSERT_LOG(args.size() == 20, "%s  size=%zu", __func__, args.size());
   auto args_itr = args.begin();
   uint16_t handle = args_itr.extract<uint16_t>();
@@ -903,16 +866,15 @@
 }
 
 void DualModeController::HciWriteDefaultLinkPolicySettings(
-    bluetooth::packet::PacketView<true> args) {
+    PacketView<true> args) {
   ASSERT_LOG(args.size() == 2, "%s  size=%zu", __func__, args.size());
   auto packet =
       bluetooth::hci::WriteDefaultLinkPolicySettingsCompleteBuilder::Create(
-          kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+          kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciFlowSpecification(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciFlowSpecification(PacketView<true> args) {
   ASSERT_LOG(args.size() == 21, "%s  size=%zu", __func__, args.size());
   auto args_itr = args.begin();
   uint16_t handle = args_itr.extract<uint16_t>();
@@ -933,8 +895,7 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciWriteLinkPolicySettings(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciWriteLinkPolicySettings(PacketView<true> args) {
   ASSERT_LOG(args.size() == 4, "%s  size=%zu", __func__, args.size());
 
   auto args_itr = args.begin();
@@ -949,8 +910,7 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciWriteLinkSupervisionTimeout(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciWriteLinkSupervisionTimeout(PacketView<true> args) {
   ASSERT_LOG(args.size() == 4, "%s  size=%zu", __func__, args.size());
 
   auto args_itr = args.begin();
@@ -965,8 +925,7 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciReadLocalName(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciReadLocalName(PacketView<true> args) {
   ASSERT_LOG(args.size() == 0, "%s  size=%zu", __func__, args.size());
 
   std::array<uint8_t, 248> local_name;
@@ -978,113 +937,104 @@
   std::copy_n(properties_.GetName().begin(), len, local_name.begin());
 
   auto packet = bluetooth::hci::ReadLocalNameCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, local_name);
+      kNumCommandPackets, ErrorCode::SUCCESS, local_name);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciWriteLocalName(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciWriteLocalName(PacketView<true> args) {
   ASSERT_LOG(args.size() == 248, "%s  size=%zu", __func__, args.size());
   std::vector<uint8_t> clipped(args.begin(), args.begin() + LastNonZero(args) + 1);
   properties_.SetName(clipped);
   auto packet = bluetooth::hci::WriteLocalNameCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
 void DualModeController::HciWriteExtendedInquiryResponse(
-    bluetooth::packet::PacketView<true> args) {
+    PacketView<true> args) {
   ASSERT_LOG(args.size() == 241, "%s  size=%zu", __func__, args.size());
   // Strip FEC byte and trailing zeros
   std::vector<uint8_t> clipped(args.begin() + 1, args.begin() + LastNonZero(args) + 1);
   properties_.SetExtendedInquiryData(clipped);
   auto packet =
       bluetooth::hci::WriteExtendedInquiryResponseCompleteBuilder::Create(
-          kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+          kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciRefreshEncryptionKey(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciRefreshEncryptionKey(PacketView<true> args) {
   ASSERT_LOG(args.size() == 2, "%s  size=%zu", __func__, args.size());
   auto args_itr = args.begin();
   uint16_t handle = args_itr.extract<uint16_t>();
   auto status_packet =
       bluetooth::hci::RefreshEncryptionKeyStatusBuilder::Create(
-          bluetooth::hci::ErrorCode::SUCCESS, kNumCommandPackets);
+          ErrorCode::SUCCESS, kNumCommandPackets);
   send_event_(std::move(status_packet));
   // TODO: Support this in the link layer
   auto complete_packet =
       bluetooth::hci::EncryptionKeyRefreshCompleteBuilder::Create(
-          bluetooth::hci::ErrorCode::SUCCESS, handle);
+          ErrorCode::SUCCESS, handle);
   send_event_(std::move(complete_packet));
 }
 
-void DualModeController::HciWriteVoiceSetting(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciWriteVoiceSetting(PacketView<true> args) {
   ASSERT_LOG(args.size() == 2, "%s  size=%zu", __func__, args.size());
   auto packet = bluetooth::hci::WriteVoiceSettingCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciWriteCurrentIacLap(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciWriteCurrentIacLap(PacketView<true> args) {
   ASSERT(args.size() > 0);
   ASSERT(args.size() == 1 + (3 * args[0]));  // count + 3-byte IACs
   auto packet = bluetooth::hci::WriteCurrentIacLapCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciWriteInquiryScanActivity(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciWriteInquiryScanActivity(PacketView<true> args) {
   ASSERT_LOG(args.size() == 4, "%s  size=%zu", __func__, args.size());
   auto packet = bluetooth::hci::WriteInquiryScanActivityCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciWriteScanEnable(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciWriteScanEnable(PacketView<true> args) {
   ASSERT_LOG(args.size() == 1, "%s  size=%zu", __func__, args.size());
   link_layer_controller_.SetInquiryScanEnable(args[0] & 0x1);
   link_layer_controller_.SetPageScanEnable(args[0] & 0x2);
   auto packet = bluetooth::hci::WriteScanEnableCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciSetEventFilter(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciSetEventFilter(PacketView<true> args) {
   ASSERT(args.size() > 0);
   auto packet = bluetooth::hci::SetEventFilterCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciInquiry(bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciInquiry(PacketView<true> args) {
   ASSERT_LOG(args.size() == 5, "%s  size=%zu", __func__, args.size());
   link_layer_controller_.SetInquiryLAP(args[0] | (args[1], 8) | (args[2], 16));
   link_layer_controller_.SetInquiryMaxResponses(args[4]);
   link_layer_controller_.StartInquiry(std::chrono::milliseconds(args[3] * 1280));
 
   auto packet = bluetooth::hci::InquiryStatusBuilder::Create(
-      bluetooth::hci::ErrorCode::SUCCESS, kNumCommandPackets);
+      ErrorCode::SUCCESS, kNumCommandPackets);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciInquiryCancel(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciInquiryCancel(PacketView<true> args) {
   ASSERT_LOG(args.size() == 0, "%s  size=%zu", __func__, args.size());
   link_layer_controller_.InquiryCancel();
   auto packet = bluetooth::hci::InquiryCancelCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciAcceptConnectionRequest(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciAcceptConnectionRequest(PacketView<true> args) {
   ASSERT_LOG(args.size() == 7, "%s  size=%zu", __func__, args.size());
   Address addr = args.begin().extract<Address>();
   bool try_role_switch = args[6] == 0;
@@ -1095,8 +1045,7 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciRejectConnectionRequest(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciRejectConnectionRequest(PacketView<true> args) {
   ASSERT_LOG(args.size() == 7, "%s  size=%zu", __func__, args.size());
   auto args_itr = args.begin();
   Address addr = args_itr.extract<Address>();
@@ -1107,8 +1056,7 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLinkKeyRequestReply(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLinkKeyRequestReply(PacketView<true> args) {
   ASSERT_LOG(args.size() == 22, "%s  size=%zu", __func__, args.size());
   auto args_it = args.begin();
   Address addr = args_it.extract<Address>();
@@ -1119,8 +1067,7 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLinkKeyRequestNegativeReply(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLinkKeyRequestNegativeReply(PacketView<true> args) {
   ASSERT_LOG(args.size() == 6, "%s  size=%zu", __func__, args.size());
   Address addr = args.begin().extract<Address>();
   auto status = link_layer_controller_.LinkKeyRequestNegativeReply(addr);
@@ -1130,8 +1077,7 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciDeleteStoredLinkKey(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciDeleteStoredLinkKey(PacketView<true> args) {
   ASSERT_LOG(args.size() == 7, "%s  size=%zu", __func__, args.size());
 
   uint16_t deleted_keys = 0;
@@ -1146,39 +1092,36 @@
   }
 
   auto packet = bluetooth::hci::DeleteStoredLinkKeyCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, deleted_keys);
+      kNumCommandPackets, ErrorCode::SUCCESS, deleted_keys);
 
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciRemoteNameRequest(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciRemoteNameRequest(PacketView<true> args) {
   ASSERT_LOG(args.size() == 10, "%s  size=%zu", __func__, args.size());
 
   Address remote_addr = args.begin().extract<Address>();
 
   auto status = link_layer_controller_.SendCommandToRemoteByAddress(
-      bluetooth::hci::OpCode::REMOTE_NAME_REQUEST, args, remote_addr);
+      OpCode::REMOTE_NAME_REQUEST, args, remote_addr);
 
   auto packet = bluetooth::hci::RemoteNameRequestStatusBuilder::Create(
       status, kNumCommandPackets);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeSetEventMask(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeSetEventMask(PacketView<true> args) {
   ASSERT_LOG(args.size() == 8, "%s  size=%zu", __func__, args.size());
   /*
     uint64_t mask = args.begin().extract<uint64_t>();
     link_layer_controller_.SetLeEventMask(mask);
   */
   auto packet = bluetooth::hci::LeSetEventMaskCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeReadBufferSize(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeReadBufferSize(PacketView<true> args) {
   ASSERT_LOG(args.size() == 0, "%s  size=%zu", __func__, args.size());
 
   bluetooth::hci::LeBufferSize le_buffer_size;
@@ -1186,31 +1129,29 @@
   le_buffer_size.total_num_le_packets_ = properties_.GetTotalNumLeDataPackets();
 
   auto packet = bluetooth::hci::LeReadBufferSizeCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, le_buffer_size);
+      kNumCommandPackets, ErrorCode::SUCCESS, le_buffer_size);
   send_event_(std::move(packet));
 }
 
 void DualModeController::HciLeReadLocalSupportedFeatures(
-    bluetooth::packet::PacketView<true> args) {
+    PacketView<true> args) {
   ASSERT_LOG(args.size() == 0, "%s  size=%zu", __func__, args.size());
   auto packet =
       bluetooth::hci::LeReadLocalSupportedFeaturesCompleteBuilder::Create(
-          kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
+          kNumCommandPackets, ErrorCode::SUCCESS,
           properties_.GetLeSupportedFeatures());
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeSetRandomAddress(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeSetRandomAddress(PacketView<true> args) {
   ASSERT_LOG(args.size() == 6, "%s  size=%zu", __func__, args.size());
   properties_.SetLeAddress(args.begin().extract<Address>());
   auto packet = bluetooth::hci::LeSetRandomAddressCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeSetAdvertisingParameters(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeSetAdvertisingParameters(PacketView<true> args) {
   ASSERT_LOG(args.size() == 15, "%s  size=%zu", __func__, args.size());
   auto args_itr = args.begin();
   properties_.SetLeAdvertisingParameters(
@@ -1223,30 +1164,27 @@
 
   auto packet =
       bluetooth::hci::LeSetAdvertisingParametersCompleteBuilder::Create(
-          kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+          kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeSetAdvertisingData(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeSetAdvertisingData(PacketView<true> args) {
   ASSERT_LOG(args.size() == 32, "%s  size=%zu", __func__, args.size());
   properties_.SetLeAdvertisement(std::vector<uint8_t>(args.begin() + 1, args.end()));
   auto packet = bluetooth::hci::LeSetAdvertisingDataCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeSetScanResponseData(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeSetScanResponseData(PacketView<true> args) {
   ASSERT_LOG(args.size() == 32, "%s  size=%zu", __func__, args.size());
   properties_.SetLeScanResponse(std::vector<uint8_t>(args.begin() + 1, args.end()));
   auto packet = bluetooth::hci::LeSetScanResponseDataCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeSetAdvertisingEnable(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeSetAdvertisingEnable(PacketView<true> args) {
   ASSERT_LOG(args.size() == 1, "%s  size=%zu", __func__, args.size());
   auto status = link_layer_controller_.SetLeAdvertisingEnable(
       args.begin().extract<uint8_t>());
@@ -1255,8 +1193,7 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeSetScanParameters(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeSetScanParameters(PacketView<true> args) {
   ASSERT_LOG(args.size() == 7, "%s  size=%zu", __func__, args.size());
   link_layer_controller_.SetLeScanType(args[0]);
   link_layer_controller_.SetLeScanInterval(args[1] | (args[2], 8));
@@ -1264,22 +1201,20 @@
   link_layer_controller_.SetLeAddressType(args[5]);
   link_layer_controller_.SetLeScanFilterPolicy(args[6]);
   auto packet = bluetooth::hci::LeSetScanParametersCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeSetScanEnable(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeSetScanEnable(PacketView<true> args) {
   ASSERT_LOG(args.size() == 2, "%s  size=%zu", __func__, args.size());
   link_layer_controller_.SetLeScanEnable(args[0]);
   link_layer_controller_.SetLeFilterDuplicates(args[1]);
   auto packet = bluetooth::hci::LeSetScanEnableCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeCreateConnection(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeCreateConnection(PacketView<true> args) {
   ASSERT_LOG(args.size() == 25, "%s  size=%zu", __func__, args.size());
   auto args_itr = args.begin();
   link_layer_controller_.SetLeScanInterval(args_itr.extract<uint16_t>());
@@ -1308,23 +1243,20 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeConnectionUpdate(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeConnectionUpdate(PacketView<true> args) {
   ASSERT_LOG(args.size() == 14, "%s  size=%zu", __func__, args.size());
 
   auto status_packet = bluetooth::hci::LeConnectionUpdateStatusBuilder::Create(
-      bluetooth::hci::ErrorCode::CONNECTION_REJECTED_UNACCEPTABLE_BD_ADDR,
-      kNumCommandPackets);
+      ErrorCode::CONNECTION_REJECTED_UNACCEPTABLE_BD_ADDR, kNumCommandPackets);
   send_event_(std::move(status_packet));
 
   auto complete_packet =
       bluetooth::hci::LeConnectionUpdateCompleteBuilder::Create(
-          bluetooth::hci::ErrorCode::SUCCESS, 0x0002, 0x0006, 0x0000, 0x01f4);
+          ErrorCode::SUCCESS, 0x0002, 0x0006, 0x0000, 0x01f4);
   send_event_(std::move(complete_packet));
 }
 
-void DualModeController::HciCreateConnection(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciCreateConnection(PacketView<true> args) {
   ASSERT_LOG(args.size() == 13, "%s  size=%zu", __func__, args.size());
 
   auto args_itr = args.begin();
@@ -1342,8 +1274,7 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciDisconnect(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciDisconnect(PacketView<true> args) {
   ASSERT_LOG(args.size() == 3, "%s  size=%zu", __func__, args.size());
 
   auto args_itr = args.begin();
@@ -1357,47 +1288,41 @@
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeConnectionCancel(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeConnectionCancel(PacketView<true> args) {
   ASSERT_LOG(args.size() == 0, "%s  size=%zu", __func__, args.size());
   link_layer_controller_.SetLeConnect(false);
   auto packet = bluetooth::hci::LeCreateConnectionCancelStatusBuilder::Create(
-      bluetooth::hci::ErrorCode::SUCCESS, kNumCommandPackets);
+      ErrorCode::SUCCESS, kNumCommandPackets);
   send_event_(std::move(packet));
   /* For testing Jakub's patch:  Figure out a neat way to call this without
      recompiling.  I'm thinking about a bad device. */
   /*
   SendCommandCompleteOnlyStatus(OpCode::LE_CREATE_CONNECTION_CANCEL,
-                                bluetooth::hci::ErrorCode::COMMAND_DISALLOWED);
+                                ErrorCode::COMMAND_DISALLOWED);
   */
 }
 
-void DualModeController::HciLeReadWhiteListSize(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeReadWhiteListSize(PacketView<true> args) {
   ASSERT_LOG(args.size() == 0, "%s  size=%zu", __func__, args.size());
   auto packet = bluetooth::hci::LeReadWhiteListSizeCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
-      properties_.GetLeWhiteListSize());
+      kNumCommandPackets, ErrorCode::SUCCESS, properties_.GetLeWhiteListSize());
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeClearWhiteList(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeClearWhiteList(PacketView<true> args) {
   ASSERT_LOG(args.size() == 0, "%s  size=%zu", __func__, args.size());
   link_layer_controller_.LeWhiteListClear();
   auto packet = bluetooth::hci::LeClearWhiteListCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeAddDeviceToWhiteList(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeAddDeviceToWhiteList(PacketView<true> args) {
   ASSERT_LOG(args.size() == 7, "%s  size=%zu", __func__, args.size());
 
   if (link_layer_controller_.LeWhiteListFull()) {
     auto packet = bluetooth::hci::LeAddDeviceToWhiteListCompleteBuilder::Create(
-        kNumCommandPackets,
-        bluetooth::hci::ErrorCode::MEMORY_CAPACITY_EXCEEDED);
+        kNumCommandPackets, ErrorCode::MEMORY_CAPACITY_EXCEEDED);
     send_event_(std::move(packet));
     return;
   }
@@ -1406,12 +1331,11 @@
   Address address = args_itr.extract<Address>();
   link_layer_controller_.LeWhiteListAddDevice(address, addr_type);
   auto packet = bluetooth::hci::LeAddDeviceToWhiteListCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeRemoveDeviceFromWhiteList(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeRemoveDeviceFromWhiteList(PacketView<true> args) {
   ASSERT_LOG(args.size() == 7, "%s  size=%zu", __func__, args.size());
 
   auto args_itr = args.begin();
@@ -1420,28 +1344,25 @@
   link_layer_controller_.LeWhiteListRemoveDevice(address, addr_type);
   auto packet =
       bluetooth::hci::LeRemoveDeviceFromWhiteListCompleteBuilder::Create(
-          kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+          kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeClearResolvingList(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeClearResolvingList(PacketView<true> args) {
   ASSERT_LOG(args.size() == 0, "%s  size=%zu", __func__, args.size());
   link_layer_controller_.LeResolvingListClear();
   auto packet = bluetooth::hci::LeClearResolvingListCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeAddDeviceToResolvingList(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeAddDeviceToResolvingList(PacketView<true> args) {
   ASSERT_LOG(args.size() == 39, "%s  size=%zu", __func__, args.size());
 
   if (link_layer_controller_.LeResolvingListFull()) {
     auto packet =
         bluetooth::hci::LeAddDeviceToResolvingListCompleteBuilder::Create(
-            kNumCommandPackets,
-            bluetooth::hci::ErrorCode::MEMORY_CAPACITY_EXCEEDED);
+            kNumCommandPackets, ErrorCode::MEMORY_CAPACITY_EXCEEDED);
     send_event_(std::move(packet));
     return;
   }
@@ -1464,12 +1385,12 @@
                                                   localIrk);
   auto packet =
       bluetooth::hci::LeAddDeviceToResolvingListCompleteBuilder::Create(
-          kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+          kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
 void DualModeController::HciLeRemoveDeviceFromResolvingList(
-    bluetooth::packet::PacketView<true> args) {
+    PacketView<true> args) {
   ASSERT_LOG(args.size() == 7, "%s  size=%zu", __func__, args.size());
 
   auto args_itr = args.begin();
@@ -1478,12 +1399,11 @@
   link_layer_controller_.LeResolvingListRemoveDevice(address, addr_type);
   auto packet =
       bluetooth::hci::LeRemoveDeviceFromResolvingListCompleteBuilder::Create(
-          kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+          kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeSetPrivacyMode(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeSetPrivacyMode(PacketView<true> args) {
   ASSERT_LOG(args.size() == 8, "%s  size=%zu", __func__, args.size());
 
   auto args_itr = args.begin();
@@ -1498,25 +1418,24 @@
   }
 
   auto packet = bluetooth::hci::LeSetPrivacyModeCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeReadRemoteFeatures(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeReadRemoteFeatures(PacketView<true> args) {
   ASSERT_LOG(args.size() == 2, "%s  size=%zu", __func__, args.size());
 
   uint16_t handle = args.begin().extract<uint16_t>();
 
   auto status = link_layer_controller_.SendCommandToRemoteByHandle(
-      bluetooth::hci::OpCode::LE_READ_REMOTE_FEATURES, args, handle);
+      OpCode::LE_READ_REMOTE_FEATURES, args, handle);
 
   auto packet = bluetooth::hci::LeConnectionUpdateStatusBuilder::Create(
       status, kNumCommandPackets);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeRand(bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeRand(PacketView<true> args) {
   ASSERT_LOG(args.size() == 0, "%s  size=%zu", __func__, args.size());
   uint64_t random_val = 0;
   for (size_t rand_bytes = 0; rand_bytes < sizeof(uint64_t); rand_bytes += sizeof(RAND_MAX)) {
@@ -1524,71 +1443,63 @@
   }
 
   auto packet = bluetooth::hci::LeRandCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, random_val);
+      kNumCommandPackets, ErrorCode::SUCCESS, random_val);
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeReadSupportedStates(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeReadSupportedStates(PacketView<true> args) {
   ASSERT_LOG(args.size() == 0, "%s  size=%zu", __func__, args.size());
   auto packet = bluetooth::hci::LeReadSupportedStatesCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
+      kNumCommandPackets, ErrorCode::SUCCESS,
       properties_.GetLeSupportedStates());
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeVendorCap(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeVendorCap(PacketView<true> args) {
   ASSERT_LOG(args.size() == 0, "%s  size=%zu", __func__, args.size());
   vector<uint8_t> caps = properties_.GetLeVendorCap();
   if (caps.size() == 0) {
-    SendCommandCompleteUnknownOpCodeEvent(static_cast<uint16_t>(
-        bluetooth::hci::OpCode::LE_GET_VENDOR_CAPABILITIES));
+    SendCommandCompleteUnknownOpCodeEvent(
+        static_cast<uint16_t>(OpCode::LE_GET_VENDOR_CAPABILITIES));
     return;
   }
 
   std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
       std::make_unique<bluetooth::packet::RawBuilder>();
-  raw_builder_ptr->AddOctets1(
-      static_cast<uint8_t>(bluetooth::hci::ErrorCode::SUCCESS));
+  raw_builder_ptr->AddOctets1(static_cast<uint8_t>(ErrorCode::SUCCESS));
   raw_builder_ptr->AddOctets(properties_.GetLeVendorCap());
 
   auto packet = bluetooth::hci::CommandCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::OpCode::LE_GET_VENDOR_CAPABILITIES,
+      kNumCommandPackets, OpCode::LE_GET_VENDOR_CAPABILITIES,
       std::move(raw_builder_ptr));
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciLeVendorMultiAdv(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeVendorMultiAdv(PacketView<true> args) {
   ASSERT(args.size() > 0);
   SendCommandCompleteUnknownOpCodeEvent(
-      static_cast<uint16_t>(bluetooth::hci::OpCode::LE_MULTI_ADVT));
+      static_cast<uint16_t>(OpCode::LE_MULTI_ADVT));
 }
 
-void DualModeController::HciLeAdvertisingFilter(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeAdvertisingFilter(PacketView<true> args) {
   ASSERT(args.size() > 0);
   SendCommandCompleteUnknownOpCodeEvent(
-      static_cast<uint16_t>(bluetooth::hci::OpCode::LE_ADV_FILTER));
+      static_cast<uint16_t>(OpCode::LE_ADV_FILTER));
 }
 
-void DualModeController::HciLeEnergyInfo(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeEnergyInfo(PacketView<true> args) {
   ASSERT(args.size() > 0);
   SendCommandCompleteUnknownOpCodeEvent(
-      static_cast<uint16_t>(bluetooth::hci::OpCode::LE_ENERGY_INFO));
+      static_cast<uint16_t>(OpCode::LE_ENERGY_INFO));
 }
 
-void DualModeController::HciLeExtendedScanParams(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeExtendedScanParams(PacketView<true> args) {
   ASSERT(args.size() > 0);
   SendCommandCompleteUnknownOpCodeEvent(
-      static_cast<uint16_t>(bluetooth::hci::OpCode::LE_EXTENDED_SCAN_PARAMS));
+      static_cast<uint16_t>(OpCode::LE_EXTENDED_SCAN_PARAMS));
 }
 
-void DualModeController::HciLeStartEncryption(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciLeStartEncryption(PacketView<true> args) {
   ASSERT_LOG(args.size() == 28, "%s  size=%zu", __func__, args.size());
 
   auto args_itr = args.begin();
@@ -1600,12 +1511,11 @@
   //   long_term_key.push_back(args_itr.extract<uint18_t>();
   // }
   auto status_packet = bluetooth::hci::LeStartEncryptionStatusBuilder::Create(
-      bluetooth::hci::ErrorCode::SUCCESS, kNumCommandPackets);
+      ErrorCode::SUCCESS, kNumCommandPackets);
   send_event_(std::move(status_packet));
 
   auto complete_packet = bluetooth::hci::EncryptionChangeBuilder::Create(
-      bluetooth::hci::ErrorCode::SUCCESS, handle,
-      bluetooth::hci::EncryptionEnabled::OFF);
+      ErrorCode::SUCCESS, handle, bluetooth::hci::EncryptionEnabled::OFF);
   send_event_(std::move(complete_packet));
 #if 0
 
@@ -1661,33 +1571,31 @@
 #endif
 }
 
-void DualModeController::HciReadLoopbackMode(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciReadLoopbackMode(PacketView<true> args) {
   ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
   auto packet = bluetooth::hci::ReadLoopbackModeCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
-      static_cast<bluetooth::hci::LoopbackMode>(loopback_mode_));
+      kNumCommandPackets, ErrorCode::SUCCESS,
+      static_cast<LoopbackMode>(loopback_mode_));
   send_event_(std::move(packet));
 }
 
-void DualModeController::HciWriteLoopbackMode(
-    bluetooth::packet::PacketView<true> args) {
+void DualModeController::HciWriteLoopbackMode(PacketView<true> args) {
   ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
-  loopback_mode_ = static_cast<bluetooth::hci::LoopbackMode>(args[0]);
+  loopback_mode_ = static_cast<LoopbackMode>(args[0]);
   // ACL channel
   uint16_t acl_handle = 0x123;
   auto packet_acl = bluetooth::hci::ConnectionCompleteBuilder::Create(
-      bluetooth::hci::ErrorCode::SUCCESS, acl_handle, properties_.GetAddress(),
+      ErrorCode::SUCCESS, acl_handle, properties_.GetAddress(),
       bluetooth::hci::LinkType::ACL, bluetooth::hci::Enable::DISABLED);
   send_event_(std::move(packet_acl));
   // SCO channel
   uint16_t sco_handle = 0x345;
   auto packet_sco = bluetooth::hci::ConnectionCompleteBuilder::Create(
-      bluetooth::hci::ErrorCode::SUCCESS, sco_handle, properties_.GetAddress(),
+      ErrorCode::SUCCESS, sco_handle, properties_.GetAddress(),
       bluetooth::hci::LinkType::SCO, bluetooth::hci::Enable::DISABLED);
   send_event_(std::move(packet_sco));
   auto packet = bluetooth::hci::WriteLoopbackModeCompleteBuilder::Create(
-      kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+      kNumCommandPackets, ErrorCode::SUCCESS);
   send_event_(std::move(packet));
 }
 
diff --git a/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.h b/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.h
index d7c41e5..b024cbb 100644
--- a/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.h
+++ b/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.h
@@ -34,6 +34,7 @@
 namespace test_vendor_lib {
 
 using ::bluetooth::hci::Address;
+using ::bluetooth::packet::PacketView;
 
 // Emulates a dual mode BR/EDR + LE controller by maintaining the link layer
 // state machine detailed in the Bluetooth Core Specification Version 4.2,
@@ -106,326 +107,315 @@
   // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.1
 
   // 7.1.1
-  void HciInquiry(bluetooth::packet::PacketView<true> args);
+  void HciInquiry(PacketView<true> args);
 
   // 7.1.2
-  void HciInquiryCancel(bluetooth::packet::PacketView<true> args);
+  void HciInquiryCancel(PacketView<true> args);
 
   // 7.1.5
-  void HciCreateConnection(bluetooth::packet::PacketView<true> args);
+  void HciCreateConnection(PacketView<true> args);
 
   // 7.1.6
-  void HciDisconnect(bluetooth::packet::PacketView<true> args);
+  void HciDisconnect(PacketView<true> args);
 
   // 7.1.8
-  void HciAcceptConnectionRequest(bluetooth::packet::PacketView<true> args);
+  void HciAcceptConnectionRequest(PacketView<true> args);
 
   // 7.1.9
-  void HciRejectConnectionRequest(bluetooth::packet::PacketView<true> args);
+  void HciRejectConnectionRequest(PacketView<true> args);
 
   // 7.1.10
-  void HciLinkKeyRequestReply(bluetooth::packet::PacketView<true> args);
+  void HciLinkKeyRequestReply(PacketView<true> args);
 
   // 7.1.11
-  void HciLinkKeyRequestNegativeReply(bluetooth::packet::PacketView<true> args);
+  void HciLinkKeyRequestNegativeReply(PacketView<true> args);
 
   // 7.1.14
-  void HciChangeConnectionPacketType(bluetooth::packet::PacketView<true> args);
+  void HciChangeConnectionPacketType(PacketView<true> args);
 
   // 7.1.15
-  void HciAuthenticationRequested(bluetooth::packet::PacketView<true> args);
+  void HciAuthenticationRequested(PacketView<true> args);
 
   // 7.1.16
-  void HciSetConnectionEncryption(bluetooth::packet::PacketView<true> args);
+  void HciSetConnectionEncryption(PacketView<true> args);
 
   // 7.1.17
-  void HciChangeConnectionLinkKey(bluetooth::packet::PacketView<true> args);
+  void HciChangeConnectionLinkKey(PacketView<true> args);
 
   // 7.1.18
-  void HciMasterLinkKey(bluetooth::packet::PacketView<true> args);
+  void HciMasterLinkKey(PacketView<true> args);
 
   // 7.1.19
-  void HciRemoteNameRequest(bluetooth::packet::PacketView<true> args);
+  void HciRemoteNameRequest(PacketView<true> args);
 
   // 7.2.8
-  void HciSwitchRole(bluetooth::packet::PacketView<true> args);
+  void HciSwitchRole(PacketView<true> args);
 
   // 7.1.21
-  void HciReadRemoteSupportedFeatures(bluetooth::packet::PacketView<true> args);
+  void HciReadRemoteSupportedFeatures(PacketView<true> args);
 
   // 7.1.22
-  void HciReadRemoteExtendedFeatures(bluetooth::packet::PacketView<true> args);
+  void HciReadRemoteExtendedFeatures(PacketView<true> args);
 
   // 7.1.23
-  void HciReadRemoteVersionInformation(
-      bluetooth::packet::PacketView<true> args);
+  void HciReadRemoteVersionInformation(PacketView<true> args);
 
   // 7.1.24
-  void HciReadClockOffset(bluetooth::packet::PacketView<true> args);
+  void HciReadClockOffset(PacketView<true> args);
 
   // 7.1.29
-  void HciIoCapabilityRequestReply(bluetooth::packet::PacketView<true> args);
+  void HciIoCapabilityRequestReply(PacketView<true> args);
 
   // 7.1.30
-  void HciUserConfirmationRequestReply(
-      bluetooth::packet::PacketView<true> args);
+  void HciUserConfirmationRequestReply(PacketView<true> args);
 
   // 7.1.31
-  void HciUserConfirmationRequestNegativeReply(
-      bluetooth::packet::PacketView<true> args);
+  void HciUserConfirmationRequestNegativeReply(PacketView<true> args);
 
   // 7.1.32
-  void HciUserPasskeyRequestReply(bluetooth::packet::PacketView<true> args);
+  void HciUserPasskeyRequestReply(PacketView<true> args);
 
   // 7.1.33
-  void HciUserPasskeyRequestNegativeReply(
-      bluetooth::packet::PacketView<true> args);
+  void HciUserPasskeyRequestNegativeReply(PacketView<true> args);
 
   // 7.1.34
-  void HciRemoteOobDataRequestReply(bluetooth::packet::PacketView<true> args);
+  void HciRemoteOobDataRequestReply(PacketView<true> args);
 
   // 7.1.35
-  void HciRemoteOobDataRequestNegativeReply(
-      bluetooth::packet::PacketView<true> args);
+  void HciRemoteOobDataRequestNegativeReply(PacketView<true> args);
 
   // 7.1.36
-  void HciIoCapabilityRequestNegativeReply(
-      bluetooth::packet::PacketView<true> args);
+  void HciIoCapabilityRequestNegativeReply(PacketView<true> args);
 
   // Link Policy Commands
   // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.2
 
   // 7.2.1
-  void HciHoldMode(bluetooth::packet::PacketView<true> args);
+  void HciHoldMode(PacketView<true> args);
 
   // 7.2.2
-  void HciSniffMode(bluetooth::packet::PacketView<true> args);
+  void HciSniffMode(PacketView<true> args);
 
   // 7.2.3
-  void HciExitSniffMode(bluetooth::packet::PacketView<true> args);
+  void HciExitSniffMode(PacketView<true> args);
 
   // 7.2.6
-  void HciQosSetup(bluetooth::packet::PacketView<true> args);
+  void HciQosSetup(PacketView<true> args);
 
   // 7.2.10
-  void HciWriteLinkPolicySettings(bluetooth::packet::PacketView<true> args);
+  void HciWriteLinkPolicySettings(PacketView<true> args);
 
   // 7.2.12
-  void HciWriteDefaultLinkPolicySettings(
-      bluetooth::packet::PacketView<true> args);
+  void HciWriteDefaultLinkPolicySettings(PacketView<true> args);
 
   // 7.2.13
-  void HciFlowSpecification(bluetooth::packet::PacketView<true> args);
+  void HciFlowSpecification(PacketView<true> args);
 
   // 7.2.14
-  void HciSniffSubrating(bluetooth::packet::PacketView<true> args);
+  void HciSniffSubrating(PacketView<true> args);
 
   // Link Controller Commands
   // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3
 
   // 7.3.1
-  void HciSetEventMask(bluetooth::packet::PacketView<true> args);
+  void HciSetEventMask(PacketView<true> args);
 
   // 7.3.2
-  void HciReset(bluetooth::packet::PacketView<true> args);
+  void HciReset(PacketView<true> args);
 
   // 7.3.3
-  void HciSetEventFilter(bluetooth::packet::PacketView<true> args);
+  void HciSetEventFilter(PacketView<true> args);
 
   // 7.3.10
-  void HciDeleteStoredLinkKey(bluetooth::packet::PacketView<true> args);
+  void HciDeleteStoredLinkKey(PacketView<true> args);
 
   // 7.3.11
-  void HciWriteLocalName(bluetooth::packet::PacketView<true> args);
+  void HciWriteLocalName(PacketView<true> args);
 
   // 7.3.12
-  void HciReadLocalName(bluetooth::packet::PacketView<true> args);
+  void HciReadLocalName(PacketView<true> args);
 
   // 7.3.16
-  void HciWritePageTimeout(bluetooth::packet::PacketView<true> args);
+  void HciWritePageTimeout(PacketView<true> args);
 
   // 7.3.18
-  void HciWriteScanEnable(bluetooth::packet::PacketView<true> args);
+  void HciWriteScanEnable(PacketView<true> args);
 
   // 7.3.22
-  void HciWriteInquiryScanActivity(bluetooth::packet::PacketView<true> args);
+  void HciWriteInquiryScanActivity(PacketView<true> args);
 
   // 7.3.23
-  void HciReadAuthenticationEnable(bluetooth::packet::PacketView<true> args);
+  void HciReadAuthenticationEnable(PacketView<true> args);
 
   // 7.3.24
-  void HciWriteAuthenticationEnable(bluetooth::packet::PacketView<true> args);
+  void HciWriteAuthenticationEnable(PacketView<true> args);
 
   // 7.3.26
-  void HciWriteClassOfDevice(bluetooth::packet::PacketView<true> args);
+  void HciWriteClassOfDevice(PacketView<true> args);
 
   // 7.3.28
-  void HciWriteVoiceSetting(bluetooth::packet::PacketView<true> args);
+  void HciWriteVoiceSetting(PacketView<true> args);
 
   // 7.3.39
-  void HciHostBufferSize(bluetooth::packet::PacketView<true> args);
+  void HciHostBufferSize(PacketView<true> args);
 
   // 7.3.42
-  void HciWriteLinkSupervisionTimeout(bluetooth::packet::PacketView<true> args);
+  void HciWriteLinkSupervisionTimeout(PacketView<true> args);
 
   // 7.3.45
-  void HciWriteCurrentIacLap(bluetooth::packet::PacketView<true> args);
+  void HciWriteCurrentIacLap(PacketView<true> args);
 
   // 7.3.48
-  void HciWriteInquiryScanType(bluetooth::packet::PacketView<true> args);
+  void HciWriteInquiryScanType(PacketView<true> args);
 
   // 7.3.50
-  void HciWriteInquiryMode(bluetooth::packet::PacketView<true> args);
+  void HciWriteInquiryMode(PacketView<true> args);
 
   // 7.3.52
-  void HciWritePageScanType(bluetooth::packet::PacketView<true> args);
+  void HciWritePageScanType(PacketView<true> args);
 
   // 7.3.56
-  void HciWriteExtendedInquiryResponse(
-      bluetooth::packet::PacketView<true> args);
+  void HciWriteExtendedInquiryResponse(PacketView<true> args);
 
   // 7.3.57
-  void HciRefreshEncryptionKey(bluetooth::packet::PacketView<true> args);
+  void HciRefreshEncryptionKey(PacketView<true> args);
 
   // 7.3.59
-  void HciWriteSimplePairingMode(bluetooth::packet::PacketView<true> args);
+  void HciWriteSimplePairingMode(PacketView<true> args);
 
   // 7.3.79
-  void HciWriteLeHostSupport(bluetooth::packet::PacketView<true> args);
+  void HciWriteLeHostSupport(PacketView<true> args);
 
   // 7.3.92
-  void HciWriteSecureConnectionsHostSupport(
-      bluetooth::packet::PacketView<true> args);
+  void HciWriteSecureConnectionsHostSupport(PacketView<true> args);
 
   // Informational Parameters Commands
   // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.4
 
   // 7.4.5
-  void HciReadBufferSize(bluetooth::packet::PacketView<true> args);
+  void HciReadBufferSize(PacketView<true> args);
 
   // 7.4.1
-  void HciReadLocalVersionInformation(bluetooth::packet::PacketView<true> args);
+  void HciReadLocalVersionInformation(PacketView<true> args);
 
   // 7.4.6
-  void HciReadBdAddr(bluetooth::packet::PacketView<true> args);
+  void HciReadBdAddr(PacketView<true> args);
 
   // 7.4.2
-  void HciReadLocalSupportedCommands(bluetooth::packet::PacketView<true> args);
+  void HciReadLocalSupportedCommands(PacketView<true> args);
 
   // 7.4.3
-  void HciReadLocalSupportedFeatures(bluetooth::packet::PacketView<true> args);
+  void HciReadLocalSupportedFeatures(PacketView<true> args);
 
   // 7.4.4
-  void HciReadLocalExtendedFeatures(bluetooth::packet::PacketView<true> args);
+  void HciReadLocalExtendedFeatures(PacketView<true> args);
 
   // 7.4.8
-  void HciReadLocalSupportedCodecs(bluetooth::packet::PacketView<true> args);
+  void HciReadLocalSupportedCodecs(PacketView<true> args);
 
   // Status Parameters Commands
   // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.5
 
   // 7.5.7
-  void HciReadEncryptionKeySize(bluetooth::packet::PacketView<true> args);
+  void HciReadEncryptionKeySize(PacketView<true> args);
 
   // Test Commands
   // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.7
 
   // 7.7.1
-  void HciReadLoopbackMode(bluetooth::packet::PacketView<true> args);
+  void HciReadLoopbackMode(PacketView<true> args);
 
   // 7.7.2
-  void HciWriteLoopbackMode(bluetooth::packet::PacketView<true> args);
+  void HciWriteLoopbackMode(PacketView<true> args);
 
   // LE Controller Commands
   // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.8
 
   // 7.8.1
-  void HciLeSetEventMask(bluetooth::packet::PacketView<true> args);
+  void HciLeSetEventMask(PacketView<true> args);
 
   // 7.8.2
-  void HciLeReadBufferSize(bluetooth::packet::PacketView<true> args);
+  void HciLeReadBufferSize(PacketView<true> args);
 
   // 7.8.3
-  void HciLeReadLocalSupportedFeatures(
-      bluetooth::packet::PacketView<true> args);
+  void HciLeReadLocalSupportedFeatures(PacketView<true> args);
 
   // 7.8.4
-  void HciLeSetRandomAddress(bluetooth::packet::PacketView<true> args);
+  void HciLeSetRandomAddress(PacketView<true> args);
 
   // 7.8.5
-  void HciLeSetAdvertisingParameters(bluetooth::packet::PacketView<true> args);
+  void HciLeSetAdvertisingParameters(PacketView<true> args);
 
   // 7.8.7
-  void HciLeSetAdvertisingData(bluetooth::packet::PacketView<true> args);
+  void HciLeSetAdvertisingData(PacketView<true> args);
 
   // 7.8.8
-  void HciLeSetScanResponseData(bluetooth::packet::PacketView<true> args);
+  void HciLeSetScanResponseData(PacketView<true> args);
 
   // 7.8.9
-  void HciLeSetAdvertisingEnable(bluetooth::packet::PacketView<true> args);
+  void HciLeSetAdvertisingEnable(PacketView<true> args);
 
   // 7.8.10
-  void HciLeSetScanParameters(bluetooth::packet::PacketView<true> args);
+  void HciLeSetScanParameters(PacketView<true> args);
 
   // 7.8.11
-  void HciLeSetScanEnable(bluetooth::packet::PacketView<true> args);
+  void HciLeSetScanEnable(PacketView<true> args);
 
   // 7.8.12
-  void HciLeCreateConnection(bluetooth::packet::PacketView<true> args);
+  void HciLeCreateConnection(PacketView<true> args);
 
   // 7.8.18
-  void HciLeConnectionUpdate(bluetooth::packet::PacketView<true> args);
+  void HciLeConnectionUpdate(PacketView<true> args);
 
   // 7.8.13
-  void HciLeConnectionCancel(bluetooth::packet::PacketView<true> args);
+  void HciLeConnectionCancel(PacketView<true> args);
 
   // 7.8.14
-  void HciLeReadWhiteListSize(bluetooth::packet::PacketView<true> args);
+  void HciLeReadWhiteListSize(PacketView<true> args);
 
   // 7.8.15
-  void HciLeClearWhiteList(bluetooth::packet::PacketView<true> args);
+  void HciLeClearWhiteList(PacketView<true> args);
 
   // 7.8.16
-  void HciLeAddDeviceToWhiteList(bluetooth::packet::PacketView<true> args);
+  void HciLeAddDeviceToWhiteList(PacketView<true> args);
 
   // 7.8.17
-  void HciLeRemoveDeviceFromWhiteList(bluetooth::packet::PacketView<true> args);
+  void HciLeRemoveDeviceFromWhiteList(PacketView<true> args);
 
   // 7.8.21
-  void HciLeReadRemoteFeatures(bluetooth::packet::PacketView<true> args);
+  void HciLeReadRemoteFeatures(PacketView<true> args);
 
   // 7.8.23
-  void HciLeRand(bluetooth::packet::PacketView<true> args);
+  void HciLeRand(PacketView<true> args);
 
   // 7.8.24
-  void HciLeStartEncryption(bluetooth::packet::PacketView<true> args);
+  void HciLeStartEncryption(PacketView<true> args);
 
   // 7.8.27
-  void HciLeReadSupportedStates(bluetooth::packet::PacketView<true> args);
+  void HciLeReadSupportedStates(PacketView<true> args);
 
   // 7.8.38
-  void HciLeAddDeviceToResolvingList(bluetooth::packet::PacketView<true> args);
+  void HciLeAddDeviceToResolvingList(PacketView<true> args);
 
   // 7.8.39
-  void HciLeRemoveDeviceFromResolvingList(
-      bluetooth::packet::PacketView<true> args);
+  void HciLeRemoveDeviceFromResolvingList(PacketView<true> args);
 
   // 7.8.40
-  void HciLeClearResolvingList(bluetooth::packet::PacketView<true> args);
+  void HciLeClearResolvingList(PacketView<true> args);
 
   // 7.8.77
-  void HciLeSetPrivacyMode(bluetooth::packet::PacketView<true> args);
+  void HciLeSetPrivacyMode(PacketView<true> args);
 
   // Vendor-specific Commands
 
-  void HciLeVendorSleepMode(bluetooth::packet::PacketView<true> args);
-  void HciLeVendorCap(bluetooth::packet::PacketView<true> args);
-  void HciLeVendorMultiAdv(bluetooth::packet::PacketView<true> args);
-  void HciLeVendor155(bluetooth::packet::PacketView<true> args);
-  void HciLeVendor157(bluetooth::packet::PacketView<true> args);
-  void HciLeEnergyInfo(bluetooth::packet::PacketView<true> args);
-  void HciLeAdvertisingFilter(bluetooth::packet::PacketView<true> args);
-  void HciLeExtendedScanParams(bluetooth::packet::PacketView<true> args);
+  void HciLeVendorSleepMode(PacketView<true> args);
+  void HciLeVendorCap(PacketView<true> args);
+  void HciLeVendorMultiAdv(PacketView<true> args);
+  void HciLeVendor155(PacketView<true> args);
+  void HciLeVendor157(PacketView<true> args);
+  void HciLeEnergyInfo(PacketView<true> args);
+  void HciLeAdvertisingFilter(PacketView<true> args);
+  void HciLeExtendedScanParams(PacketView<true> args);
 
   void SetTimerPeriod(std::chrono::milliseconds new_period);
   void StartTimer();
@@ -453,8 +443,7 @@
   // Maintains the commands to be registered and used in the HciHandler object.
   // Keys are command opcodes and values are the callbacks to handle each
   // command.
-  std::unordered_map<uint16_t,
-                     std::function<void(bluetooth::packet::PacketView<true>)>>
+  std::unordered_map<uint16_t, std::function<void(PacketView<true>)>>
       active_hci_commands_;
 
   bluetooth::hci::LoopbackMode loopback_mode_;
diff --git a/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.cc b/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.cc
index d5f3ba7..8f0975d 100644
--- a/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.cc
+++ b/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.cc
@@ -55,65 +55,64 @@
   });
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::SendCommandToRemoteByAddress(
-    bluetooth::hci::OpCode opcode, bluetooth::packet::PacketView<true> args,
+ErrorCode LinkLayerController::SendCommandToRemoteByAddress(
+    OpCode opcode, bluetooth::packet::PacketView<true> args,
     const Address& remote) {
   Address local_address = properties_.GetAddress();
 
   switch (opcode) {
-    case (bluetooth::hci::OpCode::REMOTE_NAME_REQUEST):
+    case (OpCode::REMOTE_NAME_REQUEST):
       // LMP features get requested with remote name requests.
       SendLinkLayerPacket(model::packets::ReadRemoteLmpFeaturesBuilder::Create(
           local_address, remote));
       SendLinkLayerPacket(model::packets::RemoteNameRequestBuilder::Create(
           local_address, remote));
       break;
-    case (bluetooth::hci::OpCode::READ_REMOTE_SUPPORTED_FEATURES):
+    case (OpCode::READ_REMOTE_SUPPORTED_FEATURES):
       SendLinkLayerPacket(
           model::packets::ReadRemoteSupportedFeaturesBuilder::Create(
               local_address, remote));
       break;
-    case (bluetooth::hci::OpCode::READ_REMOTE_EXTENDED_FEATURES): {
+    case (OpCode::READ_REMOTE_EXTENDED_FEATURES): {
       uint8_t page_number =
           (args.begin() + 2).extract<uint8_t>();  // skip the handle
       SendLinkLayerPacket(
           model::packets::ReadRemoteExtendedFeaturesBuilder::Create(
               local_address, remote, page_number));
     } break;
-    case (bluetooth::hci::OpCode::READ_REMOTE_VERSION_INFORMATION):
+    case (OpCode::READ_REMOTE_VERSION_INFORMATION):
       SendLinkLayerPacket(
           model::packets::ReadRemoteVersionInformationBuilder::Create(
               local_address, remote));
       break;
-    case (bluetooth::hci::OpCode::READ_CLOCK_OFFSET):
+    case (OpCode::READ_CLOCK_OFFSET):
       SendLinkLayerPacket(model::packets::ReadClockOffsetBuilder::Create(
           local_address, remote));
       break;
     default:
       LOG_INFO("Dropping unhandled command 0x%04x",
                static_cast<uint16_t>(opcode));
-      return bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND;
+      return ErrorCode::UNKNOWN_HCI_COMMAND;
   }
 
-  return bluetooth::hci::ErrorCode::SUCCESS;
+  return ErrorCode::SUCCESS;
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::SendCommandToRemoteByHandle(
-    bluetooth::hci::OpCode opcode, bluetooth::packet::PacketView<true> args,
-    uint16_t handle) {
+ErrorCode LinkLayerController::SendCommandToRemoteByHandle(
+    OpCode opcode, bluetooth::packet::PacketView<true> args, uint16_t handle) {
   // TODO: Handle LE connections
   if (!connections_.HasHandle(handle)) {
-    return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
+    return ErrorCode::UNKNOWN_CONNECTION;
   }
   return SendCommandToRemoteByAddress(opcode, args,
                                       connections_.GetAddress(handle));
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::SendAclToRemote(
+ErrorCode LinkLayerController::SendAclToRemote(
     bluetooth::hci::AclPacketView acl_packet) {
   uint16_t handle = acl_packet.GetHandle();
   if (!connections_.HasHandle(handle)) {
-    return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
+    return ErrorCode::UNKNOWN_CONNECTION;
   }
 
   Address my_address = properties_.GetAddress();
@@ -154,7 +153,7 @@
       my_address, destination, std::move(raw_builder_ptr));
 
   SendLinkLayerPacket(std::move(acl));
-  return bluetooth::hci::ErrorCode::SUCCESS;
+  return ErrorCode::SUCCESS;
 }
 
 void LinkLayerController::IncomingPacket(
@@ -321,8 +320,7 @@
   ASSERT(view.IsValid());
 
   send_event_(bluetooth::hci::RemoteNameRequestCompleteBuilder::Create(
-      bluetooth::hci::ErrorCode::SUCCESS, packet.GetSourceAddress(),
-      view.GetName()));
+      ErrorCode::SUCCESS, packet.GetSourceAddress(), view.GetName()));
 }
 
 void LinkLayerController::IncomingReadRemoteLmpFeatures(
@@ -360,7 +358,7 @@
     uint16_t handle = connections_.GetHandle(source);
     send_event_(
         bluetooth::hci::ReadRemoteSupportedFeaturesCompleteBuilder::Create(
-            bluetooth::hci::ErrorCode::SUCCESS, handle, view.GetFeatures()));
+            ErrorCode::SUCCESS, handle, view.GetFeatures()));
   } else {
     LOG_INFO("Discarding response from a disconnected device %s",
              source.ToString().c_str());
@@ -372,10 +370,9 @@
   auto view = model::packets::ReadRemoteExtendedFeaturesView::Create(packet);
   ASSERT(view.IsValid());
   uint8_t page_number = view.GetPageNumber();
-  uint8_t error_code = static_cast<uint8_t>(bluetooth::hci::ErrorCode::SUCCESS);
+  uint8_t error_code = static_cast<uint8_t>(ErrorCode::SUCCESS);
   if (page_number > properties_.GetExtendedFeaturesMaximumPageNumber()) {
-    error_code = static_cast<uint8_t>(
-        bluetooth::hci::ErrorCode::INVALID_LMP_OR_LL_PARAMETERS);
+    error_code = static_cast<uint8_t>(ErrorCode::INVALID_LMP_OR_LL_PARAMETERS);
   }
   SendLinkLayerPacket(
       model::packets::ReadRemoteExtendedFeaturesResponseBuilder::Create(
@@ -394,7 +391,7 @@
     uint16_t handle = connections_.GetHandle(packet.GetSourceAddress());
     send_event_(
         bluetooth::hci::ReadRemoteExtendedFeaturesCompleteBuilder::Create(
-            static_cast<bluetooth::hci::ErrorCode>(view.GetStatus()), handle,
+            static_cast<ErrorCode>(view.GetStatus()), handle,
             view.GetPageNumber(), view.GetMaxPageNumber(), view.GetFeatures()));
   } else {
     LOG_INFO("Discarding response from a disconnected device %s",
@@ -420,7 +417,7 @@
     uint16_t handle = connections_.GetHandle(packet.GetSourceAddress());
     send_event_(
         bluetooth::hci::ReadRemoteVersionInformationCompleteBuilder::Create(
-            bluetooth::hci::ErrorCode::SUCCESS, handle, view.GetLmpVersion(),
+            ErrorCode::SUCCESS, handle, view.GetLmpVersion(),
             view.GetManufacturerName(), view.GetLmpSubversion()));
   } else {
     LOG_INFO("Discarding response from a disconnected device %s",
@@ -443,7 +440,7 @@
   if (connections_.IsDeviceConnected(source)) {
     uint16_t handle = connections_.GetHandle(packet.GetSourceAddress());
     send_event_(bluetooth::hci::ReadClockOffsetCompleteBuilder::Create(
-        bluetooth::hci::ErrorCode::SUCCESS, handle, view.GetOffset()));
+        ErrorCode::SUCCESS, handle, view.GetOffset()));
   } else {
     LOG_INFO("Discarding response from a disconnected device %s",
              source.ToString().c_str());
@@ -480,8 +477,7 @@
     return;
   }
   send_event_(bluetooth::hci::EncryptionChangeBuilder::Create(
-      bluetooth::hci::ErrorCode::SUCCESS, handle,
-      bluetooth::hci::EncryptionEnabled::ON));
+      ErrorCode::SUCCESS, handle, bluetooth::hci::EncryptionEnabled::ON));
 
   uint16_t count = security_manager_.ReadKey(peer);
   if (count == 0) {
@@ -505,8 +501,7 @@
     return;
   }
   auto packet = bluetooth::hci::EncryptionChangeBuilder::Create(
-      bluetooth::hci::ErrorCode::SUCCESS, handle,
-      bluetooth::hci::EncryptionEnabled::ON);
+      ErrorCode::SUCCESS, handle, bluetooth::hci::EncryptionEnabled::ON);
   send_event_(std::move(packet));
 }
 
@@ -776,8 +771,7 @@
     return;
   }
   auto packet = bluetooth::hci::LeConnectionCompleteBuilder::Create(
-      bluetooth::hci::ErrorCode::SUCCESS, handle,
-      static_cast<bluetooth::hci::Role>(role),
+      ErrorCode::SUCCESS, handle, static_cast<bluetooth::hci::Role>(role),
       static_cast<bluetooth::hci::AddressType>(address_type), address,
       connection_interval, connection_latency, supervision_timeout,
       static_cast<bluetooth::hci::MasterClockAccuracy>(0x00));
@@ -895,7 +889,7 @@
   ASSERT(reject.IsValid());
   LOG_INFO("%s: Sending CreateConnectionComplete", __func__);
   auto packet = bluetooth::hci::ConnectionCompleteBuilder::Create(
-      static_cast<bluetooth::hci::ErrorCode>(reject.GetReason()), 0x0eff,
+      static_cast<ErrorCode>(reject.GetReason()), 0x0eff,
       incoming.GetSourceAddress(), bluetooth::hci::LinkType::ACL,
       bluetooth::hci::Enable::DISABLED);
   send_event_(std::move(packet));
@@ -912,7 +906,7 @@
     return;
   }
   auto packet = bluetooth::hci::ConnectionCompleteBuilder::Create(
-      bluetooth::hci::ErrorCode::SUCCESS, handle, incoming.GetSourceAddress(),
+      ErrorCode::SUCCESS, handle, incoming.GetSourceAddress(),
       bluetooth::hci::LinkType::ACL, bluetooth::hci::Enable::DISABLED);
   send_event_(std::move(packet));
 
@@ -1072,37 +1066,37 @@
   ASSERT(security_manager_.GetAuthenticationAddress() == peer);
   // Check key in security_manager_ ?
   auto packet = bluetooth::hci::AuthenticationCompleteBuilder::Create(
-      bluetooth::hci::ErrorCode::SUCCESS, handle);
+      ErrorCode::SUCCESS, handle);
   send_event_(std::move(packet));
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::LinkKeyRequestReply(
+ErrorCode LinkLayerController::LinkKeyRequestReply(
     const Address& peer, const std::array<uint8_t, 16>& key) {
   security_manager_.WriteKey(peer, key);
   security_manager_.AuthenticationRequestFinished();
 
   ScheduleTask(milliseconds(5), [this, peer]() { AuthenticateRemoteStage2(peer); });
 
-  return bluetooth::hci::ErrorCode::SUCCESS;
+  return ErrorCode::SUCCESS;
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::LinkKeyRequestNegativeReply(
+ErrorCode LinkLayerController::LinkKeyRequestNegativeReply(
     const Address& address) {
   security_manager_.DeleteKey(address);
   // Simple pairing to get a key
   uint16_t handle = connections_.GetHandle(address);
   if (handle == acl::kReservedHandle) {
     LOG_INFO("%s: Device not connected %s", __func__, address.ToString().c_str());
-    return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
+    return ErrorCode::UNKNOWN_CONNECTION;
   }
 
   security_manager_.AuthenticationRequest(address, handle);
 
   ScheduleTask(milliseconds(5), [this, address]() { StartSimplePairing(address); });
-  return bluetooth::hci::ErrorCode::SUCCESS;
+  return ErrorCode::SUCCESS;
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::IoCapabilityRequestReply(
+ErrorCode LinkLayerController::IoCapabilityRequestReply(
     const Address& peer, uint8_t io_capability, uint8_t oob_data_present_flag,
     uint8_t authentication_requirements) {
   security_manager_.SetLocalIoCapability(peer, io_capability, oob_data_present_flag, authentication_requirements);
@@ -1124,13 +1118,13 @@
         authentication_requirements));
   }
 
-  return bluetooth::hci::ErrorCode::SUCCESS;
+  return ErrorCode::SUCCESS;
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::IoCapabilityRequestNegativeReply(
-    const Address& peer, bluetooth::hci::ErrorCode reason) {
+ErrorCode LinkLayerController::IoCapabilityRequestNegativeReply(
+    const Address& peer, ErrorCode reason) {
   if (security_manager_.GetAuthenticationAddress() != peer) {
-    return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
+    return ErrorCode::AUTHENTICATION_FAILURE;
   }
 
   security_manager_.InvalidateIoCapabilities();
@@ -1139,13 +1133,13 @@
       properties_.GetAddress(), peer, static_cast<uint8_t>(reason));
   SendLinkLayerPacket(std::move(packet));
 
-  return bluetooth::hci::ErrorCode::SUCCESS;
+  return ErrorCode::SUCCESS;
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::UserConfirmationRequestReply(
+ErrorCode LinkLayerController::UserConfirmationRequestReply(
     const Address& peer) {
   if (security_manager_.GetAuthenticationAddress() != peer) {
-    return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
+    return ErrorCode::AUTHENTICATION_FAILURE;
   }
   // TODO: Key could be calculated here.
   std::array<uint8_t, 16> key_vec{1, 2,  3,  4,  5,  6,  7,  8,
@@ -1161,50 +1155,50 @@
 
   ScheduleTask(milliseconds(15),
                [this, peer]() { AuthenticateRemoteStage2(peer); });
-  return bluetooth::hci::ErrorCode::SUCCESS;
+  return ErrorCode::SUCCESS;
 }
 
-bluetooth::hci::ErrorCode
-LinkLayerController::UserConfirmationRequestNegativeReply(const Address& peer) {
-  if (security_manager_.GetAuthenticationAddress() != peer) {
-    return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
-  }
-  return bluetooth::hci::ErrorCode::SUCCESS;
-}
-
-bluetooth::hci::ErrorCode LinkLayerController::UserPasskeyRequestReply(
-    const Address& peer, uint32_t numeric_value) {
-  if (security_manager_.GetAuthenticationAddress() != peer) {
-    return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
-  }
-  LOG_INFO("TODO:Do something with the passkey %06d", numeric_value);
-  return bluetooth::hci::ErrorCode::SUCCESS;
-}
-
-bluetooth::hci::ErrorCode LinkLayerController::UserPasskeyRequestNegativeReply(
+ErrorCode LinkLayerController::UserConfirmationRequestNegativeReply(
     const Address& peer) {
   if (security_manager_.GetAuthenticationAddress() != peer) {
-    return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
+    return ErrorCode::AUTHENTICATION_FAILURE;
   }
-  return bluetooth::hci::ErrorCode::SUCCESS;
+  return ErrorCode::SUCCESS;
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::RemoteOobDataRequestReply(
+ErrorCode LinkLayerController::UserPasskeyRequestReply(const Address& peer,
+                                                       uint32_t numeric_value) {
+  if (security_manager_.GetAuthenticationAddress() != peer) {
+    return ErrorCode::AUTHENTICATION_FAILURE;
+  }
+  LOG_INFO("TODO:Do something with the passkey %06d", numeric_value);
+  return ErrorCode::SUCCESS;
+}
+
+ErrorCode LinkLayerController::UserPasskeyRequestNegativeReply(
+    const Address& peer) {
+  if (security_manager_.GetAuthenticationAddress() != peer) {
+    return ErrorCode::AUTHENTICATION_FAILURE;
+  }
+  return ErrorCode::SUCCESS;
+}
+
+ErrorCode LinkLayerController::RemoteOobDataRequestReply(
     const Address& peer, const std::vector<uint8_t>& c,
     const std::vector<uint8_t>& r) {
   if (security_manager_.GetAuthenticationAddress() != peer) {
-    return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
+    return ErrorCode::AUTHENTICATION_FAILURE;
   }
   LOG_INFO("TODO:Do something with the OOB data c=%d r=%d", c[0], r[0]);
-  return bluetooth::hci::ErrorCode::SUCCESS;
+  return ErrorCode::SUCCESS;
 }
 
-bluetooth::hci::ErrorCode
-LinkLayerController::RemoteOobDataRequestNegativeReply(const Address& peer) {
+ErrorCode LinkLayerController::RemoteOobDataRequestNegativeReply(
+    const Address& peer) {
   if (security_manager_.GetAuthenticationAddress() != peer) {
-    return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
+    return ErrorCode::AUTHENTICATION_FAILURE;
   }
-  return bluetooth::hci::ErrorCode::SUCCESS;
+  return ErrorCode::SUCCESS;
 }
 
 void LinkLayerController::HandleAuthenticationRequest(const Address& address, uint16_t handle) {
@@ -1215,23 +1209,22 @@
   } else {  // Should never happen for our phones
     // Check for a key, try to authenticate, ask for a PIN.
     auto packet = bluetooth::hci::AuthenticationCompleteBuilder::Create(
-        bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE, handle);
+        ErrorCode::AUTHENTICATION_FAILURE, handle);
     send_event_(std::move(packet));
   }
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::AuthenticationRequested(
-    uint16_t handle) {
+ErrorCode LinkLayerController::AuthenticationRequested(uint16_t handle) {
   if (!connections_.HasHandle(handle)) {
     LOG_INFO("Authentication Requested for unknown handle %04x", handle);
-    return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
+    return ErrorCode::UNKNOWN_CONNECTION;
   }
 
   Address remote = connections_.GetAddress(handle);
 
   ScheduleTask(milliseconds(5), [this, remote, handle]() { HandleAuthenticationRequest(remote, handle); });
 
-  return bluetooth::hci::ErrorCode::SUCCESS;
+  return ErrorCode::SUCCESS;
 }
 
 void LinkLayerController::HandleSetConnectionEncryption(const Address& peer, uint16_t handle,
@@ -1240,7 +1233,7 @@
 
   if (connections_.IsEncrypted(handle) && encryption_enable) {
     auto packet = bluetooth::hci::EncryptionChangeBuilder::Create(
-        bluetooth::hci::ErrorCode::SUCCESS, handle,
+        ErrorCode::SUCCESS, handle,
         static_cast<bluetooth::hci::EncryptionEnabled>(encryption_enable));
     send_event_(std::move(packet));
     return;
@@ -1258,33 +1251,33 @@
   SendLinkLayerPacket(std::move(packet));
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::SetConnectionEncryption(
+ErrorCode LinkLayerController::SetConnectionEncryption(
     uint16_t handle, uint8_t encryption_enable) {
   if (!connections_.HasHandle(handle)) {
     LOG_INFO("Set Connection Encryption for unknown handle %04x", handle);
-    return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
+    return ErrorCode::UNKNOWN_CONNECTION;
   }
 
   if (connections_.IsEncrypted(handle) && !encryption_enable) {
-    return bluetooth::hci::ErrorCode::ENCRYPTION_MODE_NOT_ACCEPTABLE;
+    return ErrorCode::ENCRYPTION_MODE_NOT_ACCEPTABLE;
   }
   Address remote = connections_.GetAddress(handle);
 
   if (security_manager_.ReadKey(remote) == 0) {
-    return bluetooth::hci::ErrorCode::PIN_OR_KEY_MISSING;
+    return ErrorCode::PIN_OR_KEY_MISSING;
   }
 
   ScheduleTask(milliseconds(5), [this, remote, handle, encryption_enable]() {
     HandleSetConnectionEncryption(remote, handle, encryption_enable);
   });
-  return bluetooth::hci::ErrorCode::SUCCESS;
+  return ErrorCode::SUCCESS;
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::AcceptConnectionRequest(
-    const Address& addr, bool try_role_switch) {
+ErrorCode LinkLayerController::AcceptConnectionRequest(const Address& addr,
+                                                       bool try_role_switch) {
   if (!connections_.HasPendingConnection(addr)) {
     LOG_INFO("%s: No pending connection for %s", __func__, addr.ToString().c_str());
-    return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
+    return ErrorCode::UNKNOWN_CONNECTION;
   }
 
   LOG_INFO("%s: Accept in 200ms", __func__);
@@ -1293,7 +1286,7 @@
     MakeSlaveConnection(addr, try_role_switch);
   });
 
-  return bluetooth::hci::ErrorCode::SUCCESS;
+  return ErrorCode::SUCCESS;
 }
 
 void LinkLayerController::MakeSlaveConnection(const Address& addr, bool try_role_switch) {
@@ -1309,22 +1302,22 @@
   }
   LOG_INFO("%s CreateConnection returned handle 0x%x", __func__, handle);
   auto packet = bluetooth::hci::ConnectionCompleteBuilder::Create(
-      bluetooth::hci::ErrorCode::SUCCESS, handle, addr,
-      bluetooth::hci::LinkType::ACL, bluetooth::hci::Enable::DISABLED);
+      ErrorCode::SUCCESS, handle, addr, bluetooth::hci::LinkType::ACL,
+      bluetooth::hci::Enable::DISABLED);
   send_event_(std::move(packet));
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::RejectConnectionRequest(
-    const Address& addr, uint8_t reason) {
+ErrorCode LinkLayerController::RejectConnectionRequest(const Address& addr,
+                                                       uint8_t reason) {
   if (!connections_.HasPendingConnection(addr)) {
     LOG_INFO("%s: No pending connection for %s", __func__, addr.ToString().c_str());
-    return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
+    return ErrorCode::UNKNOWN_CONNECTION;
   }
 
   ScheduleTask(milliseconds(200),
                [this, addr, reason]() { RejectSlaveConnection(addr, reason); });
 
-  return bluetooth::hci::ErrorCode::SUCCESS;
+  return ErrorCode::SUCCESS;
 }
 
 void LinkLayerController::RejectSlaveConnection(const Address& addr, uint8_t reason) {
@@ -1335,39 +1328,37 @@
   SendLinkLayerPacket(std::move(to_send));
 
   auto packet = bluetooth::hci::ConnectionCompleteBuilder::Create(
-      static_cast<bluetooth::hci::ErrorCode>(reason), 0xeff, addr,
+      static_cast<ErrorCode>(reason), 0xeff, addr,
       bluetooth::hci::LinkType::ACL, bluetooth::hci::Enable::DISABLED);
   send_event_(std::move(packet));
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::CreateConnection(
-    const Address& addr, uint16_t, uint8_t, uint16_t,
-    uint8_t allow_role_switch) {
+ErrorCode LinkLayerController::CreateConnection(const Address& addr, uint16_t,
+                                                uint8_t, uint16_t,
+                                                uint8_t allow_role_switch) {
   if (!connections_.CreatePendingConnection(
           addr, properties_.GetAuthenticationEnable() == 1)) {
-    return bluetooth::hci::ErrorCode::CONTROLLER_BUSY;
+    return ErrorCode::CONTROLLER_BUSY;
   }
   auto page = model::packets::PageBuilder::Create(
       properties_.GetAddress(), addr, properties_.GetClassOfDevice(),
       allow_role_switch);
   SendLinkLayerPacket(std::move(page));
 
-  return bluetooth::hci::ErrorCode::SUCCESS;
+  return ErrorCode::SUCCESS;
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::CreateConnectionCancel(
-    const Address& addr) {
+ErrorCode LinkLayerController::CreateConnectionCancel(const Address& addr) {
   if (!connections_.CancelPendingConnection(addr)) {
-    return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
+    return ErrorCode::UNKNOWN_CONNECTION;
   }
-  return bluetooth::hci::ErrorCode::SUCCESS;
+  return ErrorCode::SUCCESS;
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::Disconnect(uint16_t handle,
-                                                          uint8_t reason) {
+ErrorCode LinkLayerController::Disconnect(uint16_t handle, uint8_t reason) {
   // TODO: Handle LE
   if (!connections_.HasHandle(handle)) {
-    return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
+    return ErrorCode::UNKNOWN_CONNECTION;
   }
 
   const Address& remote = connections_.GetAddress(handle);
@@ -1379,145 +1370,144 @@
   ScheduleTask(milliseconds(20), [this, handle]() {
     DisconnectCleanup(
         handle,
-        static_cast<uint8_t>(
-            bluetooth::hci::ErrorCode::CONNECTION_TERMINATED_BY_LOCAL_HOST));
+        static_cast<uint8_t>(ErrorCode::CONNECTION_TERMINATED_BY_LOCAL_HOST));
   });
 
-  return bluetooth::hci::ErrorCode::SUCCESS;
+  return ErrorCode::SUCCESS;
 }
 
 void LinkLayerController::DisconnectCleanup(uint16_t handle, uint8_t reason) {
   // TODO: Clean up other connection state.
   auto packet = bluetooth::hci::DisconnectionCompleteBuilder::Create(
-      bluetooth::hci::ErrorCode::SUCCESS, handle,
-      static_cast<bluetooth::hci::ErrorCode>(reason));
+      ErrorCode::SUCCESS, handle, static_cast<ErrorCode>(reason));
   send_event_(std::move(packet));
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::ChangeConnectionPacketType(
-    uint16_t handle, uint16_t types) {
+ErrorCode LinkLayerController::ChangeConnectionPacketType(uint16_t handle,
+                                                          uint16_t types) {
   if (!connections_.HasHandle(handle)) {
-    return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
+    return ErrorCode::UNKNOWN_CONNECTION;
   }
   auto packet = bluetooth::hci::ConnectionPacketTypeChangedBuilder::Create(
-      bluetooth::hci::ErrorCode::SUCCESS, handle, types);
+      ErrorCode::SUCCESS, handle, types);
   std::shared_ptr<bluetooth::hci::ConnectionPacketTypeChangedBuilder>
       shared_packet = std::move(packet);
   ScheduleTask(milliseconds(20), [this, shared_packet]() {
     send_event_(std::move(shared_packet));
   });
 
-  return bluetooth::hci::ErrorCode::SUCCESS;
+  return ErrorCode::SUCCESS;
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::ChangeConnectionLinkKey(
-    uint16_t handle) {
+ErrorCode LinkLayerController::ChangeConnectionLinkKey(uint16_t handle) {
   if (!connections_.HasHandle(handle)) {
-    return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
+    return ErrorCode::UNKNOWN_CONNECTION;
   }
 
   // TODO: implement real logic
-  return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
+  return ErrorCode::COMMAND_DISALLOWED;
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::MasterLinkKey(
-    uint8_t /* key_flag */) {
+ErrorCode LinkLayerController::MasterLinkKey(uint8_t /* key_flag */) {
   // TODO: implement real logic
-  return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
+  return ErrorCode::COMMAND_DISALLOWED;
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::HoldMode(
-    uint16_t handle, uint16_t hold_mode_max_interval,
-    uint16_t hold_mode_min_interval) {
+ErrorCode LinkLayerController::HoldMode(uint16_t handle,
+                                        uint16_t hold_mode_max_interval,
+                                        uint16_t hold_mode_min_interval) {
   if (!connections_.HasHandle(handle)) {
-    return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
+    return ErrorCode::UNKNOWN_CONNECTION;
   }
 
   if (hold_mode_max_interval < hold_mode_min_interval) {
-    return bluetooth::hci::ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
+    return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
   }
 
   // TODO: implement real logic
-  return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
+  return ErrorCode::COMMAND_DISALLOWED;
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::SniffMode(
-    uint16_t handle, uint16_t sniff_max_interval, uint16_t sniff_min_interval,
-    uint16_t sniff_attempt, uint16_t sniff_timeout) {
+ErrorCode LinkLayerController::SniffMode(uint16_t handle,
+                                         uint16_t sniff_max_interval,
+                                         uint16_t sniff_min_interval,
+                                         uint16_t sniff_attempt,
+                                         uint16_t sniff_timeout) {
   if (!connections_.HasHandle(handle)) {
-    return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
+    return ErrorCode::UNKNOWN_CONNECTION;
   }
 
   if (sniff_max_interval < sniff_min_interval || sniff_attempt < 0x0001 || sniff_attempt > 0x7FFF ||
       sniff_timeout > 0x7FFF) {
-    return bluetooth::hci::ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
+    return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
   }
 
   // TODO: implement real logic
-  return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
+  return ErrorCode::COMMAND_DISALLOWED;
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::ExitSniffMode(uint16_t handle) {
+ErrorCode LinkLayerController::ExitSniffMode(uint16_t handle) {
   if (!connections_.HasHandle(handle)) {
-    return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
+    return ErrorCode::UNKNOWN_CONNECTION;
   }
 
   // TODO: implement real logic
-  return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
+  return ErrorCode::COMMAND_DISALLOWED;
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::QosSetup(
-    uint16_t handle, uint8_t service_type, uint32_t /* token_rate */,
-    uint32_t /* peak_bandwidth */, uint32_t /* latency */,
-    uint32_t /* delay_variation */) {
+ErrorCode LinkLayerController::QosSetup(uint16_t handle, uint8_t service_type,
+                                        uint32_t /* token_rate */,
+                                        uint32_t /* peak_bandwidth */,
+                                        uint32_t /* latency */,
+                                        uint32_t /* delay_variation */) {
   if (!connections_.HasHandle(handle)) {
-    return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
+    return ErrorCode::UNKNOWN_CONNECTION;
   }
 
   if (service_type > 0x02) {
-    return bluetooth::hci::ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
+    return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
   }
 
   // TODO: implement real logic
-  return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
+  return ErrorCode::COMMAND_DISALLOWED;
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::SwitchRole(Address /* bd_addr */,
-                                                          uint8_t /* role */) {
+ErrorCode LinkLayerController::SwitchRole(Address /* bd_addr */,
+                                          uint8_t /* role */) {
   // TODO: implement real logic
-  return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
+  return ErrorCode::COMMAND_DISALLOWED;
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::WriteLinkPolicySettings(
-    uint16_t handle, uint16_t) {
+ErrorCode LinkLayerController::WriteLinkPolicySettings(uint16_t handle,
+                                                       uint16_t) {
   if (!connections_.HasHandle(handle)) {
-    return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
+    return ErrorCode::UNKNOWN_CONNECTION;
   }
-  return bluetooth::hci::ErrorCode::SUCCESS;
+  return ErrorCode::SUCCESS;
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::FlowSpecification(
+ErrorCode LinkLayerController::FlowSpecification(
     uint16_t handle, uint8_t flow_direction, uint8_t service_type,
     uint32_t /* token_rate */, uint32_t /* token_bucket_size */,
     uint32_t /* peak_bandwidth */, uint32_t /* access_latency */) {
   if (!connections_.HasHandle(handle)) {
-    return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
+    return ErrorCode::UNKNOWN_CONNECTION;
   }
 
   if (flow_direction > 0x01 || service_type > 0x02) {
-    return bluetooth::hci::ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
+    return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
   }
 
   // TODO: implement real logic
-  return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
+  return ErrorCode::COMMAND_DISALLOWED;
 }
 
-bluetooth::hci::ErrorCode LinkLayerController::WriteLinkSupervisionTimeout(
-    uint16_t handle, uint16_t) {
+ErrorCode LinkLayerController::WriteLinkSupervisionTimeout(uint16_t handle,
+                                                           uint16_t) {
   if (!connections_.HasHandle(handle)) {
-    return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
+    return ErrorCode::UNKNOWN_CONNECTION;
   }
-  return bluetooth::hci::ErrorCode::SUCCESS;
+  return ErrorCode::SUCCESS;
 }
 
 void LinkLayerController::LeWhiteListClear() {
@@ -1635,8 +1625,8 @@
 void LinkLayerController::InquiryTimeout() {
   if (inquiry_state_ == Inquiry::InquiryState::INQUIRY) {
     inquiry_state_ = Inquiry::InquiryState::STANDBY;
-    auto packet = bluetooth::hci::InquiryCompleteBuilder::Create(
-        bluetooth::hci::ErrorCode::SUCCESS);
+    auto packet =
+        bluetooth::hci::InquiryCompleteBuilder::Create(ErrorCode::SUCCESS);
     send_event_(std::move(packet));
   }
 }
diff --git a/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.h b/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.h
index 487109f..b287123 100644
--- a/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.h
+++ b/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.h
@@ -30,66 +30,57 @@
 namespace test_vendor_lib {
 
 using ::bluetooth::hci::Address;
+using ::bluetooth::hci::ErrorCode;
+using ::bluetooth::hci::OpCode;
 
 class LinkLayerController {
  public:
   static constexpr size_t kIrk_size = 16;
 
   LinkLayerController(const DeviceProperties& properties) : properties_(properties) {}
-  bluetooth::hci::ErrorCode SendCommandToRemoteByAddress(
-      bluetooth::hci::OpCode opcode, bluetooth::packet::PacketView<true> args,
+  ErrorCode SendCommandToRemoteByAddress(
+      OpCode opcode, bluetooth::packet::PacketView<true> args,
       const Address& remote);
-  bluetooth::hci::ErrorCode SendCommandToRemoteByHandle(
-      bluetooth::hci::OpCode opcode, bluetooth::packet::PacketView<true> args,
-      uint16_t handle);
-  bluetooth::hci::ErrorCode SendScoToRemote(
-      bluetooth::hci::ScoPacketView sco_packet);
-  bluetooth::hci::ErrorCode SendAclToRemote(
-      bluetooth::hci::AclPacketView acl_packet);
+  ErrorCode SendCommandToRemoteByHandle(
+      OpCode opcode, bluetooth::packet::PacketView<true> args, uint16_t handle);
+  ErrorCode SendScoToRemote(bluetooth::hci::ScoPacketView sco_packet);
+  ErrorCode SendAclToRemote(bluetooth::hci::AclPacketView acl_packet);
 
   void WriteSimplePairingMode(bool enabled);
   void StartSimplePairing(const Address& address);
   void AuthenticateRemoteStage1(const Address& address, PairingType pairing_type);
   void AuthenticateRemoteStage2(const Address& address);
-  bluetooth::hci::ErrorCode LinkKeyRequestReply(
-      const Address& address, const std::array<uint8_t, 16>& key);
-  bluetooth::hci::ErrorCode LinkKeyRequestNegativeReply(const Address& address);
-  bluetooth::hci::ErrorCode IoCapabilityRequestReply(
-      const Address& peer, uint8_t io_capability, uint8_t oob_data_present_flag,
-      uint8_t authentication_requirements);
-  bluetooth::hci::ErrorCode IoCapabilityRequestNegativeReply(
-      const Address& peer, bluetooth::hci::ErrorCode reason);
-  bluetooth::hci::ErrorCode UserConfirmationRequestReply(const Address& peer);
-  bluetooth::hci::ErrorCode UserConfirmationRequestNegativeReply(
-      const Address& peer);
-  bluetooth::hci::ErrorCode UserPasskeyRequestReply(const Address& peer,
-                                                    uint32_t numeric_value);
-  bluetooth::hci::ErrorCode UserPasskeyRequestNegativeReply(
-      const Address& peer);
-  bluetooth::hci::ErrorCode RemoteOobDataRequestReply(
-      const Address& peer, const std::vector<uint8_t>& c,
-      const std::vector<uint8_t>& r);
-  bluetooth::hci::ErrorCode RemoteOobDataRequestNegativeReply(
-      const Address& peer);
+  ErrorCode LinkKeyRequestReply(const Address& address,
+                                const std::array<uint8_t, 16>& key);
+  ErrorCode LinkKeyRequestNegativeReply(const Address& address);
+  ErrorCode IoCapabilityRequestReply(const Address& peer, uint8_t io_capability,
+                                     uint8_t oob_data_present_flag,
+                                     uint8_t authentication_requirements);
+  ErrorCode IoCapabilityRequestNegativeReply(const Address& peer,
+                                             ErrorCode reason);
+  ErrorCode UserConfirmationRequestReply(const Address& peer);
+  ErrorCode UserConfirmationRequestNegativeReply(const Address& peer);
+  ErrorCode UserPasskeyRequestReply(const Address& peer,
+                                    uint32_t numeric_value);
+  ErrorCode UserPasskeyRequestNegativeReply(const Address& peer);
+  ErrorCode RemoteOobDataRequestReply(const Address& peer,
+                                      const std::vector<uint8_t>& c,
+                                      const std::vector<uint8_t>& r);
+  ErrorCode RemoteOobDataRequestNegativeReply(const Address& peer);
   void HandleSetConnectionEncryption(const Address& address, uint16_t handle, uint8_t encryption_enable);
-  bluetooth::hci::ErrorCode SetConnectionEncryption(uint16_t handle,
-                                                    uint8_t encryption_enable);
+  ErrorCode SetConnectionEncryption(uint16_t handle, uint8_t encryption_enable);
   void HandleAuthenticationRequest(const Address& address, uint16_t handle);
-  bluetooth::hci::ErrorCode AuthenticationRequested(uint16_t handle);
+  ErrorCode AuthenticationRequested(uint16_t handle);
 
-  bluetooth::hci::ErrorCode AcceptConnectionRequest(const Address& addr,
-                                                    bool try_role_switch);
+  ErrorCode AcceptConnectionRequest(const Address& addr, bool try_role_switch);
   void MakeSlaveConnection(const Address& addr, bool try_role_switch);
-  bluetooth::hci::ErrorCode RejectConnectionRequest(const Address& addr,
-                                                    uint8_t reason);
+  ErrorCode RejectConnectionRequest(const Address& addr, uint8_t reason);
   void RejectSlaveConnection(const Address& addr, uint8_t reason);
-  bluetooth::hci::ErrorCode CreateConnection(const Address& addr,
-                                             uint16_t packet_type,
-                                             uint8_t page_scan_mode,
-                                             uint16_t clock_offset,
-                                             uint8_t allow_role_switch);
-  bluetooth::hci::ErrorCode CreateConnectionCancel(const Address& addr);
-  bluetooth::hci::ErrorCode Disconnect(uint16_t handle, uint8_t reason);
+  ErrorCode CreateConnection(const Address& addr, uint16_t packet_type,
+                             uint8_t page_scan_mode, uint16_t clock_offset,
+                             uint8_t allow_role_switch);
+  ErrorCode CreateConnectionCancel(const Address& addr);
+  ErrorCode Disconnect(uint16_t handle, uint8_t reason);
 
  private:
   void DisconnectCleanup(uint16_t handle, uint8_t reason);
@@ -157,11 +148,10 @@
   bool LeResolvingListFull();
   void LeSetPrivacyMode(uint8_t address_type, Address addr, uint8_t mode);
 
-  bluetooth::hci::ErrorCode SetLeAdvertisingEnable(
-      uint8_t le_advertising_enable) {
+  ErrorCode SetLeAdvertisingEnable(uint8_t le_advertising_enable) {
     le_advertising_enable_ = le_advertising_enable;
     // TODO: Check properties and return errors
-    return bluetooth::hci::ErrorCode::SUCCESS;
+    return ErrorCode::SUCCESS;
   }
 
   void SetLeScanEnable(uint8_t le_scan_enable) {
@@ -185,9 +175,9 @@
   void SetLeAddressType(uint8_t le_address_type) {
     le_address_type_ = le_address_type;
   }
-  bluetooth::hci::ErrorCode SetLeConnect(bool le_connect) {
+  ErrorCode SetLeConnect(bool le_connect) {
     le_connect_ = le_connect;
-    return bluetooth::hci::ErrorCode::SUCCESS;
+    return ErrorCode::SUCCESS;
   }
   void SetLeConnectionIntervalMin(uint16_t min) {
     le_connection_interval_min_ = min;
@@ -229,32 +219,25 @@
   void SetInquiryScanEnable(bool enable);
   void SetPageScanEnable(bool enable);
 
-  bluetooth::hci::ErrorCode ChangeConnectionPacketType(uint16_t handle,
-                                                       uint16_t types);
-  bluetooth::hci::ErrorCode ChangeConnectionLinkKey(uint16_t handle);
-  bluetooth::hci::ErrorCode MasterLinkKey(uint8_t key_flag);
-  bluetooth::hci::ErrorCode HoldMode(uint16_t handle,
-                                     uint16_t hold_mode_max_interval,
-                                     uint16_t hold_mode_min_interval);
-  bluetooth::hci::ErrorCode SniffMode(uint16_t handle,
-                                      uint16_t sniff_max_interval,
-                                      uint16_t sniff_min_interval,
-                                      uint16_t sniff_attempt,
-                                      uint16_t sniff_timeout);
-  bluetooth::hci::ErrorCode ExitSniffMode(uint16_t handle);
-  bluetooth::hci::ErrorCode QosSetup(uint16_t handle, uint8_t service_type,
-                                     uint32_t token_rate,
-                                     uint32_t peak_bandwidth, uint32_t latency,
-                                     uint32_t delay_variation);
-  bluetooth::hci::ErrorCode SwitchRole(Address bd_addr, uint8_t role);
-  bluetooth::hci::ErrorCode WriteLinkPolicySettings(uint16_t handle,
-                                                    uint16_t settings);
-  bluetooth::hci::ErrorCode FlowSpecification(
-      uint16_t handle, uint8_t flow_direction, uint8_t service_type,
-      uint32_t token_rate, uint32_t token_bucket_size, uint32_t peak_bandwidth,
-      uint32_t access_latency);
-  bluetooth::hci::ErrorCode WriteLinkSupervisionTimeout(uint16_t handle,
-                                                        uint16_t timeout);
+  ErrorCode ChangeConnectionPacketType(uint16_t handle, uint16_t types);
+  ErrorCode ChangeConnectionLinkKey(uint16_t handle);
+  ErrorCode MasterLinkKey(uint8_t key_flag);
+  ErrorCode HoldMode(uint16_t handle, uint16_t hold_mode_max_interval,
+                     uint16_t hold_mode_min_interval);
+  ErrorCode SniffMode(uint16_t handle, uint16_t sniff_max_interval,
+                      uint16_t sniff_min_interval, uint16_t sniff_attempt,
+                      uint16_t sniff_timeout);
+  ErrorCode ExitSniffMode(uint16_t handle);
+  ErrorCode QosSetup(uint16_t handle, uint8_t service_type, uint32_t token_rate,
+                     uint32_t peak_bandwidth, uint32_t latency,
+                     uint32_t delay_variation);
+  ErrorCode SwitchRole(Address bd_addr, uint8_t role);
+  ErrorCode WriteLinkPolicySettings(uint16_t handle, uint16_t settings);
+  ErrorCode FlowSpecification(uint16_t handle, uint8_t flow_direction,
+                              uint8_t service_type, uint32_t token_rate,
+                              uint32_t token_bucket_size,
+                              uint32_t peak_bandwidth, uint32_t access_latency);
+  ErrorCode WriteLinkSupervisionTimeout(uint16_t handle, uint16_t timeout);
 
  protected:
   void SendLeLinkLayerPacket(