// Abort if there is no response to an HCI command.
static const uint32_t COMMAND_PENDING_TIMEOUT_MS = 2000;
-static const uint32_t COMMAND_TIMEOUT_RESTART_US = 5000000;
+static const uint32_t COMMAND_TIMEOUT_RESTART_MS = 5000;
// Our interface
static bool interface_created;
static alarm_t* command_response_timer;
static list_t* commands_pending_response;
static std::recursive_mutex commands_pending_response_mutex;
+static alarm_t* hci_timeout_abort_timer;
// The hand-off point for data going to a higher layer, set by the higher layer
static base::Callback<void(const tracked_objects::Location&, BT_HDR*)>
thread_free(thread);
thread = NULL;
+ // 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;
+ }
+
return NULL;
}
}
}
+// Abort. The chip has had time to write any debugging information.
+static void hci_timeout_abort(void* unused_data) {
+ LOG_ERROR(LOG_TAG, "%s restarting the Bluetooth process.", __func__);
+ hci_close_firmware_log_file(hci_firmware_log_fd);
+
+ // We shouldn't try to recover the stack from this command timeout.
+ // If it's caused by a software bug, fix it. If it's a hardware bug, fix it.
+ abort();
+}
+
// Print debugging information and quit. Don't dereference original_wait_entry.
static void command_timed_out(void* original_wait_entry) {
std::unique_lock<std::recursive_mutex> lock(commands_pending_response_mutex);
}
lock.unlock();
+ // Don't request a firmware dump for multiple hci timeouts
+ if (hci_timeout_abort_timer != NULL || hci_firmware_log_fd != INVALID_FD) {
+ return;
+ }
+
LOG_ERROR(LOG_TAG, "%s: requesting a firmware dump.", __func__);
/* Allocate a buffer to hold the HCI command. */
transmit_fragment(bt_hdr, true);
osi_free(bt_hdr);
+ LOG_ERROR(LOG_TAG, "%s: Setting a timer to restart.", __func__);
- LOG_ERROR(LOG_TAG, "%s restarting the Bluetooth process.", __func__);
- usleep(COMMAND_TIMEOUT_RESTART_US);
- hci_close_firmware_log_file(hci_firmware_log_fd);
-
- // We shouldn't try to recover the stack from this command timeout.
- // If it's caused by a software bug, fix it. If it's a hardware bug, fix it.
- abort();
+ hci_timeout_abort_timer = alarm_new("hci.hci_timeout_aborter");
+ if (!hci_timeout_abort_timer) {
+ 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