OSDN Git Service

Get rid of HciLayer shim
authorJakub Pawlowski <jpawlowski@google.com>
Thu, 20 Feb 2020 00:25:54 +0000 (01:25 +0100)
committerJakub Pawlowski <jpawlowski@google.com>
Thu, 20 Feb 2020 00:29:17 +0000 (01:29 +0100)
Bug: 149757450
Change-Id: Id1de12794f3378301442dfab01e3857a5d1c9459

gd/facade/grpc_root_server.cc
gd/shim/Android.bp
gd/shim/hci_layer.cc [deleted file]
gd/shim/hci_layer.h [deleted file]
gd/shim/only_include_this_file_into_legacy_stack___ever.h
gd/shim/stack.cc
gd/shim/stack.h
main/shim/entry.cc
main/shim/entry.h
main/shim/hci_layer.cc

index 5096921..6a8e5de 100644 (file)
@@ -28,6 +28,7 @@
 #include "hci/facade/le_acl_manager_facade.h"
 #include "hci/facade/le_advertising_manager_facade.h"
 #include "hci/facade/le_scanning_manager_facade.h"
+#include "hci/hci_layer.h"
 #include "hci/le_advertising_manager.h"
 #include "hci/le_scanning_manager.h"
 #include "l2cap/classic/facade.h"
@@ -42,7 +43,6 @@
 #include "security/facade.h"
 #include "security/security_module.h"
 #include "shim/dumpsys.h"
-#include "shim/hci_layer.h"
 #include "shim/l2cap.h"
 #include "stack_manager.h"
 #include "storage/legacy.h"
@@ -110,9 +110,9 @@ class RootFacadeService : public ::bluetooth::facade::RootFacade::Service {
         modules.add<::bluetooth::neighbor::InquiryModule>();
         modules.add<::bluetooth::neighbor::NameModule>();
         modules.add<::bluetooth::shim::Dumpsys>();
-        modules.add<::bluetooth::shim::HciLayer>();
         modules.add<::bluetooth::shim::L2cap>();
         modules.add<::bluetooth::neighbor::PageModule>();
+        modules.add<::bluetooth::hci::HciLayer>();
         modules.add<::bluetooth::hci::LeAdvertisingManager>();
         modules.add<::bluetooth::hci::LeScanningManager>();
         modules.add<::bluetooth::security::SecurityModule>();
index 31073d1..a38272b 100644 (file)
@@ -2,7 +2,6 @@ filegroup {
     name: "BluetoothShimSources",
     srcs: [
             "dumpsys.cc",
-            "hci_layer.cc",
             "l2cap.cc",
             "stack.cc",
     ]
diff --git a/gd/shim/hci_layer.cc b/gd/shim/hci_layer.cc
deleted file mode 100644 (file)
index ac12f48..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * 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.
- */
-#define LOG_TAG "bt_gd_shim"
-
-#include <cstdint>
-#include <memory>
-#include <queue>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include "hci/hci_layer.h"
-#include "hci/hci_packets.h"
-#include "module.h"
-#include "os/handler.h"
-#include "os/log.h"
-#include "packet/raw_builder.h"
-#include "shim/hci_layer.h"
-
-namespace bluetooth {
-namespace shim {
-
-namespace {
-constexpr char kModuleName[] = "shim::HciLayer";
-}  // namespace
-
-const ModuleFactory HciLayer::Factory = ModuleFactory([]() { return new HciLayer(); });
-
-struct HciLayer::impl {
-  impl(os::Handler* handler, hci::HciLayer* hci_layer) : handler_(handler), hci_layer_(hci_layer) {}
-
-  void OnTransmitPacketCommandComplete(const void* token, hci::CommandCompleteView view) {
-    if (command_complete_callback_ == nullptr) {
-      LOG_WARN("%s Received packet complete with no complete callback registered", __func__);
-      return;
-    }
-
-    uint16_t command_op_code = static_cast<uint16_t>(view.GetCommandOpCode());
-    std::vector<const uint8_t> data(view.begin(), view.end());
-
-    command_complete_callback_(command_op_code, data, token);
-  }
-
-  void OnTransmitPacketStatus(const void* token, hci::CommandStatusView view) {
-    if (command_status_callback_ == nullptr) {
-      LOG_WARN("%s Received packet complete with no status callback registered", __func__);
-      return;
-    }
-
-    uint16_t command_op_code = static_cast<uint16_t>(view.GetCommandOpCode());
-    std::vector<const uint8_t> data(view.begin(), view.end());
-
-    uint8_t status = static_cast<uint8_t>(view.GetStatus());
-    command_status_callback_(command_op_code, data, token, status);
-  }
-
-  void TransmitCommand(uint16_t command, const uint8_t* data, size_t len, const void* token) {
-    ASSERT(data != nullptr);
-    ASSERT(token != nullptr);
-
-    const hci::OpCode op_code = static_cast<const hci::OpCode>(command);
-
-    auto payload = MakeUniquePacket(data, len);
-    auto packet = hci::CommandPacketBuilder::Create(op_code, std::move(payload));
-
-    if (IsCommandStatusOpcode(op_code)) {
-      hci_layer_->EnqueueCommand(std::move(packet),
-                                 common::BindOnce(&impl::OnTransmitPacketStatus, common::Unretained(this), token),
-                                 handler_);
-    } else {
-      hci_layer_->EnqueueCommand(
-          std::move(packet), common::BindOnce(&impl::OnTransmitPacketCommandComplete, common::Unretained(this), token),
-          handler_);
-    }
-  }
-
-  void RegisterCommandComplete(CommandCompleteCallback callback) {
-    ASSERT(command_complete_callback_ == nullptr);
-    command_complete_callback_ = callback;
-  }
-
-  void UnregisterCommandComplete() {
-    ASSERT(command_complete_callback_ != nullptr);
-    command_complete_callback_ = nullptr;
-  }
-
-  void RegisterCommandStatus(CommandStatusCallback callback) {
-    ASSERT(command_status_callback_ == nullptr);
-    command_status_callback_ = callback;
-  }
-
-  void UnregisterCommandStatus() {
-    ASSERT(command_status_callback_ != nullptr);
-    command_status_callback_ = nullptr;
-  }
-
- private:
-  os::Handler* handler_{nullptr};
-  hci::HciLayer* hci_layer_{nullptr};
-
-  CommandCompleteCallback command_complete_callback_;
-  CommandStatusCallback command_status_callback_;
-
-  /**
-   * Returns true if expecting command complete, false otherwise
-   */
-  bool IsCommandStatusOpcode(hci::OpCode op_code) {
-    switch (op_code) {
-      case hci::OpCode::INQUIRY:
-      case hci::OpCode::CREATE_CONNECTION:
-      case hci::OpCode::DISCONNECT:
-      case hci::OpCode::ACCEPT_CONNECTION_REQUEST:
-      case hci::OpCode::REJECT_CONNECTION_REQUEST:
-      case hci::OpCode::CHANGE_CONNECTION_PACKET_TYPE:
-      case hci::OpCode::AUTHENTICATION_REQUESTED:
-      case hci::OpCode::SET_CONNECTION_ENCRYPTION:
-      case hci::OpCode::CHANGE_CONNECTION_LINK_KEY:
-      case hci::OpCode::MASTER_LINK_KEY:
-      case hci::OpCode::REMOTE_NAME_REQUEST:
-      case hci::OpCode::READ_REMOTE_SUPPORTED_FEATURES:
-      case hci::OpCode::READ_REMOTE_EXTENDED_FEATURES:
-      case hci::OpCode::READ_REMOTE_VERSION_INFORMATION:
-      case hci::OpCode::READ_CLOCK_OFFSET:
-      case hci::OpCode::SETUP_SYNCHRONOUS_CONNECTION:
-      case hci::OpCode::ACCEPT_SYNCHRONOUS_CONNECTION:
-      case hci::OpCode::REJECT_SYNCHRONOUS_CONNECTION:
-      case hci::OpCode::ENHANCED_SETUP_SYNCHRONOUS_CONNECTION:
-      case hci::OpCode::ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION:
-      case hci::OpCode::HOLD_MODE:
-      case hci::OpCode::SNIFF_MODE:
-      case hci::OpCode::EXIT_SNIFF_MODE:
-      case hci::OpCode::QOS_SETUP:
-      case hci::OpCode::SWITCH_ROLE:
-      case hci::OpCode::FLOW_SPECIFICATION:
-      case hci::OpCode::REFRESH_ENCRYPTION_KEY:
-      case hci::OpCode::LE_CREATE_CONNECTION:
-      case hci::OpCode::LE_CONNECTION_UPDATE:
-      case hci::OpCode::LE_READ_REMOTE_FEATURES:
-      case hci::OpCode::LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND:
-      case hci::OpCode::LE_GENERATE_DHKEY_COMMAND:
-      case hci::OpCode::LE_SET_PHY:
-      case hci::OpCode::LE_EXTENDED_CREATE_CONNECTION:
-      case hci::OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC:
-        return true;
-      default:
-        return false;
-    }
-  }
-
-  std::unique_ptr<packet::RawBuilder> MakeUniquePacket(const uint8_t* data, size_t len) {
-    packet::RawBuilder builder;
-    std::vector<uint8_t> bytes(data, data + len);
-
-    auto payload = std::make_unique<packet::RawBuilder>();
-    payload->AddOctets(bytes);
-
-    return payload;
-  }
-};
-
-void HciLayer::TransmitCommand(uint16_t op_code, const uint8_t* data, size_t len, const void* token) {
-  pimpl_->TransmitCommand(op_code, data, len, std::move(token));
-}
-
-void HciLayer::RegisterCommandComplete(CommandCompleteCallback callback) {
-  pimpl_->RegisterCommandComplete(callback);
-}
-
-void HciLayer::UnregisterCommandComplete() {
-  pimpl_->UnregisterCommandComplete();
-}
-
-void HciLayer::RegisterCommandStatus(CommandStatusCallback callback) {
-  pimpl_->RegisterCommandStatus(callback);
-}
-
-void HciLayer::UnregisterCommandStatus() {
-  pimpl_->UnregisterCommandStatus();
-}
-
-/**
- * Module methods
- */
-void HciLayer::ListDependencies(ModuleList* list) {
-  list->add<hci::HciLayer>();
-}
-
-void HciLayer::Start() {
-  LOG_INFO("%s Starting controller shim layer", __func__);
-  pimpl_ = std::make_unique<impl>(GetHandler(), GetDependency<hci::HciLayer>());
-}
-
-void HciLayer::Stop() {
-  pimpl_.reset();
-}
-
-std::string HciLayer::ToString() const {
-  return kModuleName;
-}
-
-}  // namespace shim
-}  // namespace bluetooth
diff --git a/gd/shim/hci_layer.h b/gd/shim/hci_layer.h
deleted file mode 100644 (file)
index a18b60f..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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 <cstdint>
-#include <memory>
-#include <string>
-
-#include "module.h"
-
-/**
- * The hci layer shim module that depends on the Gd hci layer module.
- */
-namespace bluetooth {
-namespace shim {
-
-/**
- * Legacy interface and API into the Gd shim hci layer module.
- */
-using CommandCompleteCallback =
-    std::function<void(uint16_t command_op_code, std::vector<const uint8_t> data, const void* token)>;
-using CommandStatusCallback =
-    std::function<void(uint16_t command_op_code, std::vector<const uint8_t> data, const void* token, uint8_t status)>;
-
-class HciLayer : public ::bluetooth::Module {
- public:
-  HciLayer() = default;
-  ~HciLayer() = default;
-
-  void TransmitCommand(uint16_t op_code, const uint8_t* data, size_t len, const void* token);
-
-  void RegisterCommandComplete(CommandCompleteCallback callback);
-  void UnregisterCommandComplete();
-
-  void RegisterCommandStatus(CommandStatusCallback callback);
-  void UnregisterCommandStatus();
-
-  static const ModuleFactory Factory;
-
- protected:
-  void ListDependencies(ModuleList* list) override;  // Module
-  void Start() override;                             // Module
-  void Stop() override;                              // Module
-  std::string ToString() const override;             // Module
-
- private:
-  struct impl;
-  std::unique_ptr<impl> pimpl_;
-  DISALLOW_COPY_AND_ASSIGN(HciLayer);
-};
-
-}  // namespace shim
-}  // namespace bluetooth
index c348f1b..d1197e4 100644 (file)
@@ -27,7 +27,6 @@
 namespace bluetooth {
 namespace shim {
 class Dumpsys;
-class HciLayer;
 class L2cap;
 }  // namespace shim
 }  // namespace bluetooth
\ No newline at end of file
index 04a19d2..8b7ebfe 100644 (file)
@@ -20,6 +20,7 @@
 #include "att/att_module.h"
 #include "hal/hci_hal.h"
 #include "hci/acl_manager.h"
+#include "hci/hci_layer.h"
 #include "hci/le_advertising_manager.h"
 #include "hci/le_scanning_manager.h"
 #include "l2cap/classic/l2cap_classic_module.h"
@@ -35,7 +36,6 @@
 #include "os/thread.h"
 #include "security/security_module.h"
 #include "shim/dumpsys.h"
-#include "shim/hci_layer.h"
 #include "shim/l2cap.h"
 #include "stack_manager.h"
 #include "storage/legacy.h"
@@ -54,6 +54,7 @@ struct bluetooth::shim::Stack::impl {
     modules.add<::bluetooth::att::AttModule>();
     modules.add<::bluetooth::hal::HciHal>();
     modules.add<::bluetooth::hci::AclManager>();
+    modules.add<::bluetooth::hci::HciLayer>();
     modules.add<::bluetooth::hci::LeAdvertisingManager>();
     modules.add<::bluetooth::hci::LeScanningManager>();
     modules.add<::bluetooth::l2cap::classic::L2capClassicModule>();
@@ -65,7 +66,6 @@ struct bluetooth::shim::Stack::impl {
     modules.add<::bluetooth::neighbor::NameDbModule>();
     modules.add<::bluetooth::neighbor::PageModule>();
     modules.add<::bluetooth::neighbor::ScanModule>();
-    modules.add<::bluetooth::shim::HciLayer>();
     modules.add<::bluetooth::security::SecurityModule>();
     modules.add<::bluetooth::storage::LegacyModule>();
     modules.add<::bluetooth::shim::Dumpsys>();
index 4deffd8..e9ef3ff 100644 (file)
@@ -25,7 +25,6 @@
 #include "neighbor/page.h"
 #include "security/security_module.h"
 #include "shim/dumpsys.h"
-#include "shim/hci_layer.h"
 #include "shim/l2cap.h"
 #include "stack_manager.h"
 #include "storage/legacy.h"
index a4b3bc0..a485535 100644 (file)
@@ -18,6 +18,7 @@
 #include "osi/include/future.h"
 
 #include "hci/controller.h"
+#include "hci/hci_layer.h"
 #include "hci/le_advertising_manager.h"
 #include "hci/le_scanning_manager.h"
 #include "neighbor/connectability.h"
@@ -28,7 +29,6 @@
 #include "os/handler.h"
 #include "security/security_module.h"
 #include "shim/dumpsys.h"
-#include "shim/hci_layer.h"
 #include "shim/l2cap.h"
 #include "shim/stack.h"
 #include "stack_manager.h"
@@ -88,10 +88,10 @@ bluetooth::neighbor::InquiryModule* bluetooth::shim::GetInquiry() {
       ->GetInstance<bluetooth::neighbor::InquiryModule>();
 }
 
-bluetooth::shim::HciLayer* bluetooth::shim::GetHciLayer() {
+bluetooth::hci::HciLayer* bluetooth::shim::GetHciLayer() {
   return GetGabeldorscheStack()
       ->GetStackManager()
-      ->GetInstance<bluetooth::shim::HciLayer>();
+      ->GetInstance<bluetooth::hci::HciLayer>();
 }
 
 bluetooth::shim::L2cap* bluetooth::shim::GetL2cap() {
index 2697697..28cac16 100644 (file)
@@ -44,8 +44,9 @@ class NameModule;
 class PageModule;
 }
 namespace hci {
-class LeAdvertisingManager;
 class Controller;
+class HciLayer;
+class LeAdvertisingManager;
 class LeScanningManager;
 }
 
@@ -69,7 +70,7 @@ neighbor::DiscoverabilityModule* GetDiscoverability();
 neighbor::ConnectabilityModule* GetConnectability();
 Dumpsys* GetDumpsys();
 neighbor::InquiryModule* GetInquiry();
-HciLayer* GetHciLayer();
+hci::HciLayer* GetHciLayer();
 L2cap* GetL2cap();
 neighbor::NameModule* GetName();
 neighbor::PageModule* GetPage();
index 9721b7d..c7acdbd 100644 (file)
 #include <cstdint>
 
 #include "btcore/include/module.h"
+#include "hci/hci_layer.h"
 #include "main/shim/hci_layer.h"
 #include "main/shim/shim.h"
 #include "osi/include/allocator.h"
 #include "osi/include/future.h"
-#include "shim/hci_layer.h"
+#include "packet/raw_builder.h"
 #include "stack/include/bt_types.h"
 
 /**
@@ -38,8 +39,6 @@
  */
 using CommandCallbackData = struct {
   void* context;
-  command_complete_cb complete_callback;
-  command_status_cb status_callback;
 };
 
 constexpr size_t kBtHdrSize = sizeof(BT_HDR);
@@ -49,40 +48,64 @@ constexpr size_t kCommandOpcodeSize = sizeof(uint16_t);
 static hci_t interface;
 static base::Callback<void(const base::Location&, BT_HDR*)> send_data_upwards;
 
-static future_t* hci_module_shut_down(void);
-static future_t* hci_module_start_up(void);
-
-static void OnCommandComplete(uint16_t command_op_code,
-                              std::vector<const uint8_t> data,
-                              const void* token) {
-  BT_HDR* response = static_cast<BT_HDR*>(osi_calloc(data.size() + kBtHdrSize));
-  std::copy(data.begin(), data.end(), response->data);
-  response->len = data.size();
-
-  const CommandCallbackData* command_callback_data =
-      static_cast<const CommandCallbackData*>(token);
-  CHECK(command_callback_data->complete_callback != nullptr);
-
-  command_callback_data->complete_callback(response,
-                                           command_callback_data->context);
-  delete command_callback_data;
+namespace {
+bool IsCommandStatusOpcode(bluetooth::hci::OpCode op_code) {
+  switch (op_code) {
+    case bluetooth::hci::OpCode::INQUIRY:
+    case bluetooth::hci::OpCode::CREATE_CONNECTION:
+    case bluetooth::hci::OpCode::DISCONNECT:
+    case bluetooth::hci::OpCode::ACCEPT_CONNECTION_REQUEST:
+    case bluetooth::hci::OpCode::REJECT_CONNECTION_REQUEST:
+    case bluetooth::hci::OpCode::CHANGE_CONNECTION_PACKET_TYPE:
+    case bluetooth::hci::OpCode::AUTHENTICATION_REQUESTED:
+    case bluetooth::hci::OpCode::SET_CONNECTION_ENCRYPTION:
+    case bluetooth::hci::OpCode::CHANGE_CONNECTION_LINK_KEY:
+    case bluetooth::hci::OpCode::MASTER_LINK_KEY:
+    case bluetooth::hci::OpCode::REMOTE_NAME_REQUEST:
+    case bluetooth::hci::OpCode::READ_REMOTE_SUPPORTED_FEATURES:
+    case bluetooth::hci::OpCode::READ_REMOTE_EXTENDED_FEATURES:
+    case bluetooth::hci::OpCode::READ_REMOTE_VERSION_INFORMATION:
+    case bluetooth::hci::OpCode::READ_CLOCK_OFFSET:
+    case bluetooth::hci::OpCode::SETUP_SYNCHRONOUS_CONNECTION:
+    case bluetooth::hci::OpCode::ACCEPT_SYNCHRONOUS_CONNECTION:
+    case bluetooth::hci::OpCode::REJECT_SYNCHRONOUS_CONNECTION:
+    case bluetooth::hci::OpCode::ENHANCED_SETUP_SYNCHRONOUS_CONNECTION:
+    case bluetooth::hci::OpCode::ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION:
+    case bluetooth::hci::OpCode::HOLD_MODE:
+    case bluetooth::hci::OpCode::SNIFF_MODE:
+    case bluetooth::hci::OpCode::EXIT_SNIFF_MODE:
+    case bluetooth::hci::OpCode::QOS_SETUP:
+    case bluetooth::hci::OpCode::SWITCH_ROLE:
+    case bluetooth::hci::OpCode::FLOW_SPECIFICATION:
+    case bluetooth::hci::OpCode::REFRESH_ENCRYPTION_KEY:
+    case bluetooth::hci::OpCode::LE_CREATE_CONNECTION:
+    case bluetooth::hci::OpCode::LE_CONNECTION_UPDATE:
+    case bluetooth::hci::OpCode::LE_READ_REMOTE_FEATURES:
+    case bluetooth::hci::OpCode::LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND:
+    case bluetooth::hci::OpCode::LE_GENERATE_DHKEY_COMMAND:
+    case bluetooth::hci::OpCode::LE_SET_PHY:
+    case bluetooth::hci::OpCode::LE_EXTENDED_CREATE_CONNECTION:
+    case bluetooth::hci::OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC:
+      return true;
+    default:
+      return false;
+  }
 }
 
-static void OnCommandStatus(uint16_t command_op_code,
-                            std::vector<const uint8_t> data, const void* token,
-                            uint8_t status) {
-  BT_HDR* response = static_cast<BT_HDR*>(osi_calloc(data.size() + kBtHdrSize));
-  std::copy(data.begin(), data.end(), response->data);
-  response->len = data.size();
+std::unique_ptr<bluetooth::packet::RawBuilder> MakeUniquePacket(
+    const uint8_t* data, size_t len) {
+  bluetooth::packet::RawBuilder builder;
+  std::vector<uint8_t> bytes(data, data + len);
 
-  const CommandCallbackData* command_callback_data =
-      static_cast<const CommandCallbackData*>(token);
-  CHECK(command_callback_data->status_callback != nullptr);
+  auto payload = std::make_unique<bluetooth::packet::RawBuilder>();
+  payload->AddOctets(bytes);
 
-  command_callback_data->status_callback(status, response,
-                                         command_callback_data->context);
-  delete command_callback_data;
+  return payload;
 }
+}  // namespace
+
+static future_t* hci_module_shut_down(void);
+static future_t* hci_module_start_up(void);
 
 EXPORT_SYMBOL extern const module_t gd_hci_module = {
     .name = GD_HCI_MODULE,
@@ -93,14 +116,10 @@ EXPORT_SYMBOL extern const module_t gd_hci_module = {
     .dependencies = {GD_SHIM_MODULE, nullptr}};
 
 static future_t* hci_module_start_up(void) {
-  bluetooth::shim::GetHciLayer()->RegisterCommandComplete(OnCommandComplete);
-  bluetooth::shim::GetHciLayer()->RegisterCommandStatus(OnCommandStatus);
   return nullptr;
 }
 
 static future_t* hci_module_shut_down(void) {
-  bluetooth::shim::GetHciLayer()->UnregisterCommandComplete();
-  bluetooth::shim::GetHciLayer()->UnregisterCommandStatus();
   return nullptr;
 }
 
@@ -109,6 +128,33 @@ static void set_data_cb(
   send_data_upwards = std::move(send_data_cb);
 }
 
+void OnTransmitPacketCommandComplete(command_complete_cb complete_callback,
+                                     void* context,
+                                     bluetooth::hci::CommandCompleteView view) {
+  std::vector<const uint8_t> data(view.begin(), view.end());
+
+  BT_HDR* response = static_cast<BT_HDR*>(osi_calloc(data.size() + kBtHdrSize));
+  std::copy(data.begin(), data.end(), response->data);
+  response->len = data.size();
+
+  complete_callback(response, context);
+}
+
+void OnTransmitPacketStatus(command_status_cb status_callback, void* context,
+                            bluetooth::hci::CommandStatusView view) {
+  std::vector<const uint8_t> data(view.begin(), view.end());
+
+  BT_HDR* response = static_cast<BT_HDR*>(osi_calloc(data.size() + kBtHdrSize));
+  std::copy(data.begin(), data.end(), response->data);
+  response->len = data.size();
+
+  uint8_t status = static_cast<uint8_t>(view.GetStatus());
+  status_callback(status, response, context);
+}
+
+using bluetooth::common::BindOnce;
+using bluetooth::common::Unretained;
+
 static void transmit_command(BT_HDR* command,
                              command_complete_cb complete_callback,
                              command_status_cb status_callback, void* context) {
@@ -124,14 +170,24 @@ static void transmit_command(BT_HDR* command,
   data += (kCommandOpcodeSize + kCommandLengthSize);
   len -= (kCommandOpcodeSize + kCommandLengthSize);
 
-  const CommandCallbackData* command_callback_data = new CommandCallbackData{
-      context,
-      complete_callback,
-      status_callback,
-  };
-  bluetooth::shim::GetHciLayer()->TransmitCommand(
-      command_op_code, const_cast<const uint8_t*>(data), len,
-      static_cast<const void*>(command_callback_data));
+  const bluetooth::hci::OpCode op_code =
+      static_cast<const bluetooth::hci::OpCode>(command_op_code);
+
+  auto payload = MakeUniquePacket(data, len);
+  auto packet =
+      bluetooth::hci::CommandPacketBuilder::Create(op_code, std::move(payload));
+
+  if (IsCommandStatusOpcode(op_code)) {
+    bluetooth::shim::GetHciLayer()->EnqueueCommand(
+        std::move(packet),
+        BindOnce(OnTransmitPacketStatus, status_callback, context),
+        bluetooth::shim::GetGdShimHandler());
+  } else {
+    bluetooth::shim::GetHciLayer()->EnqueueCommand(
+        std::move(packet),
+        BindOnce(OnTransmitPacketCommandComplete, complete_callback, context),
+        bluetooth::shim::GetGdShimHandler());
+  }
 }
 
 const hci_t* bluetooth::shim::hci_layer_get_interface() {