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

Commit df4e08f2 authored by howardchung's avatar howardchung Committed by Yun-Hao Chung
Browse files

Floss: Don't crash when chipset is broken

There are a few known issues in some chipsets of ChromeOS which would
break some assertion in HAL randomly. This CL removes those assertion
for Floss and make btadapterd catch the raise.

Bug: 287570078
Bug: 227395826
Tag: #floss
Test: enable Floss and then run 'rmmod btusb'. make sure there is no
crash.
Test: run usbreset and verify btadapterd can be restarted and there is
no crash.
Test: mma -j32

Change-Id: I6de4187cab0994eca771bc6ad546b8373d546f97
parent 818bd8ce
Loading
Loading
Loading
Loading
+20 −2
Original line number Original line Diff line number Diff line
@@ -162,6 +162,9 @@ int waitHciDev(int hci_interface) {
              break;
              break;
            }
            }
          }
          }

          // Chipset might be lost. Wait for index added event.
          LOG_ERROR("HCI interface(%d) not found in the MGMT lndex list", hci_interface);
        } else {
        } else {
          // Unlikely event (probably developer error or driver shut down).
          // Unlikely event (probably developer error or driver shut down).
          LOG_ERROR("Failed to read index list: status(%d)", cc->status);
          LOG_ERROR("Failed to read index list: status(%d)", cc->status);
@@ -289,7 +292,14 @@ class HciHalHost : public HciHal {
    std::lock_guard<std::mutex> lock(api_mutex_);
    std::lock_guard<std::mutex> lock(api_mutex_);
    ASSERT(sock_fd_ == INVALID_FD);
    ASSERT(sock_fd_ == INVALID_FD);
    sock_fd_ = ConnectToSocket();
    sock_fd_ = ConnectToSocket();
    ASSERT(sock_fd_ != INVALID_FD);

    // We don't want to crash when the chipset is broken.
    if (sock_fd_ == INVALID_FD) {
      LOG_ERROR("Failed to connect to HCI socket. Aborting HAL initialization process.");
      raise(SIGINT);
      return;
    }

    reactable_ = hci_incoming_thread_.GetReactor()->Register(
    reactable_ = hci_incoming_thread_.GetReactor()->Register(
        sock_fd_,
        sock_fd_,
        common::Bind(&HciHalHost::incoming_packet_received, common::Unretained(this)),
        common::Bind(&HciHalHost::incoming_packet_received, common::Unretained(this)),
@@ -370,7 +380,15 @@ class HciHalHost : public HciHal {


    ssize_t received_size;
    ssize_t received_size;
    RUN_NO_INTR(received_size = read(sock_fd_, buf, kBufSize));
    RUN_NO_INTR(received_size = read(sock_fd_, buf, kBufSize));
    ASSERT_LOG(received_size != -1, "Can't receive from socket: %s", strerror(errno));

    // we don't want crash when the chipset is broken.
    if (received_size == -1) {
      LOG_ERROR("Can't receive from socket: %s", strerror(errno));
      close(sock_fd_);
      raise(SIGINT);
      return;
    }

    if (received_size == 0) {
    if (received_size == 0) {
      LOG_WARN("Can't read H4 header. EOF received");
      LOG_WARN("Can't read H4 header. EOF received");
      // First close sock fd before raising sigint
      // First close sock fd before raising sigint
+16 −2
Original line number Original line Diff line number Diff line
@@ -412,14 +412,21 @@ fn main() -> Result<(), Box<dyn Error>> {
            // Install SIGTERM handler so that we can properly shutdown
            // Install SIGTERM handler so that we can properly shutdown
            *SIG_DATA.lock().unwrap() = Some((tx.clone(), sig_notifier.clone()));
            *SIG_DATA.lock().unwrap() = Some((tx.clone(), sig_notifier.clone()));


            let sig_action = signal::SigAction::new(
            let sig_action_term = signal::SigAction::new(
                signal::SigHandler::Handler(handle_sigterm),
                signal::SigHandler::Handler(handle_sigterm),
                signal::SaFlags::empty(),
                signal::SaFlags::empty(),
                signal::SigSet::empty(),
                signal::SigSet::empty(),
            );
            );


            let sig_action_int = signal::SigAction::new(
                signal::SigHandler::Handler(handle_sigint),
                signal::SaFlags::empty(),
                signal::SigSet::empty(),
            );

            unsafe {
            unsafe {
                signal::sigaction(signal::SIGTERM, &sig_action).unwrap();
                signal::sigaction(signal::SIGTERM, &sig_action_term).unwrap();
                signal::sigaction(signal::SIGINT, &sig_action_int).unwrap();
            }
            }
        }
        }


@@ -467,3 +474,10 @@ extern "C" fn handle_sigterm(_signum: i32) {
    log::debug!("Sigterm completed");
    log::debug!("Sigterm completed");
    std::process::exit(0);
    std::process::exit(0);
}
}

extern "C" fn handle_sigint(_signum: i32) {
    // Assumed this is from HAL Host, which is likely caused by chipset error.
    // In this case, don't crash the daemon and don't try to power off the adapter.
    log::debug!("Sigint completed");
    std::process::exit(0);
}