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

Commit beb13b45 authored by Myles Watson's avatar Myles Watson
Browse files

Bluetooth: Use AsyncFdWatcher for power management

Implement low power mode using timeouts from the interface.

Test: Boots, Bluetooth turns on/off,
      Instrumented bt_vendor library shows power management
      calls.
Change-Id: Ic4fcbb222f24b66c13f3797b14475d278c49fbc6
parent eba1312c
Loading
Loading
Loading
Loading
+47 −0
Original line number Original line Diff line number Diff line
@@ -44,6 +44,11 @@ struct {
  uint16_t opcode;
  uint16_t opcode;
} internal_command;
} internal_command;


// True when LPM is not enabled yet or wake is not asserted.
bool lpm_wake_deasserted;
uint32_t lpm_timeout_ms;
bool recent_activity_flag;

VendorInterface* g_vendor_interface = nullptr;
VendorInterface* g_vendor_interface = nullptr;


const size_t preamble_size_for_type[] = {
const size_t preamble_size_for_type[] = {
@@ -271,6 +276,9 @@ bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb,
  fd_watcher_.WatchFdForNonBlockingReads(uart_fd_,
  fd_watcher_.WatchFdForNonBlockingReads(uart_fd_,
                                         [this](int fd) { OnDataReady(fd); });
                                         [this](int fd) { OnDataReady(fd); });


  // Initially, the power management is off.
  lpm_wake_deasserted = false;

  // Start configuring the firmware
  // Start configuring the firmware
  firmware_startup_timer_ = new FirmwareStartupTimer();
  firmware_startup_timer_ = new FirmwareStartupTimer();
  lib_interface_->op(BT_VND_OP_FW_CFG, nullptr);
  lib_interface_->op(BT_VND_OP_FW_CFG, nullptr);
@@ -302,6 +310,19 @@ void VendorInterface::Close() {
size_t VendorInterface::Send(uint8_t type, const uint8_t* data, size_t length) {
size_t VendorInterface::Send(uint8_t type, const uint8_t* data, size_t length) {
  if (uart_fd_ == INVALID_FD) return 0;
  if (uart_fd_ == INVALID_FD) return 0;


  recent_activity_flag = true;

  if (lpm_wake_deasserted == true) {
    // Restart the timer.
    fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms),
                                 [this]() { OnTimeout(); });
    // Assert wake.
    lpm_wake_deasserted = false;
    bt_vendor_lpm_wake_state_t wakeState = BT_VND_LPM_WAKE_ASSERT;
    lib_interface_->op(BT_VND_OP_LPM_WAKE_SET_STATE, &wakeState);
    ALOGV("%s: Sent wake before (%02x)", __func__, data[0] | (data[1] << 8));
  }

  int rv = write_safely(uart_fd_, &type, sizeof(type));
  int rv = write_safely(uart_fd_, &type, sizeof(type));
  if (rv == sizeof(type))
  if (rv == sizeof(type))
    rv = write_safely(uart_fd_, data, length);
    rv = write_safely(uart_fd_, data, length);
@@ -321,6 +342,32 @@ void VendorInterface::OnFirmwareConfigured(uint8_t result) {
    initialize_complete_cb_(result == 0);
    initialize_complete_cb_(result == 0);
    initialize_complete_cb_ = nullptr;
    initialize_complete_cb_ = nullptr;
  }
  }

  lib_interface_->op(BT_VND_OP_GET_LPM_IDLE_TIMEOUT, &lpm_timeout_ms);
  ALOGI("%s: lpm_timeout_ms %d", __func__, lpm_timeout_ms);

  bt_vendor_lpm_mode_t mode = BT_VND_LPM_ENABLE;
  lib_interface_->op(BT_VND_OP_LPM_SET_MODE, &mode);

  ALOGD("%s Calling StartLowPowerWatchdog()", __func__);
  fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms),
                               [this]() { OnTimeout(); });

  bt_vendor_lpm_wake_state_t wakeState = BT_VND_LPM_WAKE_ASSERT;
  lib_interface_->op(BT_VND_OP_LPM_WAKE_SET_STATE, &wakeState);
}

void VendorInterface::OnTimeout() {
  ALOGV("%s", __func__);
  if (recent_activity_flag == false) {
    lpm_wake_deasserted = true;
    bt_vendor_lpm_wake_state_t wakeState = BT_VND_LPM_WAKE_DEASSERT;
    lib_interface_->op(BT_VND_OP_LPM_WAKE_SET_STATE, &wakeState);
    fd_watcher_.ConfigureTimeout(std::chrono::seconds(0), []() {
      ALOGE("Zero timeout! Should never happen.");
    });
  }
  recent_activity_flag = false;
}
}


void VendorInterface::OnDataReady(int fd) {
void VendorInterface::OnDataReady(int fd) {
+2 −0
Original line number Original line Diff line number Diff line
@@ -53,6 +53,8 @@ class VendorInterface {
            PacketReadCallback packet_read_cb);
            PacketReadCallback packet_read_cb);
  void Close();
  void Close();


  void OnTimeout();

  void OnDataReady(int fd);
  void OnDataReady(int fd);


  void *lib_handle_;
  void *lib_handle_;