diff --git a/bluetooth/hci/Android.bp b/bluetooth/hci/Android.bp
new file mode 100644
index 0000000..f0f6e8f
--- /dev/null
+++ b/bluetooth/hci/Android.bp
@@ -0,0 +1,46 @@
+package {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library_static {
+    name: "android.hardware.bluetooth.hci",
+    vendor_available: true,
+    host_supported: true,
+    defaults: ["hidl_defaults"],
+    srcs: [
+        "hci_packetizer.cc",
+        "h4_protocol.cc",
+    ],
+    export_include_dirs: ["."],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "liblog",
+        "libutils",
+    ],
+}
+
+cc_test {
+    name: "bluetooth-vendor-interface-hci-test",
+    host_supported: true,
+    defaults: ["hidl_defaults"],
+    srcs: [
+        "test/h4_protocol_unittest.cc",
+    ],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "liblog",
+        "libutils",
+    ],
+    static_libs: [
+        "android.hardware.bluetooth.async",
+        "android.hardware.bluetooth.hci",
+        "libgmock",
+    ],
+    sanitize: {
+        address: true,
+        cfi: true,
+    },
+    test_suites: ["general-tests"],
+}
diff --git a/bluetooth/hci/h4_protocol.cc b/bluetooth/hci/h4_protocol.cc
new file mode 100644
index 0000000..97ba7aa
--- /dev/null
+++ b/bluetooth/hci/h4_protocol.cc
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2022 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 "h4_protocol.h"
+
+#define LOG_TAG "android.hardware.bluetooth.hci-h4"
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/uio.h>
+
+#include "log/log.h"
+
+namespace android::hardware::bluetooth::hci {
+
+H4Protocol::H4Protocol(int fd, PacketReadCallback cmd_cb,
+                       PacketReadCallback acl_cb, PacketReadCallback sco_cb,
+                       PacketReadCallback event_cb, PacketReadCallback iso_cb,
+                       DisconnectCallback disconnect_cb)
+    : uart_fd_(fd),
+      cmd_cb_(std::move(cmd_cb)),
+      acl_cb_(std::move(acl_cb)),
+      sco_cb_(std::move(sco_cb)),
+      event_cb_(std::move(event_cb)),
+      iso_cb_(std::move(iso_cb)),
+      disconnect_cb_(std::move(disconnect_cb)) {}
+
+size_t H4Protocol::Send(PacketType type, const std::vector<uint8_t>& vector) {
+  return Send(type, vector.data(), vector.size());
+}
+
+size_t H4Protocol::Send(PacketType type, const uint8_t* data, size_t length) {
+  /* For HCI communication over USB dongle, multiple write results in
+   * response timeout as driver expect type + data at once to process
+   * the command, so using "writev"(for atomicity) here.
+   */
+  struct iovec iov[2];
+  ssize_t ret = 0;
+  iov[0].iov_base = &type;
+  iov[0].iov_len = sizeof(type);
+  iov[1].iov_base = (void*)data;
+  iov[1].iov_len = length;
+  while (1) {
+    ret = TEMP_FAILURE_RETRY(writev(uart_fd_, iov, 2));
+    if (ret == -1) {
+      if (errno == EAGAIN) {
+        ALOGE("%s error writing to UART (%s)", __func__, strerror(errno));
+        continue;
+      }
+    } else if (ret == 0) {
+      // Nothing written :(
+      ALOGE("%s zero bytes written - something went wrong...", __func__);
+      break;
+    }
+    break;
+  }
+  return ret;
+}
+
+size_t H4Protocol::OnPacketReady(const std::vector<uint8_t>& packet) {
+  switch (hci_packet_type_) {
+    case PacketType::COMMAND:
+      cmd_cb_(packet);
+      break;
+    case PacketType::ACL_DATA:
+      acl_cb_(packet);
+      break;
+    case PacketType::SCO_DATA:
+      sco_cb_(packet);
+      break;
+    case PacketType::EVENT:
+      event_cb_(packet);
+      break;
+    case PacketType::ISO_DATA:
+      iso_cb_(packet);
+      break;
+    default: {
+      LOG_ALWAYS_FATAL("Bad packet type 0x%x",
+                       static_cast<int>(hci_packet_type_));
+    }
+  }
+  return packet.size();
+}
+
+void H4Protocol::SendDataToPacketizer(uint8_t* buffer, size_t length) {
+  std::vector<uint8_t> input_buffer{buffer, buffer + length};
+  size_t buffer_offset = 0;
+  while (buffer_offset < input_buffer.size()) {
+    if (hci_packet_type_ == PacketType::UNKNOWN) {
+      hci_packet_type_ =
+          static_cast<PacketType>(input_buffer.data()[buffer_offset]);
+      buffer_offset += 1;
+    } else {
+      bool packet_ready = hci_packetizer_.OnDataReady(
+          hci_packet_type_, input_buffer, buffer_offset);
+      if (packet_ready) {
+        // Call packet callback and move offset.
+        buffer_offset += OnPacketReady(hci_packetizer_.GetPacket());
+        // Get ready for the next type byte.
+        hci_packet_type_ = PacketType::UNKNOWN;
+      } else {
+        // The data was consumed, but there wasn't a packet.
+        buffer_offset = input_buffer.size();
+      }
+    }
+  }
+}
+
+void H4Protocol::OnDataReady() {
+  if (disconnected_) {
+    return;
+  }
+  uint8_t buffer[kMaxPacketLength];
+  ssize_t bytes_read =
+      TEMP_FAILURE_RETRY(read(uart_fd_, buffer, kMaxPacketLength));
+  if (bytes_read == 0) {
+    ALOGI("No bytes read, calling the disconnect callback");
+    disconnected_ = true;
+    disconnect_cb_();
+    return;
+  }
+  if (bytes_read < 0) {
+    ALOGW("error reading from UART (%s)", strerror(errno));
+    return;
+  }
+  SendDataToPacketizer(buffer, bytes_read);
+}
+
+}  // namespace android::hardware::bluetooth::hci
diff --git a/bluetooth/hci/h4_protocol.h b/bluetooth/hci/h4_protocol.h
new file mode 100644
index 0000000..5daee83
--- /dev/null
+++ b/bluetooth/hci/h4_protocol.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2022 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 <memory>
+#include <vector>
+
+#include "hci_internals.h"
+#include "hci_packetizer.h"
+
+namespace android::hardware::bluetooth::hci {
+
+using PacketReadCallback = std::function<void(const std::vector<uint8_t>&)>;
+using DisconnectCallback = std::function<void(void)>;
+
+class H4Protocol {
+ public:
+  H4Protocol(int fd, PacketReadCallback cmd_cb, PacketReadCallback acl_cb,
+             PacketReadCallback sco_cb, PacketReadCallback event_cb,
+             PacketReadCallback iso_cb, DisconnectCallback disconnect_cb);
+
+  size_t Send(PacketType type, const uint8_t* data, size_t length);
+  size_t Send(PacketType type, const std::vector<uint8_t>& data);
+
+  void OnDataReady();
+
+ protected:
+  size_t OnPacketReady(const std::vector<uint8_t>& packet);
+  void SendDataToPacketizer(uint8_t* buffer, size_t length);
+
+ private:
+  int uart_fd_;
+  bool disconnected_{false};
+
+  PacketReadCallback cmd_cb_;
+  PacketReadCallback acl_cb_;
+  PacketReadCallback sco_cb_;
+  PacketReadCallback event_cb_;
+  PacketReadCallback iso_cb_;
+  DisconnectCallback disconnect_cb_;
+
+  PacketType hci_packet_type_{PacketType::UNKNOWN};
+  HciPacketizer hci_packetizer_;
+
+  /**
+   * Question : Why read in single chunk rather than multiple reads?
+   * Answer: Using multiple reads does not work with some BT USB dongles.
+   * Reading in single shot gives expected response.
+   * ACL max length is 2 bytes, so using 64K as the buffer length.
+   */
+  static constexpr size_t kMaxPacketLength = 64 * 1024;
+};
+
+}  // namespace android::hardware::bluetooth::hci
diff --git a/bluetooth/hci/hci_internals.h b/bluetooth/hci/hci_internals.h
new file mode 100644
index 0000000..71b6191
--- /dev/null
+++ b/bluetooth/hci/hci_internals.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2022 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 <cstdlib>
+
+namespace android::hardware::bluetooth::hci {
+
+// HCI UART transport packet types (Volume 4, Part A, 2)
+enum class PacketType : uint8_t {
+  UNKNOWN = 0,
+  COMMAND = 1,
+  ACL_DATA = 2,
+  SCO_DATA = 3,
+  EVENT = 4,
+  ISO_DATA = 5,
+};
+
+// 2 bytes for opcode, 1 byte for parameter length (Volume 4, Part E, 5.4.1)
+static constexpr size_t kCommandHeaderSize = 3;
+static constexpr size_t kCommandLengthOffset = 2;
+
+// 2 bytes for handle, 2 bytes for data length (Volume 4, Part E, 5.4.2)
+static constexpr size_t kAclHeaderSize = 4;
+static constexpr size_t kAclLengthOffset = 2;
+
+// 2 bytes for handle, 1 byte for data length (Volume 4, Part E, 5.4.3)
+static constexpr size_t kScoHeaderSize = 3;
+static constexpr size_t kScoLengthOffset = 2;
+
+// 1 byte for event code, 1 byte for parameter length (Volume 4, Part E, 5.4.4)
+static constexpr size_t kEventHeaderSize = 2;
+static constexpr size_t kEventLengthOffset = 1;
+
+// 2 bytes for handle, 2 bytes for data length (Volume 4, Part E, 5.4.5)
+static constexpr size_t kIsoHeaderSize = 4;
+static constexpr size_t kIsoLengthOffset = 2;
+
+static constexpr size_t kMaxHeaderSize = kAclHeaderSize;
+
+}  // namespace android::hardware::bluetooth::hci
diff --git a/bluetooth/hci/hci_packetizer.cc b/bluetooth/hci/hci_packetizer.cc
new file mode 100644
index 0000000..5b6c443
--- /dev/null
+++ b/bluetooth/hci/hci_packetizer.cc
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2022 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 "hci_packetizer.h"
+
+#define LOG_TAG "android.hardware.bluetooth.hci-packetizer"
+#include "log/log.h"
+
+namespace android::hardware::bluetooth::hci {
+
+namespace {
+
+const size_t header_size_for_type[] = {0,
+                                       kCommandHeaderSize,
+                                       kAclHeaderSize,
+                                       kScoHeaderSize,
+                                       kEventHeaderSize,
+                                       kIsoHeaderSize};
+const size_t packet_length_offset_for_type[] = {0,
+                                                kCommandLengthOffset,
+                                                kAclLengthOffset,
+                                                kScoLengthOffset,
+                                                kEventLengthOffset,
+                                                kIsoLengthOffset};
+
+size_t HciGetPacketLengthForType(PacketType type,
+                                 const std::vector<uint8_t>& header) {
+  size_t offset = packet_length_offset_for_type[static_cast<uint8_t>(type)];
+  if (type != PacketType::ACL_DATA && type != PacketType::ISO_DATA) {
+    return header[offset];
+  }
+  return (((header[offset + 1]) << 8) | header[offset]);
+}
+
+}  // namespace
+
+const std::vector<uint8_t>& HciPacketizer::GetPacket() const { return packet_; }
+
+bool HciPacketizer::OnDataReady(PacketType packet_type,
+                                const std::vector<uint8_t>& buffer,
+                                size_t offset) {
+  bool packet_completed = false;
+  size_t bytes_available = buffer.size() - offset;
+  switch (state_) {
+    case HCI_HEADER: {
+      size_t header_size =
+          header_size_for_type[static_cast<size_t>(packet_type)];
+      if (bytes_remaining_ == 0) {
+        bytes_remaining_ = header_size;
+        packet_.clear();
+      }
+      size_t bytes_to_copy = std::min(bytes_remaining_, bytes_available);
+      packet_.insert(packet_.end(), buffer.begin() + offset,
+                     buffer.begin() + offset + bytes_to_copy);
+      bytes_remaining_ -= bytes_to_copy;
+      bytes_available -= bytes_to_copy;
+      if (bytes_remaining_ == 0) {
+        bytes_remaining_ = HciGetPacketLengthForType(packet_type, packet_);
+        if (bytes_remaining_ > 0) {
+          state_ = HCI_PAYLOAD;
+          if (bytes_available > 0) {
+            packet_completed =
+                OnDataReady(packet_type, buffer, offset + bytes_to_copy);
+          }
+        } else {
+          packet_completed = true;
+        }
+      }
+      break;
+    }
+
+    case HCI_PAYLOAD: {
+      size_t bytes_to_copy = std::min(bytes_remaining_, bytes_available);
+      packet_.insert(packet_.end(), buffer.begin() + offset,
+                     buffer.begin() + offset + bytes_to_copy);
+      bytes_remaining_ -= bytes_to_copy;
+      if (bytes_remaining_ == 0) {
+        state_ = HCI_HEADER;
+        packet_completed = true;
+      }
+      break;
+    }
+  }
+  return packet_completed;
+}
+
+}  // namespace android::hardware::bluetooth::hci
diff --git a/bluetooth/hci/hci_packetizer.h b/bluetooth/hci/hci_packetizer.h
new file mode 100644
index 0000000..ba3e841
--- /dev/null
+++ b/bluetooth/hci/hci_packetizer.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2022 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 <functional>
+#include <memory>
+#include <vector>
+
+#include "hci_internals.h"
+
+namespace android::hardware::bluetooth::hci {
+
+class HciPacketizer {
+ public:
+  HciPacketizer() = default;
+  bool OnDataReady(PacketType packet_type, const std::vector<uint8_t>& data,
+                   size_t offset);
+  const std::vector<uint8_t>& GetPacket() const;
+
+ protected:
+  enum State { HCI_HEADER, HCI_PAYLOAD };
+  State state_{HCI_HEADER};
+  std::vector<uint8_t> packet_;
+  size_t bytes_remaining_{0};
+};
+
+}  // namespace android::hardware::bluetooth::hci
diff --git a/bluetooth/hci/test/h4_protocol_unittest.cc b/bluetooth/hci/test/h4_protocol_unittest.cc
new file mode 100644
index 0000000..d6f74fc
--- /dev/null
+++ b/bluetooth/hci/test/h4_protocol_unittest.cc
@@ -0,0 +1,441 @@
+/*
+ * Copyright 2022 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_h4_unittest"
+
+#include "h4_protocol.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <log/log.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <cstdint>
+#include <cstring>
+#include <future>
+#include <vector>
+
+#include "async_fd_watcher.h"
+#include "log/log.h"
+
+using android::hardware::bluetooth::async::AsyncFdWatcher;
+using namespace android::hardware::bluetooth::hci;
+using ::testing::Eq;
+
+static char sample_data1[100] = "A point is that which has no part.";
+static char sample_data2[100] = "A line is breadthless length.";
+static char sample_data3[100] = "The ends of a line are points.";
+static char sample_data4[100] =
+    "A plane surface is a surface which lies evenly with the straight ...";
+static char acl_data[100] =
+    "A straight line is a line which lies evenly with the points on itself.";
+static char sco_data[100] =
+    "A surface is that which has length and breadth only.";
+static char event_data[100] = "The edges of a surface are lines.";
+static char iso_data[100] =
+    "A plane angle is the inclination to one another of two lines in a ...";
+
+MATCHER_P3(PacketMatches, header_, header_length, payload,
+           "Match header_length bytes of header and then the payload") {
+  size_t payload_length = strlen(payload);
+  if (header_length + payload_length != arg.size()) {
+    return false;
+  }
+
+  if (memcmp(header_, arg.data(), header_length) != 0) {
+    return false;
+  }
+
+  return memcmp(payload, arg.data() + header_length, payload_length) == 0;
+};
+
+ACTION_P(Notify, barrier) {
+  ALOGD("%s", __func__);
+  barrier->set_value();
+}
+
+class H4ProtocolTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    ALOGD("%s", __func__);
+
+    int sockfd[2];
+    socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd);
+    chip_uart_fd_ = sockfd[1];
+    stack_uart_fd_ = sockfd[0];
+    h4_hci_ = std::make_shared<H4Protocol>(
+        stack_uart_fd_, cmd_cb_.AsStdFunction(), acl_cb_.AsStdFunction(),
+        sco_cb_.AsStdFunction(), event_cb_.AsStdFunction(),
+        iso_cb_.AsStdFunction(), disconnect_cb_.AsStdFunction());
+  }
+
+  void TearDown() override {
+    close(stack_uart_fd_);
+    close(chip_uart_fd_);
+  }
+
+  virtual void CallDataReady() { h4_hci_->OnDataReady(); }
+
+  void SendAndReadUartOutbound(PacketType type, char* data) {
+    ALOGD("%s sending", __func__);
+    int data_length = strlen(data);
+    h4_hci_->Send(type, (uint8_t*)data, data_length);
+
+    int uart_length = data_length + 1;  // + 1 for data type code
+    int i;
+
+    ALOGD("%s reading", __func__);
+    for (i = 0; i < uart_length; i++) {
+      fd_set read_fds;
+      FD_ZERO(&read_fds);
+      FD_SET(chip_uart_fd_, &read_fds);
+      TEMP_FAILURE_RETRY(
+          select(chip_uart_fd_ + 1, &read_fds, nullptr, nullptr, nullptr));
+
+      char byte;
+      TEMP_FAILURE_RETRY(read(chip_uart_fd_, &byte, 1));
+
+      EXPECT_EQ(i == 0 ? static_cast<uint8_t>(type) : data[i - 1], byte);
+    }
+
+    EXPECT_EQ(i, uart_length);
+  }
+
+  void ExpectInboundAclData(char* payload, std::promise<void>* promise) {
+    // h4 type[1] + handle[2] + size[2]
+    header_[0] = static_cast<uint8_t>(PacketType::ACL_DATA);
+    header_[1] = 19;
+    header_[2] = 92;
+    int length = strlen(payload);
+    header_[3] = length & 0xFF;
+    header_[4] = (length >> 8) & 0xFF;
+    ALOGD("(%d bytes) %s", length, payload);
+
+    EXPECT_CALL(acl_cb_,
+                Call(PacketMatches(header_ + 1, kAclHeaderSize, payload)))
+        .WillOnce(Notify(promise));
+  }
+
+  void WaitForTimeout(size_t timeout_ms, std::promise<void>* promise) {
+    auto future = promise->get_future();
+    auto status = future.wait_for(std::chrono::milliseconds(timeout_ms));
+    EXPECT_EQ(status, std::future_status::ready);
+  }
+
+  void WriteInboundAclData(char* payload) {
+    // Use the header_ computed in ExpectInboundAclData
+    TEMP_FAILURE_RETRY(write(chip_uart_fd_, header_, kAclHeaderSize + 1));
+    TEMP_FAILURE_RETRY(write(chip_uart_fd_, payload, strlen(payload)));
+  }
+
+  void ExpectInboundScoData(char* payload, std::promise<void>* promise) {
+    // h4 type[1] + handle[2] + size[1]
+    header_[0] = static_cast<uint8_t>(PacketType::SCO_DATA);
+    header_[1] = 20;
+    header_[2] = 17;
+    header_[3] = strlen(payload) & 0xFF;
+    EXPECT_CALL(sco_cb_,
+                Call(PacketMatches(header_ + 1, kScoHeaderSize, payload)))
+        .WillOnce(Notify(promise));
+  }
+
+  void WriteInboundScoData(char* payload) {
+    // Use the header_ computed in ExpectInboundScoData
+    ALOGD("%s writing", __func__);
+    TEMP_FAILURE_RETRY(write(chip_uart_fd_, header_, kScoHeaderSize + 1));
+    TEMP_FAILURE_RETRY(write(chip_uart_fd_, payload, strlen(payload)));
+  }
+
+  void ExpectInboundEvent(char* payload, std::promise<void>* promise) {
+    // h4 type[1] + event_code[1] + size[1]
+    header_[0] = static_cast<uint8_t>(PacketType::EVENT);
+    header_[1] = 9;
+    header_[2] = strlen(payload) & 0xFF;
+    EXPECT_CALL(event_cb_,
+                Call(PacketMatches(header_ + 1, kEventHeaderSize, payload)))
+        .WillOnce(Notify(promise));
+  }
+
+  void WriteInboundEvent(char* payload) {
+    // Use the header_ computed in ExpectInboundEvent
+    char preamble[3] = {static_cast<uint8_t>(PacketType::EVENT), 9, 0};
+    preamble[2] = strlen(payload) & 0xFF;
+    ALOGD("%s writing", __func__);
+    TEMP_FAILURE_RETRY(write(chip_uart_fd_, header_, kEventHeaderSize + 1));
+    TEMP_FAILURE_RETRY(write(chip_uart_fd_, payload, strlen(payload)));
+  }
+
+  void ExpectInboundIsoData(char* payload, std::promise<void>* promise) {
+    // h4 type[1] + handle[2] + size[1]
+    header_[0] = static_cast<uint8_t>(PacketType::ISO_DATA);
+    header_[1] = 19;
+    header_[2] = 92;
+    int length = strlen(payload);
+    header_[3] = length & 0xFF;
+    header_[4] = (length >> 8) & 0x3F;
+
+    EXPECT_CALL(iso_cb_,
+                Call(PacketMatches(header_ + 1, kIsoHeaderSize, payload)))
+        .WillOnce(Notify(promise));
+  }
+
+  void WriteInboundIsoData(char* payload) {
+    // Use the header_ computed in ExpectInboundIsoData
+    ALOGD("%s writing", __func__);
+    TEMP_FAILURE_RETRY(write(chip_uart_fd_, header_, kIsoHeaderSize + 1));
+    TEMP_FAILURE_RETRY(write(chip_uart_fd_, payload, strlen(payload)));
+  }
+
+  void WriteAndExpectManyInboundAclDataPackets(char* payload) {
+    size_t kNumPackets = 20;
+    // h4 type[1] + handle[2] + size[2]
+    char preamble[5] = {static_cast<uint8_t>(PacketType::ACL_DATA), 19, 92, 0,
+                        0};
+    int length = strlen(payload);
+    preamble[3] = length & 0xFF;
+    preamble[4] = (length >> 8) & 0xFF;
+
+    EXPECT_CALL(acl_cb_, Call(PacketMatches(preamble + 1, sizeof(preamble) - 1,
+                                            payload)))
+        .Times(kNumPackets);
+
+    for (size_t i = 0; i < kNumPackets; i++) {
+      TEMP_FAILURE_RETRY(write(chip_uart_fd_, preamble, sizeof(preamble)));
+      TEMP_FAILURE_RETRY(write(chip_uart_fd_, payload, strlen(payload)));
+    }
+
+    CallDataReady();
+  }
+
+  testing::MockFunction<void(const std::vector<uint8_t>&)> cmd_cb_;
+  testing::MockFunction<void(const std::vector<uint8_t>&)> event_cb_;
+  testing::MockFunction<void(const std::vector<uint8_t>&)> acl_cb_;
+  testing::MockFunction<void(const std::vector<uint8_t>&)> sco_cb_;
+  testing::MockFunction<void(const std::vector<uint8_t>&)> iso_cb_;
+  testing::MockFunction<void(void)> disconnect_cb_;
+  std::shared_ptr<H4Protocol> h4_hci_;
+  int chip_uart_fd_;
+  int stack_uart_fd_;
+
+  char header_[5];
+};
+
+// Test sending data sends correct data onto the UART
+TEST_F(H4ProtocolTest, TestSends) {
+  SendAndReadUartOutbound(PacketType::COMMAND, sample_data1);
+  SendAndReadUartOutbound(PacketType::ACL_DATA, sample_data2);
+  SendAndReadUartOutbound(PacketType::SCO_DATA, sample_data3);
+  SendAndReadUartOutbound(PacketType::ISO_DATA, sample_data4);
+}
+
+// Ensure we properly parse data coming from the UART
+TEST_F(H4ProtocolTest, TestReads) {
+  std::promise<void> acl_promise;
+  std::promise<void> sco_promise;
+  std::promise<void> event_promise;
+  std::promise<void> iso_promise;
+
+  ExpectInboundAclData(acl_data, &acl_promise);
+  WriteInboundAclData(acl_data);
+  CallDataReady();
+  ExpectInboundScoData(sco_data, &sco_promise);
+  WriteInboundScoData(sco_data);
+  CallDataReady();
+  ExpectInboundEvent(event_data, &event_promise);
+  WriteInboundEvent(event_data);
+  CallDataReady();
+  ExpectInboundIsoData(iso_data, &iso_promise);
+  WriteInboundIsoData(iso_data);
+  CallDataReady();
+
+  WaitForTimeout(100, &acl_promise);
+  WaitForTimeout(100, &sco_promise);
+  WaitForTimeout(100, &event_promise);
+  WaitForTimeout(100, &iso_promise);
+}
+
+TEST_F(H4ProtocolTest, TestMultiplePackets) {
+  WriteAndExpectManyInboundAclDataPackets(sco_data);
+}
+
+TEST_F(H4ProtocolTest, TestDisconnect) {
+  EXPECT_CALL(disconnect_cb_, Call());
+  close(chip_uart_fd_);
+  CallDataReady();
+}
+
+TEST_F(H4ProtocolTest, TestPartialWrites) {
+  size_t payload_len = strlen(acl_data);
+  const size_t kNumIntervals = payload_len + 1;
+  // h4 type[1] + handle[2] + size[2]
+  header_[0] = static_cast<uint8_t>(PacketType::ACL_DATA);
+  header_[1] = 19;
+  header_[2] = 92;
+  header_[3] = payload_len & 0xFF;
+  header_[4] = (payload_len >> 8) & 0xFF;
+
+  EXPECT_CALL(acl_cb_,
+              Call(PacketMatches(header_ + 1, sizeof(header_) - 1, acl_data)))
+      .Times(kNumIntervals);
+
+  for (size_t interval = 1; interval < kNumIntervals + 1; interval++) {
+    // Use the header_ data that expect already set up.
+    if (interval < kAclHeaderSize) {
+      TEMP_FAILURE_RETRY(write(chip_uart_fd_, header_, interval));
+      CallDataReady();
+      TEMP_FAILURE_RETRY(write(chip_uart_fd_, header_ + interval,
+                               kAclHeaderSize + 1 - interval));
+      CallDataReady();
+    } else {
+      TEMP_FAILURE_RETRY(write(chip_uart_fd_, header_, kAclHeaderSize + 1));
+      CallDataReady();
+    }
+
+    for (size_t bytes = 0; bytes + interval <= payload_len; bytes += interval) {
+      TEMP_FAILURE_RETRY(write(chip_uart_fd_, acl_data + bytes, interval));
+      CallDataReady();
+    }
+    size_t extra_bytes = payload_len % interval;
+    if (extra_bytes) {
+      TEMP_FAILURE_RETRY(write(
+          chip_uart_fd_, acl_data + payload_len - extra_bytes, extra_bytes));
+      CallDataReady();
+    }
+  }
+}
+
+class H4ProtocolAsyncTest : public H4ProtocolTest {
+ protected:
+  void SetUp() override {
+    H4ProtocolTest::SetUp();
+    fd_watcher_.WatchFdForNonBlockingReads(
+        stack_uart_fd_, [this](int) { h4_hci_->OnDataReady(); });
+  }
+
+  void TearDown() override { fd_watcher_.StopWatchingFileDescriptors(); }
+
+  void CallDataReady() override {
+    // The Async test can't call data ready.
+    FAIL();
+  }
+
+  void SendAndReadUartOutbound(PacketType type, char* data) {
+    ALOGD("%s sending", __func__);
+    int data_length = strlen(data);
+    h4_hci_->Send(type, (uint8_t*)data, data_length);
+
+    int uart_length = data_length + 1;  // + 1 for data type code
+    int i;
+
+    ALOGD("%s reading", __func__);
+    for (i = 0; i < uart_length; i++) {
+      fd_set read_fds;
+      FD_ZERO(&read_fds);
+      FD_SET(chip_uart_fd_, &read_fds);
+      TEMP_FAILURE_RETRY(
+          select(chip_uart_fd_ + 1, &read_fds, nullptr, nullptr, nullptr));
+
+      char byte;
+      TEMP_FAILURE_RETRY(read(chip_uart_fd_, &byte, 1));
+
+      EXPECT_EQ(i == 0 ? static_cast<uint8_t>(type) : data[i - 1], byte);
+    }
+
+    EXPECT_EQ(i, uart_length);
+  }
+
+  void WriteAndExpectInboundAclData(char* payload) {
+    std::promise<void> promise;
+    ExpectInboundAclData(payload, &promise);
+    WriteInboundAclData(payload);
+    WaitForTimeout(100, &promise);
+  }
+
+  void WriteAndExpectInboundScoData(char* payload) {
+    std::promise<void> promise;
+    ExpectInboundScoData(payload, &promise);
+    WriteInboundScoData(payload);
+    WaitForTimeout(100, &promise);
+  }
+
+  void WriteAndExpectInboundEvent(char* payload) {
+    std::promise<void> promise;
+    ExpectInboundEvent(payload, &promise);
+    WriteInboundEvent(payload);
+    WaitForTimeout(100, &promise);
+  }
+
+  void WriteAndExpectInboundIsoData(char* payload) {
+    std::promise<void> promise;
+    ExpectInboundIsoData(payload, &promise);
+    WriteInboundIsoData(payload);
+    WaitForTimeout(100, &promise);
+  }
+
+  void WriteAndExpectManyInboundAclDataPackets(char* payload) {
+    const size_t kNumPackets = 20;
+    // h4 type[1] + handle[2] + size[2]
+    char preamble[5] = {static_cast<uint8_t>(PacketType::ACL_DATA), 19, 92, 0,
+                        0};
+    int length = strlen(payload);
+    preamble[3] = length & 0xFF;
+    preamble[4] = (length >> 8) & 0xFF;
+
+    EXPECT_CALL(acl_cb_, Call(PacketMatches(preamble + 1, sizeof(preamble) - 1,
+                                            payload)))
+        .Times(kNumPackets);
+
+    for (size_t i = 0; i < kNumPackets; i++) {
+      TEMP_FAILURE_RETRY(write(chip_uart_fd_, preamble, sizeof(preamble)));
+      TEMP_FAILURE_RETRY(write(chip_uart_fd_, payload, strlen(payload)));
+    }
+
+    WriteAndExpectInboundEvent(event_data);
+  }
+
+  AsyncFdWatcher fd_watcher_;
+};
+
+// Test sending data sends correct data onto the UART
+TEST_F(H4ProtocolAsyncTest, TestSends) {
+  SendAndReadUartOutbound(PacketType::COMMAND, sample_data1);
+  SendAndReadUartOutbound(PacketType::ACL_DATA, sample_data2);
+  SendAndReadUartOutbound(PacketType::SCO_DATA, sample_data3);
+  SendAndReadUartOutbound(PacketType::ISO_DATA, sample_data4);
+}
+
+// Ensure we properly parse data coming from the UART
+TEST_F(H4ProtocolAsyncTest, TestReads) {
+  WriteAndExpectInboundAclData(acl_data);
+  WriteAndExpectInboundScoData(sco_data);
+  WriteAndExpectInboundEvent(event_data);
+  WriteAndExpectInboundIsoData(iso_data);
+}
+
+TEST_F(H4ProtocolAsyncTest, TestMultiplePackets) {
+  WriteAndExpectManyInboundAclDataPackets(sco_data);
+}
+
+TEST_F(H4ProtocolAsyncTest, TestDisconnect) {
+  std::promise<void> promise;
+  EXPECT_CALL(disconnect_cb_, Call()).WillOnce(Notify(&promise));
+  close(chip_uart_fd_);
+
+  // Fail if it takes longer than 100 ms.
+  WaitForTimeout(100, &promise);
+}
