Loading system/btif/include/btif_bqr.h +7 −1 Original line number Diff line number Diff line Loading @@ -67,6 +67,11 @@ static constexpr int8_t kCriWarnRssi = -80; static constexpr uint8_t kCriWarnUnusedCh = 55; // The queue size of recording the BQR events. static constexpr uint8_t kBqrEventQueueSize = 25; // The minimum size of the ROOT_INFLAMMATION event // HCI_VENDOR_SPECIFIC_EVT(1) + BQR sub event(1) + BQR report ID(1) + // error code(1) + vendor error code(1) = 5 static constexpr uint8_t kRootInflammationPacketMinSize = 5; // The Property of BQR event mask configuration. static constexpr const char* kpPropertyEventMask = "persist.bluetooth.bqr.event_mask"; Loading @@ -90,7 +95,8 @@ enum BqrQualityReportId : uint8_t { QUALITY_REPORT_ID_MONITOR_MODE = 0x01, QUALITY_REPORT_ID_APPROACH_LSTO = 0x02, QUALITY_REPORT_ID_A2DP_AUDIO_CHOPPY = 0x03, QUALITY_REPORT_ID_SCO_VOICE_CHOPPY = 0x04 QUALITY_REPORT_ID_SCO_VOICE_CHOPPY = 0x04, QUALITY_REPORT_ID_ROOT_INFLAMMATION = 0x05 }; // Packet Type definition Loading system/hci/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ cc_library_static { "packages/modules/Bluetooth/system/stack/include", "packages/modules/Bluetooth/system/utils/include", "packages/modules/Bluetooth/system/bta/include", "packages/modules/Bluetooth/system/btif/include", "system/libhwbinder/include", ], } Loading system/hci/src/hci_layer.cc +78 −20 Original line number Diff line number Diff line Loading @@ -36,10 +36,12 @@ #include <mutex> #include "btcore/include/module.h" #include "btif/include/btif_bqr.h" #include "btsnoop.h" #include "buffer_allocator.h" #include "common/message_loop_thread.h" #include "common/metrics.h" #include "common/once_timer.h" #include "hci_inject.h" #include "hci_internals.h" #include "hcidefs.h" Loading @@ -55,6 +57,7 @@ #define BT_HCI_TIMEOUT_TAG_NUM 1010000 using bluetooth::common::MessageLoopThread; using bluetooth::common::OnceTimer; extern void hci_initialize(); extern void hci_transmit(BT_HDR* packet); Loading Loading @@ -111,7 +114,7 @@ static std::queue<base::Closure> command_queue; static alarm_t* command_response_timer; static list_t* commands_pending_response; static std::recursive_timed_mutex commands_pending_response_mutex; static alarm_t* hci_timeout_abort_timer; static OnceTimer abort_timer; // The hand-off point for data going to a higher layer, set by the higher layer static base::Callback<void(const base::Location&, BT_HDR*)> send_data_upwards; Loading Loading @@ -166,6 +169,14 @@ void iso_data_received(BT_HDR* packet) { packet_fragmenter->reassemble_and_dispatch(packet); } void hal_service_died() { if (abort_timer.IsScheduled()) { LOG(ERROR) << "abort_timer is scheduled, wait for timeout"; return; } abort(); } // Module lifecycle functions static future_t* hci_module_shut_down(); Loading Loading @@ -264,12 +275,6 @@ static future_t* hci_module_shut_down() { packet_fragmenter->cleanup(); // Clean up abort timer, if it exists. if (hci_timeout_abort_timer != NULL) { alarm_free(hci_timeout_abort_timer); hci_timeout_abort_timer = NULL; } if (hci_firmware_log_fd != INVALID_FD) { hci_close_firmware_log_file(hci_firmware_log_fd); hci_firmware_log_fd = INVALID_FD; Loading Loading @@ -442,7 +447,7 @@ static void fragmenter_transmit_finished(BT_HDR* packet, } // Abort. The chip has had time to write any debugging information. static void hci_timeout_abort(void* unused_data) { static void hci_timeout_abort(void) { LOG_ERROR(LOG_TAG, "%s restarting the Bluetooth process.", __func__); hci_close_firmware_log_file(hci_firmware_log_fd); Loading @@ -451,6 +456,12 @@ static void hci_timeout_abort(void* unused_data) { abort(); } static void hci_root_inflamed_abort(uint8_t error_code, uint8_t vendor_error_code) { LOG(FATAL) << __func__ << ": error_code = " << std::to_string(error_code) << ", vendor_error_code = " << std::to_string(vendor_error_code); } static void command_timed_out_log_info(void* original_wait_entry) { LOG_ERROR(LOG_TAG, "%s: %d commands pending response", __func__, get_num_waiting_commands()); Loading Loading @@ -500,7 +511,7 @@ static void command_timed_out(void* original_wait_entry) { } // Don't request a firmware dump for multiple hci timeouts if (hci_timeout_abort_timer != NULL || hci_firmware_log_fd != INVALID_FD) { if (hci_firmware_log_fd != INVALID_FD) { return; } Loading @@ -526,13 +537,13 @@ static void command_timed_out(void* original_wait_entry) { osi_free(bt_hdr); LOG_ERROR(LOG_TAG, "%s: Setting a timer to restart.", __func__); hci_timeout_abort_timer = alarm_new("hci.hci_timeout_aborter"); if (!hci_timeout_abort_timer) { // alarm_default_callbacks thread post to hci_thread. if (!abort_timer.Schedule( hci_thread.GetWeakPtr(), FROM_HERE, base::Bind(hci_timeout_abort), base::TimeDelta::FromMilliseconds(COMMAND_TIMEOUT_RESTART_MS))) { LOG_ERROR(LOG_TAG, "%s unable to create an abort timer.", __func__); abort(); } alarm_set(hci_timeout_abort_timer, COMMAND_TIMEOUT_RESTART_MS, hci_timeout_abort, nullptr); } // Event/packet receiving functions Loading Loading @@ -619,7 +630,11 @@ static bool filter_incoming_event(BT_HDR* packet) { } goto intercepted; } else if (event_code == HCI_VSE_SUBCODE_DEBUG_INFO_SUB_EVT) { } else if (event_code == HCI_VENDOR_SPECIFIC_EVT) { uint8_t sub_event_code; STREAM_TO_UINT8(sub_event_code, stream); if (sub_event_code == HCI_VSE_SUBCODE_DEBUG_INFO_SUB_EVT) { if (hci_firmware_log_fd == INVALID_FD) hci_firmware_log_fd = hci_open_firmware_log_file(); Loading @@ -628,6 +643,49 @@ static bool filter_incoming_event(BT_HDR* packet) { buffer_allocator->free(packet); return true; } else if (sub_event_code == HCI_VSE_SUBCODE_BQR_SUB_EVT) { uint8_t bqr_report_id; STREAM_TO_UINT8(bqr_report_id, stream); if (bqr_report_id == bluetooth::bqr::QUALITY_REPORT_ID_ROOT_INFLAMMATION && packet->len >= bluetooth::bqr::kRootInflammationPacketMinSize) { uint8_t error_code; uint8_t vendor_error_code; STREAM_TO_UINT8(error_code, stream); STREAM_TO_UINT8(vendor_error_code, stream); // TODO(ugoyu) Report to bluetooth metrics here LOG(ERROR) << __func__ << ": Root inflammation event! setting timer to restart."; { // Try to stop hci command and startup timers std::unique_lock<std::recursive_timed_mutex> lock( commands_pending_response_mutex, std::defer_lock); if (lock.try_lock_for(std::chrono::milliseconds( COMMAND_PENDING_MUTEX_ACQUIRE_TIMEOUT_MS))) { if (alarm_is_scheduled(startup_timer)) { alarm_cancel(startup_timer); } if (alarm_is_scheduled(command_response_timer)) { alarm_cancel(command_response_timer); } } else { LOG(ERROR) << __func__ << ": Failed to obtain mutex"; } } // HwBinder thread post to hci_thread if (!abort_timer.Schedule(hci_thread.GetWeakPtr(), FROM_HERE, base::Bind(hci_root_inflamed_abort, error_code, vendor_error_code), base::TimeDelta::FromMilliseconds( COMMAND_TIMEOUT_RESTART_MS))) { LOG(ERROR) << "Failed to schedule abort_timer!"; hci_root_inflamed_abort(error_code, vendor_error_code); } } } } return false; Loading system/hci/src/hci_layer_android.cc +2 −1 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ extern void hci_event_received(const base::Location& from_here, BT_HDR* packet); extern void acl_event_received(BT_HDR* packet); extern void sco_data_received(BT_HDR* packet); extern void iso_data_received(BT_HDR* packet); extern void hal_service_died(); android::sp<V1_0::IBluetoothHci> btHci; android::sp<V1_1::IBluetoothHci> btHci_1_1; Loading @@ -63,7 +64,7 @@ class BluetoothHciDeathRecipient : public hidl_death_recipient { public: virtual void serviceDied(uint64_t /*cookie*/, const android::wp<::android::hidl::base::V1_0::IBase>& /*who*/) { LOG_ERROR(LOG_TAG, "Bluetooth HAL service died!"); abort(); hal_service_died(); } }; android::sp<BluetoothHciDeathRecipient> bluetoothHciDeathRecipient = new BluetoothHciDeathRecipient(); Loading Loading
system/btif/include/btif_bqr.h +7 −1 Original line number Diff line number Diff line Loading @@ -67,6 +67,11 @@ static constexpr int8_t kCriWarnRssi = -80; static constexpr uint8_t kCriWarnUnusedCh = 55; // The queue size of recording the BQR events. static constexpr uint8_t kBqrEventQueueSize = 25; // The minimum size of the ROOT_INFLAMMATION event // HCI_VENDOR_SPECIFIC_EVT(1) + BQR sub event(1) + BQR report ID(1) + // error code(1) + vendor error code(1) = 5 static constexpr uint8_t kRootInflammationPacketMinSize = 5; // The Property of BQR event mask configuration. static constexpr const char* kpPropertyEventMask = "persist.bluetooth.bqr.event_mask"; Loading @@ -90,7 +95,8 @@ enum BqrQualityReportId : uint8_t { QUALITY_REPORT_ID_MONITOR_MODE = 0x01, QUALITY_REPORT_ID_APPROACH_LSTO = 0x02, QUALITY_REPORT_ID_A2DP_AUDIO_CHOPPY = 0x03, QUALITY_REPORT_ID_SCO_VOICE_CHOPPY = 0x04 QUALITY_REPORT_ID_SCO_VOICE_CHOPPY = 0x04, QUALITY_REPORT_ID_ROOT_INFLAMMATION = 0x05 }; // Packet Type definition Loading
system/hci/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ cc_library_static { "packages/modules/Bluetooth/system/stack/include", "packages/modules/Bluetooth/system/utils/include", "packages/modules/Bluetooth/system/bta/include", "packages/modules/Bluetooth/system/btif/include", "system/libhwbinder/include", ], } Loading
system/hci/src/hci_layer.cc +78 −20 Original line number Diff line number Diff line Loading @@ -36,10 +36,12 @@ #include <mutex> #include "btcore/include/module.h" #include "btif/include/btif_bqr.h" #include "btsnoop.h" #include "buffer_allocator.h" #include "common/message_loop_thread.h" #include "common/metrics.h" #include "common/once_timer.h" #include "hci_inject.h" #include "hci_internals.h" #include "hcidefs.h" Loading @@ -55,6 +57,7 @@ #define BT_HCI_TIMEOUT_TAG_NUM 1010000 using bluetooth::common::MessageLoopThread; using bluetooth::common::OnceTimer; extern void hci_initialize(); extern void hci_transmit(BT_HDR* packet); Loading Loading @@ -111,7 +114,7 @@ static std::queue<base::Closure> command_queue; static alarm_t* command_response_timer; static list_t* commands_pending_response; static std::recursive_timed_mutex commands_pending_response_mutex; static alarm_t* hci_timeout_abort_timer; static OnceTimer abort_timer; // The hand-off point for data going to a higher layer, set by the higher layer static base::Callback<void(const base::Location&, BT_HDR*)> send_data_upwards; Loading Loading @@ -166,6 +169,14 @@ void iso_data_received(BT_HDR* packet) { packet_fragmenter->reassemble_and_dispatch(packet); } void hal_service_died() { if (abort_timer.IsScheduled()) { LOG(ERROR) << "abort_timer is scheduled, wait for timeout"; return; } abort(); } // Module lifecycle functions static future_t* hci_module_shut_down(); Loading Loading @@ -264,12 +275,6 @@ static future_t* hci_module_shut_down() { packet_fragmenter->cleanup(); // Clean up abort timer, if it exists. if (hci_timeout_abort_timer != NULL) { alarm_free(hci_timeout_abort_timer); hci_timeout_abort_timer = NULL; } if (hci_firmware_log_fd != INVALID_FD) { hci_close_firmware_log_file(hci_firmware_log_fd); hci_firmware_log_fd = INVALID_FD; Loading Loading @@ -442,7 +447,7 @@ static void fragmenter_transmit_finished(BT_HDR* packet, } // Abort. The chip has had time to write any debugging information. static void hci_timeout_abort(void* unused_data) { static void hci_timeout_abort(void) { LOG_ERROR(LOG_TAG, "%s restarting the Bluetooth process.", __func__); hci_close_firmware_log_file(hci_firmware_log_fd); Loading @@ -451,6 +456,12 @@ static void hci_timeout_abort(void* unused_data) { abort(); } static void hci_root_inflamed_abort(uint8_t error_code, uint8_t vendor_error_code) { LOG(FATAL) << __func__ << ": error_code = " << std::to_string(error_code) << ", vendor_error_code = " << std::to_string(vendor_error_code); } static void command_timed_out_log_info(void* original_wait_entry) { LOG_ERROR(LOG_TAG, "%s: %d commands pending response", __func__, get_num_waiting_commands()); Loading Loading @@ -500,7 +511,7 @@ static void command_timed_out(void* original_wait_entry) { } // Don't request a firmware dump for multiple hci timeouts if (hci_timeout_abort_timer != NULL || hci_firmware_log_fd != INVALID_FD) { if (hci_firmware_log_fd != INVALID_FD) { return; } Loading @@ -526,13 +537,13 @@ static void command_timed_out(void* original_wait_entry) { osi_free(bt_hdr); LOG_ERROR(LOG_TAG, "%s: Setting a timer to restart.", __func__); hci_timeout_abort_timer = alarm_new("hci.hci_timeout_aborter"); if (!hci_timeout_abort_timer) { // alarm_default_callbacks thread post to hci_thread. if (!abort_timer.Schedule( hci_thread.GetWeakPtr(), FROM_HERE, base::Bind(hci_timeout_abort), base::TimeDelta::FromMilliseconds(COMMAND_TIMEOUT_RESTART_MS))) { LOG_ERROR(LOG_TAG, "%s unable to create an abort timer.", __func__); abort(); } alarm_set(hci_timeout_abort_timer, COMMAND_TIMEOUT_RESTART_MS, hci_timeout_abort, nullptr); } // Event/packet receiving functions Loading Loading @@ -619,7 +630,11 @@ static bool filter_incoming_event(BT_HDR* packet) { } goto intercepted; } else if (event_code == HCI_VSE_SUBCODE_DEBUG_INFO_SUB_EVT) { } else if (event_code == HCI_VENDOR_SPECIFIC_EVT) { uint8_t sub_event_code; STREAM_TO_UINT8(sub_event_code, stream); if (sub_event_code == HCI_VSE_SUBCODE_DEBUG_INFO_SUB_EVT) { if (hci_firmware_log_fd == INVALID_FD) hci_firmware_log_fd = hci_open_firmware_log_file(); Loading @@ -628,6 +643,49 @@ static bool filter_incoming_event(BT_HDR* packet) { buffer_allocator->free(packet); return true; } else if (sub_event_code == HCI_VSE_SUBCODE_BQR_SUB_EVT) { uint8_t bqr_report_id; STREAM_TO_UINT8(bqr_report_id, stream); if (bqr_report_id == bluetooth::bqr::QUALITY_REPORT_ID_ROOT_INFLAMMATION && packet->len >= bluetooth::bqr::kRootInflammationPacketMinSize) { uint8_t error_code; uint8_t vendor_error_code; STREAM_TO_UINT8(error_code, stream); STREAM_TO_UINT8(vendor_error_code, stream); // TODO(ugoyu) Report to bluetooth metrics here LOG(ERROR) << __func__ << ": Root inflammation event! setting timer to restart."; { // Try to stop hci command and startup timers std::unique_lock<std::recursive_timed_mutex> lock( commands_pending_response_mutex, std::defer_lock); if (lock.try_lock_for(std::chrono::milliseconds( COMMAND_PENDING_MUTEX_ACQUIRE_TIMEOUT_MS))) { if (alarm_is_scheduled(startup_timer)) { alarm_cancel(startup_timer); } if (alarm_is_scheduled(command_response_timer)) { alarm_cancel(command_response_timer); } } else { LOG(ERROR) << __func__ << ": Failed to obtain mutex"; } } // HwBinder thread post to hci_thread if (!abort_timer.Schedule(hci_thread.GetWeakPtr(), FROM_HERE, base::Bind(hci_root_inflamed_abort, error_code, vendor_error_code), base::TimeDelta::FromMilliseconds( COMMAND_TIMEOUT_RESTART_MS))) { LOG(ERROR) << "Failed to schedule abort_timer!"; hci_root_inflamed_abort(error_code, vendor_error_code); } } } } return false; Loading
system/hci/src/hci_layer_android.cc +2 −1 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ extern void hci_event_received(const base::Location& from_here, BT_HDR* packet); extern void acl_event_received(BT_HDR* packet); extern void sco_data_received(BT_HDR* packet); extern void iso_data_received(BT_HDR* packet); extern void hal_service_died(); android::sp<V1_0::IBluetoothHci> btHci; android::sp<V1_1::IBluetoothHci> btHci_1_1; Loading @@ -63,7 +64,7 @@ class BluetoothHciDeathRecipient : public hidl_death_recipient { public: virtual void serviceDied(uint64_t /*cookie*/, const android::wp<::android::hidl::base::V1_0::IBase>& /*who*/) { LOG_ERROR(LOG_TAG, "Bluetooth HAL service died!"); abort(); hal_service_died(); } }; android::sp<BluetoothHciDeathRecipient> bluetoothHciDeathRecipient = new BluetoothHciDeathRecipient(); Loading