Loading system/gd/hal/hci_hal.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -101,6 +101,9 @@ public: // Get the MSFT opcode (as specified in Microsoft-defined Bluetooth HCI // Get the MSFT opcode (as specified in Microsoft-defined Bluetooth HCI // extensions) // extensions) virtual uint16_t getMsftOpcode() { return 0; } virtual uint16_t getMsftOpcode() { return 0; } // Mark the controller as broken to prevent further read / write operation. virtual void markControllerBroken() { return; } }; }; // LINT.ThenChange(fuzz/fuzz_hci_hal.h) // LINT.ThenChange(fuzz/fuzz_hci_hal.h) Loading system/gd/hal/hci_hal_host.cc +31 −7 Original line number Original line Diff line number Diff line Loading @@ -252,6 +252,9 @@ public: void sendHciCommand(HciPacket command) override { void sendHciCommand(HciPacket command) override { std::lock_guard<std::mutex> lock(api_mutex_); std::lock_guard<std::mutex> lock(api_mutex_); if (controller_broken_) { return; } log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD"); log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD"); std::vector<uint8_t> packet = std::move(command); std::vector<uint8_t> packet = std::move(command); btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, Loading @@ -262,6 +265,9 @@ public: void sendAclData(HciPacket data) override { void sendAclData(HciPacket data) override { std::lock_guard<std::mutex> lock(api_mutex_); std::lock_guard<std::mutex> lock(api_mutex_); if (controller_broken_) { return; } log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD"); log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD"); std::vector<uint8_t> packet = std::move(data); std::vector<uint8_t> packet = std::move(data); btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, Loading @@ -272,6 +278,10 @@ public: void sendScoData(HciPacket data) override { void sendScoData(HciPacket data) override { std::lock_guard<std::mutex> lock(api_mutex_); std::lock_guard<std::mutex> lock(api_mutex_); if (controller_broken_) { return; } log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD"); log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD"); std::vector<uint8_t> packet = std::move(data); std::vector<uint8_t> packet = std::move(data); btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, Loading @@ -282,6 +292,9 @@ public: void sendIsoData(HciPacket data) override { void sendIsoData(HciPacket data) override { std::lock_guard<std::mutex> lock(api_mutex_); std::lock_guard<std::mutex> lock(api_mutex_); if (controller_broken_) { return; } log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD"); log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD"); std::vector<uint8_t> packet = std::move(data); std::vector<uint8_t> packet = std::move(data); btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, Loading @@ -292,6 +305,15 @@ public: uint16_t getMsftOpcode() override { return Mgmt().get_vs_opcode(MGMT_VS_OPCODE_MSFT); } uint16_t getMsftOpcode() override { return Mgmt().get_vs_opcode(MGMT_VS_OPCODE_MSFT); } void markControllerBroken() override { std::lock_guard<std::mutex> lock(api_mutex_); if (controller_broken_) { log::error("Controller already marked as broken!"); return; } controller_broken_ = true; } protected: protected: void ListDependencies(ModuleList* list) const { void ListDependencies(ModuleList* list) const { list->add<LinkClocker>(); list->add<LinkClocker>(); Loading @@ -307,7 +329,7 @@ protected: // We don't want to crash when the chipset is broken. // We don't want to crash when the chipset is broken. if (sock_fd_ == INVALID_FD) { if (sock_fd_ == INVALID_FD) { log::error("Failed to connect to HCI socket. Aborting HAL initialization process."); log::error("Failed to connect to HCI socket. Aborting HAL initialization process."); raise(SIGINT); kill(getpid(), SIGTERM); return; return; } } Loading Loading @@ -357,6 +379,7 @@ private: std::queue<std::vector<uint8_t>> hci_outgoing_queue_; std::queue<std::vector<uint8_t>> hci_outgoing_queue_; SnoopLogger* btsnoop_logger_ = nullptr; SnoopLogger* btsnoop_logger_ = nullptr; LinkClocker* link_clocker_ = nullptr; LinkClocker* link_clocker_ = nullptr; bool controller_broken_ = false; void write_to_fd(HciPacket packet) { void write_to_fd(HciPacket packet) { // TODO: replace this with new queue when it's ready // TODO: replace this with new queue when it's ready Loading @@ -376,7 +399,9 @@ private: auto bytes_written = write(sock_fd_, (void*)packet_to_send.data(), packet_to_send.size()); auto bytes_written = write(sock_fd_, (void*)packet_to_send.data(), packet_to_send.size()); hci_outgoing_queue_.pop(); hci_outgoing_queue_.pop(); if (bytes_written == -1) { if (bytes_written == -1) { abort(); log::error("Can't write to socket: {}", strerror(errno)); markControllerBroken(); kill(getpid(), SIGTERM); } } if (hci_outgoing_queue_.empty()) { if (hci_outgoing_queue_.empty()) { hci_incoming_thread_.GetReactor()->ModifyRegistration(reactable_, hci_incoming_thread_.GetReactor()->ModifyRegistration(reactable_, Loading @@ -400,16 +425,15 @@ private: // we don't want crash when the chipset is broken. // we don't want crash when the chipset is broken. if (received_size == -1) { if (received_size == -1) { log::error("Can't receive from socket: {}", strerror(errno)); log::error("Can't receive from socket: {}", strerror(errno)); close(sock_fd_); markControllerBroken(); raise(SIGINT); kill(getpid(), SIGTERM); return; 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 markControllerBroken(); close(sock_fd_); kill(getpid(), SIGTERM); raise(SIGINT); return; return; } } Loading system/gd/hci/hci_layer.cc +4 −2 Original line number Original line Diff line number Diff line Loading @@ -465,10 +465,12 @@ struct HciLayer::impl { log::assert_that(event_view.IsValid(), "assert failed: event_view.IsValid()"); log::assert_that(event_view.IsValid(), "assert failed: event_view.IsValid()"); #ifdef TARGET_FLOSS #ifdef TARGET_FLOSS log::warn("Hardware Error Event with code 0x{:02x}", event_view.GetHardwareCode()); log::warn("Hardware Error Event with code 0x{:02x}", event_view.GetHardwareCode()); // Sending SIGINT to process the exception from BT controller. // Sending SIGTERM to process the exception from BT controller. // The Floss daemon will be restarted. HCI reset during restart will clear the // The Floss daemon will be restarted. HCI reset during restart will clear the // error state of the BT controller. // error state of the BT controller. kill(getpid(), SIGINT); auto hal = module_.GetDependency<hal::HciHal>(); hal->markControllerBroken(); kill(getpid(), SIGTERM); #else #else log::fatal("Hardware Error Event with code 0x{:02x}", event_view.GetHardwareCode()); log::fatal("Hardware Error Event with code 0x{:02x}", event_view.GetHardwareCode()); #endif #endif Loading system/gd/rust/linux/service/src/main.rs +0 −14 Original line number Original line Diff line number Diff line Loading @@ -262,15 +262,8 @@ fn main() -> Result<(), Box<dyn Error>> { 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_term).unwrap(); signal::sigaction(signal::SIGTERM, &sig_action_term).unwrap(); signal::sigaction(signal::SIGINT, &sig_action_int).unwrap(); } } } } Loading Loading @@ -318,10 +311,3 @@ 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); } Loading
system/gd/hal/hci_hal.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -101,6 +101,9 @@ public: // Get the MSFT opcode (as specified in Microsoft-defined Bluetooth HCI // Get the MSFT opcode (as specified in Microsoft-defined Bluetooth HCI // extensions) // extensions) virtual uint16_t getMsftOpcode() { return 0; } virtual uint16_t getMsftOpcode() { return 0; } // Mark the controller as broken to prevent further read / write operation. virtual void markControllerBroken() { return; } }; }; // LINT.ThenChange(fuzz/fuzz_hci_hal.h) // LINT.ThenChange(fuzz/fuzz_hci_hal.h) Loading
system/gd/hal/hci_hal_host.cc +31 −7 Original line number Original line Diff line number Diff line Loading @@ -252,6 +252,9 @@ public: void sendHciCommand(HciPacket command) override { void sendHciCommand(HciPacket command) override { std::lock_guard<std::mutex> lock(api_mutex_); std::lock_guard<std::mutex> lock(api_mutex_); if (controller_broken_) { return; } log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD"); log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD"); std::vector<uint8_t> packet = std::move(command); std::vector<uint8_t> packet = std::move(command); btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, Loading @@ -262,6 +265,9 @@ public: void sendAclData(HciPacket data) override { void sendAclData(HciPacket data) override { std::lock_guard<std::mutex> lock(api_mutex_); std::lock_guard<std::mutex> lock(api_mutex_); if (controller_broken_) { return; } log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD"); log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD"); std::vector<uint8_t> packet = std::move(data); std::vector<uint8_t> packet = std::move(data); btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, Loading @@ -272,6 +278,10 @@ public: void sendScoData(HciPacket data) override { void sendScoData(HciPacket data) override { std::lock_guard<std::mutex> lock(api_mutex_); std::lock_guard<std::mutex> lock(api_mutex_); if (controller_broken_) { return; } log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD"); log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD"); std::vector<uint8_t> packet = std::move(data); std::vector<uint8_t> packet = std::move(data); btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, Loading @@ -282,6 +292,9 @@ public: void sendIsoData(HciPacket data) override { void sendIsoData(HciPacket data) override { std::lock_guard<std::mutex> lock(api_mutex_); std::lock_guard<std::mutex> lock(api_mutex_); if (controller_broken_) { return; } log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD"); log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD"); std::vector<uint8_t> packet = std::move(data); std::vector<uint8_t> packet = std::move(data); btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, Loading @@ -292,6 +305,15 @@ public: uint16_t getMsftOpcode() override { return Mgmt().get_vs_opcode(MGMT_VS_OPCODE_MSFT); } uint16_t getMsftOpcode() override { return Mgmt().get_vs_opcode(MGMT_VS_OPCODE_MSFT); } void markControllerBroken() override { std::lock_guard<std::mutex> lock(api_mutex_); if (controller_broken_) { log::error("Controller already marked as broken!"); return; } controller_broken_ = true; } protected: protected: void ListDependencies(ModuleList* list) const { void ListDependencies(ModuleList* list) const { list->add<LinkClocker>(); list->add<LinkClocker>(); Loading @@ -307,7 +329,7 @@ protected: // We don't want to crash when the chipset is broken. // We don't want to crash when the chipset is broken. if (sock_fd_ == INVALID_FD) { if (sock_fd_ == INVALID_FD) { log::error("Failed to connect to HCI socket. Aborting HAL initialization process."); log::error("Failed to connect to HCI socket. Aborting HAL initialization process."); raise(SIGINT); kill(getpid(), SIGTERM); return; return; } } Loading Loading @@ -357,6 +379,7 @@ private: std::queue<std::vector<uint8_t>> hci_outgoing_queue_; std::queue<std::vector<uint8_t>> hci_outgoing_queue_; SnoopLogger* btsnoop_logger_ = nullptr; SnoopLogger* btsnoop_logger_ = nullptr; LinkClocker* link_clocker_ = nullptr; LinkClocker* link_clocker_ = nullptr; bool controller_broken_ = false; void write_to_fd(HciPacket packet) { void write_to_fd(HciPacket packet) { // TODO: replace this with new queue when it's ready // TODO: replace this with new queue when it's ready Loading @@ -376,7 +399,9 @@ private: auto bytes_written = write(sock_fd_, (void*)packet_to_send.data(), packet_to_send.size()); auto bytes_written = write(sock_fd_, (void*)packet_to_send.data(), packet_to_send.size()); hci_outgoing_queue_.pop(); hci_outgoing_queue_.pop(); if (bytes_written == -1) { if (bytes_written == -1) { abort(); log::error("Can't write to socket: {}", strerror(errno)); markControllerBroken(); kill(getpid(), SIGTERM); } } if (hci_outgoing_queue_.empty()) { if (hci_outgoing_queue_.empty()) { hci_incoming_thread_.GetReactor()->ModifyRegistration(reactable_, hci_incoming_thread_.GetReactor()->ModifyRegistration(reactable_, Loading @@ -400,16 +425,15 @@ private: // we don't want crash when the chipset is broken. // we don't want crash when the chipset is broken. if (received_size == -1) { if (received_size == -1) { log::error("Can't receive from socket: {}", strerror(errno)); log::error("Can't receive from socket: {}", strerror(errno)); close(sock_fd_); markControllerBroken(); raise(SIGINT); kill(getpid(), SIGTERM); return; 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 markControllerBroken(); close(sock_fd_); kill(getpid(), SIGTERM); raise(SIGINT); return; return; } } Loading
system/gd/hci/hci_layer.cc +4 −2 Original line number Original line Diff line number Diff line Loading @@ -465,10 +465,12 @@ struct HciLayer::impl { log::assert_that(event_view.IsValid(), "assert failed: event_view.IsValid()"); log::assert_that(event_view.IsValid(), "assert failed: event_view.IsValid()"); #ifdef TARGET_FLOSS #ifdef TARGET_FLOSS log::warn("Hardware Error Event with code 0x{:02x}", event_view.GetHardwareCode()); log::warn("Hardware Error Event with code 0x{:02x}", event_view.GetHardwareCode()); // Sending SIGINT to process the exception from BT controller. // Sending SIGTERM to process the exception from BT controller. // The Floss daemon will be restarted. HCI reset during restart will clear the // The Floss daemon will be restarted. HCI reset during restart will clear the // error state of the BT controller. // error state of the BT controller. kill(getpid(), SIGINT); auto hal = module_.GetDependency<hal::HciHal>(); hal->markControllerBroken(); kill(getpid(), SIGTERM); #else #else log::fatal("Hardware Error Event with code 0x{:02x}", event_view.GetHardwareCode()); log::fatal("Hardware Error Event with code 0x{:02x}", event_view.GetHardwareCode()); #endif #endif Loading
system/gd/rust/linux/service/src/main.rs +0 −14 Original line number Original line Diff line number Diff line Loading @@ -262,15 +262,8 @@ fn main() -> Result<(), Box<dyn Error>> { 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_term).unwrap(); signal::sigaction(signal::SIGTERM, &sig_action_term).unwrap(); signal::sigaction(signal::SIGINT, &sig_action_int).unwrap(); } } } } Loading Loading @@ -318,10 +311,3 @@ 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); }