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

Commit 0febef2c authored by Boon Jun Soh's avatar Boon Jun Soh Committed by Gerrit Code Review
Browse files

Merge "Revert "RootCanal: Remove h4_packetizer_lib to device/google/cuttlefish""

parents 9002040c a1447e17
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -89,7 +89,9 @@ cc_library_static {
        "model/devices/scripted_beacon.cc",
        "model/devices/sniffer.cc",
        "model/hci/h4_data_channel_packetizer.cc",
        "model/hci/h4_packetizer.cc",
        "model/hci/h4_parser.cc",
        "model/hci/hci_protocol.cc",
        "model/hci/hci_sniffer.cc",
        "model/hci/hci_socket_transport.cc",
        "model/setup/async_manager.cc",
@@ -438,3 +440,30 @@ genrule {
    srcs: ["packets/hci/hci_packets.pdl"],
    out: ["hci_packets.rs"],
}

// bt_vhci_forwarder in cuttlefish depends on this H4Packetizer implementation.
cc_library_static {
    name: "h4_packetizer_lib",
    vendor: true,
    defaults: [
        "gd_defaults",
    ],
    srcs: [
        "model/hci/h4_packetizer.cc",
        "model/hci/h4_parser.cc",
        "model/hci/hci_protocol.cc",
    ],
    header_libs: [
        "libbase_headers",
    ],
    local_include_dirs: [
        "include",
    ],
    export_include_dirs: [
        ".",
        "include",
    ],
    include_dirs: [
        "packages/modules/Bluetooth/system/gd",
    ],
}
+1 −0
Original line number Diff line number Diff line
@@ -259,6 +259,7 @@ android_add_library(
      model/devices/sniffer.cc
      model/hci/h4_data_channel_packetizer.cc
      model/hci/h4_parser.cc
      model/hci/hci_protocol.cc
      model/hci/hci_sniffer.cc
      model/hci/hci_socket_transport.cc
      model/setup/device_boutique.cc
+1 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@

#include "log.h"                     // for LOG_ERROR, LOG_ALWAYS_FATAL
#include "model/hci/h4_parser.h"     // for H4Parser, ClientDisconnectCa...
#include "model/hci/hci_protocol.h"  // for PacketReadCallback, AsyncDataChannel
#include "net/async_data_channel.h"  // for AsyncDataChannel

namespace rootcanal {
+4 −3
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <memory>  // for shared_ptr

#include "h4_parser.h"     // for ClientDisconnectCallback, H4Parser
#include "hci_protocol.h"  // for PacketReadCallback, AsyncDataChannel, HciProtocol
#include "net/async_data_channel.h"  // for AsyncDataChannel

namespace rootcanal {
@@ -30,7 +31,7 @@ using android::net::AsyncDataChannel;

// A socket based H4DataChannelPacketizer. Call OnDataReady whenever
// data can be read from the socket.
class H4DataChannelPacketizer {
class H4DataChannelPacketizer : public HciProtocol {
 public:
  H4DataChannelPacketizer(std::shared_ptr<AsyncDataChannel> socket,
                          PacketReadCallback command_cb,
@@ -39,7 +40,7 @@ class H4DataChannelPacketizer {
                          PacketReadCallback iso_cb,
                          ClientDisconnectCallback disconnect_cb);

  size_t Send(uint8_t type, const uint8_t* data, size_t length);
  size_t Send(uint8_t type, const uint8_t* data, size_t length) override;

  void OnDataReady(std::shared_ptr<AsyncDataChannel> socket);

+92 −0
Original line number Diff line number Diff line
//
// Copyright 2017 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_packetizer.h"

#include <dlfcn.h>
#include <fcntl.h>
#include <sys/uio.h>
#include <unistd.h>

#include <cerrno>

#include "log.h"

namespace rootcanal {

H4Packetizer::H4Packetizer(int fd, PacketReadCallback command_cb,
                           PacketReadCallback event_cb,
                           PacketReadCallback acl_cb, PacketReadCallback sco_cb,
                           PacketReadCallback iso_cb,
                           ClientDisconnectCallback disconnect_cb)
    : uart_fd_(fd),
      h4_parser_(command_cb, event_cb, acl_cb, sco_cb, iso_cb),
      disconnect_cb_(std::move(disconnect_cb)) {}

size_t H4Packetizer::Send(uint8_t type, const uint8_t* data, size_t length) {
  struct iovec iov[] = {{&type, sizeof(type)},
                        {const_cast<uint8_t*>(data), length}};
  ssize_t ret = 0;
  do {
    ret = writev(uart_fd_, iov, sizeof(iov) / sizeof(iov[0]));
  } while (-1 == ret && (EINTR == errno || EAGAIN == errno));

  if (ret == -1) {
    LOG_ERROR("Error writing to UART (%s)", strerror(errno));
  } else if (ret < static_cast<ssize_t>(length + 1)) {
    LOG_ERROR("%d / %d bytes written - something went wrong...",
              static_cast<int>(ret), static_cast<int>(length + 1));
  }
  return ret;
}

void H4Packetizer::OnDataReady(int fd) {
  if (disconnected_) {
    return;
  }
  ssize_t bytes_to_read = h4_parser_.BytesRequested();
  std::vector<uint8_t> buffer(bytes_to_read);

  ssize_t bytes_read;
  do {
    bytes_read = read(fd, buffer.data(), bytes_to_read);
  } while (bytes_read == -1 && errno == EINTR);

  if (bytes_read == 0) {
    LOG_INFO("remote disconnected!");
    disconnected_ = true;
    disconnect_cb_();
    return;
  }
  if (bytes_read < 0) {
    if (errno == EAGAIN) {
      // No data, try again later.
      return;
    }
    if (errno == ECONNRESET) {
      // They probably rejected our packet
      disconnected_ = true;
      disconnect_cb_();
      return;
    }

    LOG_ALWAYS_FATAL("Read error in %d: %s", h4_parser_.CurrentState(),
                     strerror(errno));
  }
  h4_parser_.Consume(buffer.data(), bytes_read);
}

}  // namespace rootcanal
Loading