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

Commit 9041d978 authored by Andre Eisenbach's avatar Andre Eisenbach Committed by Myles Watson
Browse files

bluetooth: Add initialization completed callback

Test: bluetooth_hidl_hal_test
Bug: 31972505
Change-Id: I64c19a7fe7299079c5daf74e7b238b0d71d65db2
parent ab16b319
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -35,12 +35,18 @@ interface IBluetoothHci {
     * required to communicate with the Bluetooth hardware in the
     * device.
     *
     * The |oninitializationComplete| callback must be invoked in response
     * to this function to indicate success before any other function
     * (sendHciCommand, sendAclData, * sendScoData) is invoked on this
     * interface.
     *
     * @param callback implements IBluetoothHciCallbacks which will
     *    receive callbacks when incoming HCI packets are received
     *    from the controller to be sent to the host.
     * @return status result of the initialization
     */
    initialize(IBluetoothHciCallbacks callback) generates (Status status);
    @entry
    @callflow(next={"sendHciCommand", "sendAclData", "sendScoData", "close"})
    initialize(IBluetoothHciCallbacks callback);

    /**
     * Send an HCI command (as specified in the Bluetooth Specification
@@ -49,6 +55,7 @@ interface IBluetoothHci {
     *
     * @param command is the HCI command to be sent
     */
    @callflow(next={"sendHciCommand", "sendAclData", "sendScoData", "close"})
    sendHciCommand(HciPacket command);

    /**
@@ -57,6 +64,7 @@ interface IBluetoothHci {
     * Packets must be processed in order.
     * @param data HCI data packet to be sent
     */
    @callflow(next={"sendHciCommand", "sendAclData", "sendScoData", "close"})
    sendAclData(HciPacket data);

    /**
@@ -65,10 +73,12 @@ interface IBluetoothHci {
     * Packets must be processed in order.
     * @param data HCI data packet to be sent
     */
    @callflow(next={"sendHciCommand", "sendAclData", "sendScoData", "close"})
    sendScoData(HciPacket data);

    /**
     * Close the HCI interface
     */
    @exit
    close();
};
+9 −3
Original line number Diff line number Diff line
@@ -18,22 +18,28 @@ package android.hardware.bluetooth@1.0;

/* The interface from the Bluetooth Controller to the stack. */
interface IBluetoothHciCallbacks {
    /**
     * Invoked when the Bluetooth controller initialization has been
     * completed.
     */
    initializationComplete(Status status);

    /**
     * This function is invoked when an HCI event is received from the
     * Bluetooth controller to be forwarded to the Bluetooth stack.
     * @param event is the HCI event to be sent to the Bluetooth stack.
     */
    oneway hciEventReceived(HciPacket event);
    hciEventReceived(HciPacket event);

    /**
     * Send an ACL data packet form the controller to the host.
     * @param data the ACL HCI packet to be passed to the host stack
     */
    oneway aclDataReceived(HciPacket data);
    aclDataReceived(HciPacket data);

    /**
     * Send a SCO data packet form the controller to the host.
     * @param data the SCO HCI packet to be passed to the host stack
     */
    oneway scoDataReceived(HciPacket data);
    scoDataReceived(HciPacket data);
};
+7 −4
Original line number Diff line number Diff line
@@ -30,12 +30,16 @@ static const uint8_t HCI_DATA_TYPE_COMMAND = 1;
static const uint8_t HCI_DATA_TYPE_ACL = 2;
static const uint8_t HCI_DATA_TYPE_SCO = 3;

Return<Status> BluetoothHci::initialize(
Return<void> BluetoothHci::initialize(
    const ::android::sp<IBluetoothHciCallbacks>& cb) {
  ALOGW("BluetoothHci::initialize()");
  event_cb_ = cb;

  bool rc = VendorInterface::Initialize(
      [this](bool status) {
        event_cb_->initializationComplete(
            status ? Status::SUCCESS : Status::INITIALIZATION_ERROR);
      },
      [this](HciPacketType type, const hidl_vec<uint8_t>& packet) {
        switch (type) {
          case HCI_PACKET_TYPE_EVENT:
@@ -52,9 +56,8 @@ Return<Status> BluetoothHci::initialize(
            break;
        }
      });
  if (!rc) return Status::INITIALIZATION_ERROR;

  return Status::SUCCESS;
  if (!rc) event_cb_->initializationComplete(Status::INITIALIZATION_ERROR);
  return Void();
}

Return<void> BluetoothHci::close() {
+1 −1
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ using ::android::hardware::hidl_vec;

class BluetoothHci : public IBluetoothHci {
 public:
  Return<Status> initialize(
  Return<void> initialize(
      const ::android::sp<IBluetoothHciCallbacks>& cb) override;
  Return<void> sendHciCommand(const hidl_vec<uint8_t>& packet) override;
  Return<void> sendAclData(const hidl_vec<uint8_t>& data) override;
+60 −51
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ static const int INVALID_FD = -1;
namespace {

using android::hardware::bluetooth::V1_0::implementation::VendorInterface;
using android::hardware::hidl_vec;

tINT_CMD_CBACK internal_command_cb;
VendorInterface* g_vendor_interface = nullptr;
@@ -46,17 +47,14 @@ const size_t packet_length_offset_for_type[] = {
    0, HCI_LENGTH_OFFSET_CMD, HCI_LENGTH_OFFSET_ACL, HCI_LENGTH_OFFSET_SCO,
    HCI_LENGTH_OFFSET_EVT};

size_t HciGetPacketLengthForType(
    HciPacketType type, const android::hardware::hidl_vec<uint8_t>& packet) {
size_t HciGetPacketLengthForType(HciPacketType type,
                                 const hidl_vec<uint8_t>& packet) {
  size_t offset = packet_length_offset_for_type[type];
  if (type == HCI_PACKET_TYPE_ACL_DATA) {
  if (type != HCI_PACKET_TYPE_ACL_DATA) return packet[offset];
  return (((packet[offset + 1]) << 8) | packet[offset]);
}
  return packet[offset];
}

HC_BT_HDR* WrapPacketAndCopy(uint16_t event,
                             const android::hardware::hidl_vec<uint8_t>& data) {
HC_BT_HDR* WrapPacketAndCopy(uint16_t event, const hidl_vec<uint8_t>& data) {
  size_t packet_size = data.size() + sizeof(HC_BT_HDR);
  HC_BT_HDR* packet = reinterpret_cast<HC_BT_HDR*>(new uint8_t[packet_size]);
  packet->offset = 0;
@@ -71,17 +69,16 @@ HC_BT_HDR* WrapPacketAndCopy(uint16_t event,

uint8_t transmit_cb(uint16_t opcode, void* buffer, tINT_CMD_CBACK callback) {
  ALOGV("%s opcode: 0x%04x, ptr: %p", __func__, opcode, buffer);
  HC_BT_HDR* bt_hdr = reinterpret_cast<HC_BT_HDR*>(buffer);

  internal_command_cb = callback;
  uint8_t type = HCI_PACKET_TYPE_COMMAND;
  VendorInterface::get()->SendPrivate(&type, 1);
  VendorInterface::get()->SendPrivate(bt_hdr->data, bt_hdr->len);
  VendorInterface::get()->Send(&type, 1);
  HC_BT_HDR* bt_hdr = reinterpret_cast<HC_BT_HDR*>(buffer);
  VendorInterface::get()->Send(bt_hdr->data, bt_hdr->len);
  return true;
}

void firmware_config_cb(bt_vendor_op_result_t result) {
  ALOGD("%s result: %d", __func__, result);
  ALOGV("%s result: %d", __func__, result);
  VendorInterface::get()->OnFirmwareConfigured(result);
}

@@ -131,10 +128,28 @@ namespace bluetooth {
namespace V1_0 {
namespace implementation {

bool VendorInterface::Initialize(PacketReadCallback packet_read_cb) {
class FirmwareStartupTimer {
 public:
  FirmwareStartupTimer() : start_time_(std::chrono::steady_clock::now()) {}

  ~FirmwareStartupTimer() {
    std::chrono::duration<double> duration =
        std::chrono::steady_clock::now() - start_time_;
    double s = duration.count();
    if (s == 0) return;
    ALOGD("Firmware configured in %.3fs", s);
  }

 private:
  std::chrono::steady_clock::time_point start_time_;
};

bool VendorInterface::Initialize(
    InitializeCompleteCallback initialize_complete_cb,
    PacketReadCallback packet_read_cb) {
  assert(!g_vendor_interface);
  g_vendor_interface = new VendorInterface();
  return g_vendor_interface->Open(packet_read_cb);
  return g_vendor_interface->Open(initialize_complete_cb, packet_read_cb);
}

void VendorInterface::Shutdown() {
@@ -146,8 +161,9 @@ void VendorInterface::Shutdown() {

VendorInterface* VendorInterface::get() { return g_vendor_interface; }

bool VendorInterface::Open(PacketReadCallback packet_read_cb) {
  firmware_configured_ = false;
bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb,
                           PacketReadCallback packet_read_cb) {
  initialize_complete_cb_ = initialize_complete_cb;
  packet_read_cb_ = packet_read_cb;

  // Initialize vendor interface
@@ -209,6 +225,7 @@ bool VendorInterface::Open(PacketReadCallback packet_read_cb) {
                                         [this](int fd) { OnDataReady(fd); });

  // Start configuring the firmware
  firmware_startup_timer_ = new FirmwareStartupTimer();
  lib_interface_->op(BT_VND_OP_FW_CFG, nullptr);

  return true;
@@ -229,31 +246,13 @@ void VendorInterface::Close() {
    lib_handle_ = nullptr;
  }

  firmware_configured_ = false;
  if (firmware_startup_timer_ != nullptr) {
    delete firmware_startup_timer_;
    firmware_startup_timer_ = nullptr;
  }

size_t VendorInterface::Send(const uint8_t* data, size_t length) {
  if (firmware_configured_ && queued_data_.size() == 0)
    return SendPrivate(data, length);

  if (!firmware_configured_) {
    ALOGI("%s queueing command", __func__);
    queued_data_.resize(queued_data_.size() + length);
    uint8_t* append_ptr = &queued_data_[queued_data_.size() - length];
    memcpy(append_ptr, data, length);
    return length;
  }

  ALOGI("%s sending queued command", __func__);
  SendPrivate(queued_data_.data(), queued_data_.size());
  queued_data_.resize(0);

  ALOGI("%s done sending queued command", __func__);

  return SendPrivate(data, length);
}

size_t VendorInterface::SendPrivate(const uint8_t* data, size_t length) {
size_t VendorInterface::Send(const uint8_t* data, size_t length) {
  if (uart_fd_ == INVALID_FD) return 0;

  size_t transmitted_length = 0;
@@ -280,9 +279,18 @@ size_t VendorInterface::SendPrivate(const uint8_t* data, size_t length) {
}

void VendorInterface::OnFirmwareConfigured(uint8_t result) {
  ALOGI("%s: result = %d", __func__, result);
  firmware_configured_ = true;
  VendorInterface::get()->Send(NULL, 0);
  ALOGD("%s result: %d", __func__, result);
  internal_command_cb = nullptr;

  if (firmware_startup_timer_ != nullptr) {
    delete firmware_startup_timer_;
    firmware_startup_timer_ = nullptr;
  }

  if (initialize_complete_cb_ != nullptr) {
    initialize_complete_cb_(result == 0);
    initialize_complete_cb_ = nullptr;
  }
}

void VendorInterface::OnDataReady(int fd) {
@@ -331,16 +339,17 @@ void VendorInterface::OnDataReady(int fd) {
      hci_packet_bytes_remaining_ -= bytes_read;
      hci_packet_bytes_read_ += bytes_read;
      if (hci_packet_bytes_remaining_ == 0) {
        if (firmware_configured_) {
          if (packet_read_cb_ != nullptr) {
            packet_read_cb_(hci_packet_type_, hci_packet_);
          }
        } else {
        if (internal_command_cb != nullptr) {
          HC_BT_HDR* bt_hdr =
              WrapPacketAndCopy(HCI_PACKET_TYPE_EVENT, hci_packet_);
          internal_command_cb(bt_hdr);
          }
        } else if (packet_read_cb_ != nullptr &&
                   initialize_complete_cb_ == nullptr) {
          packet_read_cb_(hci_packet_type_, hci_packet_);
        } else {
          ALOGE(
              "%s HCI_PAYLOAD received without packet_read_cb or pending init.",
              __func__);
        }
        hci_parser_state_ = HCI_IDLE;
      }
Loading