system/bt
Revisión | 7e0b7d04688aafc192b579ba11868ee6bd0cf33c (tree) |
---|---|
Tiempo | 2019-12-20 01:47:01 |
Autor | TreeHugger Robot <treehugger-gerrit@goog...> |
Commiter | Android (Google) Code Review |
Merge "Handle BQR root inflammation event" into qt-qpr1-dev
@@ -67,6 +67,11 @@ static constexpr int8_t kCriWarnRssi = -80; | ||
67 | 67 | static constexpr uint8_t kCriWarnUnusedCh = 55; |
68 | 68 | // The queue size of recording the BQR events. |
69 | 69 | static constexpr uint8_t kBqrEventQueueSize = 25; |
70 | +// The minimum size of the ROOT_INFLAMMATION event | |
71 | +// HCI_VENDOR_SPECIFIC_EVT(1) + BQR sub event(1) + BQR report ID(1) + | |
72 | +// error code(1) + vendor error code(1) = 5 | |
73 | +static constexpr uint8_t kRootInflammationPacketMinSize = 5; | |
74 | + | |
70 | 75 | // The Property of BQR event mask configuration. |
71 | 76 | static constexpr const char* kpPropertyEventMask = |
72 | 77 | "persist.bluetooth.bqr.event_mask"; |
@@ -90,7 +95,8 @@ enum BqrQualityReportId : uint8_t { | ||
90 | 95 | QUALITY_REPORT_ID_MONITOR_MODE = 0x01, |
91 | 96 | QUALITY_REPORT_ID_APPROACH_LSTO = 0x02, |
92 | 97 | QUALITY_REPORT_ID_A2DP_AUDIO_CHOPPY = 0x03, |
93 | - QUALITY_REPORT_ID_SCO_VOICE_CHOPPY = 0x04 | |
98 | + QUALITY_REPORT_ID_SCO_VOICE_CHOPPY = 0x04, | |
99 | + QUALITY_REPORT_ID_ROOT_INFLAMMATION = 0x05 | |
94 | 100 | }; |
95 | 101 | |
96 | 102 | // Packet Type definition |
@@ -36,6 +36,7 @@ cc_library_static { | ||
36 | 36 | "system/bt/stack/include", |
37 | 37 | "system/bt/utils/include", |
38 | 38 | "system/bt/bta/include", |
39 | + "system/bt/btif/include", | |
39 | 40 | "system/libhwbinder/include", |
40 | 41 | ], |
41 | 42 | } |
@@ -36,10 +36,12 @@ | ||
36 | 36 | #include <mutex> |
37 | 37 | |
38 | 38 | #include "btcore/include/module.h" |
39 | +#include "btif/include/btif_bqr.h" | |
39 | 40 | #include "btsnoop.h" |
40 | 41 | #include "buffer_allocator.h" |
41 | 42 | #include "common/message_loop_thread.h" |
42 | 43 | #include "common/metrics.h" |
44 | +#include "common/once_timer.h" | |
43 | 45 | #include "hci_inject.h" |
44 | 46 | #include "hci_internals.h" |
45 | 47 | #include "hcidefs.h" |
@@ -54,6 +56,7 @@ | ||
54 | 56 | #define BT_HCI_TIMEOUT_TAG_NUM 1010000 |
55 | 57 | |
56 | 58 | using bluetooth::common::MessageLoopThread; |
59 | +using bluetooth::common::OnceTimer; | |
57 | 60 | |
58 | 61 | extern void hci_initialize(); |
59 | 62 | extern void hci_transmit(BT_HDR* packet); |
@@ -110,7 +113,7 @@ static std::queue<base::Closure> command_queue; | ||
110 | 113 | static alarm_t* command_response_timer; |
111 | 114 | static list_t* commands_pending_response; |
112 | 115 | static std::recursive_timed_mutex commands_pending_response_mutex; |
113 | -static alarm_t* hci_timeout_abort_timer; | |
116 | +static OnceTimer abort_timer; | |
114 | 117 | |
115 | 118 | // The hand-off point for data going to a higher layer, set by the higher layer |
116 | 119 | static base::Callback<void(const base::Location&, BT_HDR*)> send_data_upwards; |
@@ -160,6 +163,14 @@ void sco_data_received(BT_HDR* packet) { | ||
160 | 163 | packet_fragmenter->reassemble_and_dispatch(packet); |
161 | 164 | } |
162 | 165 | |
166 | +void hal_service_died() { | |
167 | + if (abort_timer.IsScheduled()) { | |
168 | + LOG(ERROR) << "abort_timer is scheduled, wait for timeout"; | |
169 | + return; | |
170 | + } | |
171 | + abort(); | |
172 | +} | |
173 | + | |
163 | 174 | // Module lifecycle functions |
164 | 175 | |
165 | 176 | static future_t* hci_module_shut_down(); |
@@ -258,12 +269,6 @@ static future_t* hci_module_shut_down() { | ||
258 | 269 | |
259 | 270 | packet_fragmenter->cleanup(); |
260 | 271 | |
261 | - // Clean up abort timer, if it exists. | |
262 | - if (hci_timeout_abort_timer != NULL) { | |
263 | - alarm_free(hci_timeout_abort_timer); | |
264 | - hci_timeout_abort_timer = NULL; | |
265 | - } | |
266 | - | |
267 | 272 | if (hci_firmware_log_fd != INVALID_FD) { |
268 | 273 | hci_close_firmware_log_file(hci_firmware_log_fd); |
269 | 274 | hci_firmware_log_fd = INVALID_FD; |
@@ -436,7 +441,7 @@ static void fragmenter_transmit_finished(BT_HDR* packet, | ||
436 | 441 | } |
437 | 442 | |
438 | 443 | // Abort. The chip has had time to write any debugging information. |
439 | -static void hci_timeout_abort(void* unused_data) { | |
444 | +static void hci_timeout_abort(void) { | |
440 | 445 | LOG_ERROR(LOG_TAG, "%s restarting the Bluetooth process.", __func__); |
441 | 446 | hci_close_firmware_log_file(hci_firmware_log_fd); |
442 | 447 |
@@ -445,6 +450,12 @@ static void hci_timeout_abort(void* unused_data) { | ||
445 | 450 | abort(); |
446 | 451 | } |
447 | 452 | |
453 | +static void hci_root_inflamed_abort(uint8_t error_code, | |
454 | + uint8_t vendor_error_code) { | |
455 | + LOG(FATAL) << __func__ << ": error_code = " << std::to_string(error_code) | |
456 | + << ", vendor_error_code = " << std::to_string(vendor_error_code); | |
457 | +} | |
458 | + | |
448 | 459 | static void command_timed_out_log_info(void* original_wait_entry) { |
449 | 460 | LOG_ERROR(LOG_TAG, "%s: %d commands pending response", __func__, |
450 | 461 | get_num_waiting_commands()); |
@@ -494,7 +505,7 @@ static void command_timed_out(void* original_wait_entry) { | ||
494 | 505 | } |
495 | 506 | |
496 | 507 | // Don't request a firmware dump for multiple hci timeouts |
497 | - if (hci_timeout_abort_timer != NULL || hci_firmware_log_fd != INVALID_FD) { | |
508 | + if (hci_firmware_log_fd != INVALID_FD) { | |
498 | 509 | return; |
499 | 510 | } |
500 | 511 |
@@ -521,13 +532,13 @@ static void command_timed_out(void* original_wait_entry) { | ||
521 | 532 | osi_free(bt_hdr); |
522 | 533 | LOG_ERROR(LOG_TAG, "%s: Setting a timer to restart.", __func__); |
523 | 534 | |
524 | - hci_timeout_abort_timer = alarm_new("hci.hci_timeout_aborter"); | |
525 | - if (!hci_timeout_abort_timer) { | |
535 | + // alarm_default_callbacks thread post to hci_thread. | |
536 | + if (!abort_timer.Schedule( | |
537 | + hci_thread.GetWeakPtr(), FROM_HERE, base::Bind(hci_timeout_abort), | |
538 | + base::TimeDelta::FromMilliseconds(COMMAND_TIMEOUT_RESTART_MS))) { | |
526 | 539 | LOG_ERROR(LOG_TAG, "%s unable to create an abort timer.", __func__); |
527 | 540 | abort(); |
528 | 541 | } |
529 | - alarm_set(hci_timeout_abort_timer, COMMAND_TIMEOUT_RESTART_MS, | |
530 | - hci_timeout_abort, nullptr); | |
531 | 542 | } |
532 | 543 | |
533 | 544 | // Event/packet receiving functions |
@@ -614,15 +625,62 @@ static bool filter_incoming_event(BT_HDR* packet) { | ||
614 | 625 | } |
615 | 626 | |
616 | 627 | goto intercepted; |
617 | - } else if (event_code == HCI_VSE_SUBCODE_DEBUG_INFO_SUB_EVT) { | |
618 | - if (hci_firmware_log_fd == INVALID_FD) | |
619 | - hci_firmware_log_fd = hci_open_firmware_log_file(); | |
628 | + } else if (event_code == HCI_VENDOR_SPECIFIC_EVT) { | |
629 | + uint8_t sub_event_code; | |
630 | + STREAM_TO_UINT8(sub_event_code, stream); | |
620 | 631 | |
621 | - if (hci_firmware_log_fd != INVALID_FD) | |
622 | - hci_log_firmware_debug_packet(hci_firmware_log_fd, packet); | |
632 | + if (sub_event_code == HCI_VSE_SUBCODE_DEBUG_INFO_SUB_EVT) { | |
633 | + if (hci_firmware_log_fd == INVALID_FD) | |
634 | + hci_firmware_log_fd = hci_open_firmware_log_file(); | |
623 | 635 | |
624 | - buffer_allocator->free(packet); | |
625 | - return true; | |
636 | + if (hci_firmware_log_fd != INVALID_FD) | |
637 | + hci_log_firmware_debug_packet(hci_firmware_log_fd, packet); | |
638 | + | |
639 | + buffer_allocator->free(packet); | |
640 | + return true; | |
641 | + } else if (sub_event_code == HCI_VSE_SUBCODE_BQR_SUB_EVT) { | |
642 | + uint8_t bqr_report_id; | |
643 | + STREAM_TO_UINT8(bqr_report_id, stream); | |
644 | + | |
645 | + if (bqr_report_id == | |
646 | + bluetooth::bqr::QUALITY_REPORT_ID_ROOT_INFLAMMATION && | |
647 | + packet->len >= bluetooth::bqr::kRootInflammationPacketMinSize) { | |
648 | + uint8_t error_code; | |
649 | + uint8_t vendor_error_code; | |
650 | + STREAM_TO_UINT8(error_code, stream); | |
651 | + STREAM_TO_UINT8(vendor_error_code, stream); | |
652 | + // TODO(ugoyu) Report to bluetooth metrics here | |
653 | + | |
654 | + LOG(ERROR) << __func__ | |
655 | + << ": Root inflammation event! setting timer to restart."; | |
656 | + { | |
657 | + // Try to stop hci command and startup timers | |
658 | + std::unique_lock<std::recursive_timed_mutex> lock( | |
659 | + commands_pending_response_mutex, std::defer_lock); | |
660 | + if (lock.try_lock_for(std::chrono::milliseconds( | |
661 | + COMMAND_PENDING_MUTEX_ACQUIRE_TIMEOUT_MS))) { | |
662 | + if (alarm_is_scheduled(startup_timer)) { | |
663 | + alarm_cancel(startup_timer); | |
664 | + } | |
665 | + if (alarm_is_scheduled(command_response_timer)) { | |
666 | + alarm_cancel(command_response_timer); | |
667 | + } | |
668 | + } else { | |
669 | + LOG(ERROR) << __func__ << ": Failed to obtain mutex"; | |
670 | + } | |
671 | + } | |
672 | + | |
673 | + // HwBinder thread post to hci_thread | |
674 | + if (!abort_timer.Schedule(hci_thread.GetWeakPtr(), FROM_HERE, | |
675 | + base::Bind(hci_root_inflamed_abort, | |
676 | + error_code, vendor_error_code), | |
677 | + base::TimeDelta::FromMilliseconds( | |
678 | + COMMAND_TIMEOUT_RESTART_MS))) { | |
679 | + LOG(ERROR) << "Failed to schedule abort_timer!"; | |
680 | + hci_root_inflamed_abort(error_code, vendor_error_code); | |
681 | + } | |
682 | + } | |
683 | + } | |
626 | 684 | } |
627 | 685 | |
628 | 686 | return false; |
@@ -51,6 +51,7 @@ extern void initialization_complete(); | ||
51 | 51 | extern void hci_event_received(const base::Location& from_here, BT_HDR* packet); |
52 | 52 | extern void acl_event_received(BT_HDR* packet); |
53 | 53 | extern void sco_data_received(BT_HDR* packet); |
54 | +extern void hal_service_died(); | |
54 | 55 | |
55 | 56 | android::sp<IBluetoothHci> btHci; |
56 | 57 |
@@ -58,7 +59,7 @@ class BluetoothHciDeathRecipient : public hidl_death_recipient { | ||
58 | 59 | public: |
59 | 60 | virtual void serviceDied(uint64_t /*cookie*/, const android::wp<::android::hidl::base::V1_0::IBase>& /*who*/) { |
60 | 61 | LOG_ERROR(LOG_TAG, "Bluetooth HAL service died!"); |
61 | - abort(); | |
62 | + hal_service_died(); | |
62 | 63 | } |
63 | 64 | }; |
64 | 65 | android::sp<BluetoothHciDeathRecipient> bluetoothHciDeathRecipient = new BluetoothHciDeathRecipient(); |