From 685ec254e689929d6c79079e434b9be624c4d00f Mon Sep 17 00:00:00 2001
From: Matthias Ringwald <matthias@ringwald.ch>
Date: Thu, 4 Nov 2021 15:18:24 +0100
Subject: [PATCH] hcI: add 1000 ms watchdog that forces power off for
 hci_power_control(HCI_POWER_OFF)

---
 src/hci.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/hci.c b/src/hci.c
index b477b1985..315f1c975 100644
--- a/src/hci.c
+++ b/src/hci.c
@@ -152,6 +152,7 @@ static void gap_inquiry_explode(uint8_t *packet, uint16_t size);
 static int  hci_power_control_on(void);
 static void hci_power_control_off(void);
 static void hci_state_reset(void);
+static void hci_halting_timeout_handler(btstack_timer_source_t * ds);
 static void hci_emit_transport_packet_sent(void);
 static void hci_emit_disconnection_complete(hci_con_handle_t con_handle, uint8_t reason);
 static void hci_emit_nr_connections_changed(void);
@@ -3934,6 +3935,10 @@ static int hci_power_control_state_working(HCI_POWER_MODE power_mode) {
             // see hci_run
             hci_stack->state = HCI_STATE_HALTING;
             hci_stack->substate = HCI_HALTING_DISCONNECT_ALL_NO_TIMER;
+            // setup watchdog timer for disconnect - only triggers if Controller does not respond anymore
+            btstack_run_loop_set_timer(&hci_stack->timeout, 1000);
+            btstack_run_loop_set_timer_handler(&hci_stack->timeout, hci_halting_timeout_handler);
+            btstack_run_loop_add_timer(&hci_stack->timeout);
             break;
         case HCI_POWER_SLEEP:
             // see hci_run
@@ -5041,6 +5046,7 @@ static void hci_run(void){
                         // no connections left, wait a bit to assert that btstack_cyrpto isn't waiting for an HCI event
                         log_info("HCI_STATE_HALTING: wait 50 ms");
                         hci_stack->substate = HCI_HALTING_W4_TIMER;
+                        btstack_run_loop_remove_timer(&hci_stack->timeout);
                         btstack_run_loop_set_timer(&hci_stack->timeout, 50);
                         btstack_run_loop_set_timer_handler(&hci_stack->timeout, hci_halting_timeout_handler);
                         btstack_run_loop_add_timer(&hci_stack->timeout);
@@ -5050,6 +5056,9 @@ static void hci_run(void){
                     /* fall through */
 
                 case HCI_HALTING_CLOSE:
+                    // close left over connections (that had not been properly closed before)
+                    hci_discard_connections();
+
                     log_info("HCI_STATE_HALTING, calling off");
                     
                     // switch mode