hci: only pause during halting if hci_halting_defer is called after receiving BTSTACK_EVENT_STATE

This commit is contained in:
Matthias Ringwald 2019-02-05 16:24:35 +01:00
parent 26fe959261
commit beceedde07
2 changed files with 43 additions and 16 deletions

View File

@ -2976,7 +2976,7 @@ int hci_power_control(HCI_POWER_MODE power_mode){
case HCI_POWER_OFF: case HCI_POWER_OFF:
// see hci_run // see hci_run
hci_stack->state = HCI_STATE_HALTING; hci_stack->state = HCI_STATE_HALTING;
hci_stack->substate = HCI_HALTING_DISCONNECT_ALL; hci_stack->substate = HCI_HALTING_DISCONNECT_ALL_NO_TIMER;
break; break;
case HCI_POWER_SLEEP: case HCI_POWER_SLEEP:
// see hci_run // see hci_run
@ -3019,7 +3019,7 @@ int hci_power_control(HCI_POWER_MODE power_mode){
case HCI_POWER_OFF: case HCI_POWER_OFF:
// see hci_run // see hci_run
hci_stack->state = HCI_STATE_HALTING; hci_stack->state = HCI_STATE_HALTING;
hci_stack->substate = HCI_HALTING_DISCONNECT_ALL; hci_stack->substate = HCI_HALTING_DISCONNECT_ALL_NO_TIMER;
break; break;
case HCI_POWER_SLEEP: case HCI_POWER_SLEEP:
// do nothing // do nothing
@ -3046,7 +3046,7 @@ int hci_power_control(HCI_POWER_MODE power_mode){
break; break;
case HCI_POWER_OFF: case HCI_POWER_OFF:
hci_stack->state = HCI_STATE_HALTING; hci_stack->state = HCI_STATE_HALTING;
hci_stack->substate = HCI_HALTING_DISCONNECT_ALL; hci_stack->substate = HCI_HALTING_DISCONNECT_ALL_NO_TIMER;
break; break;
case HCI_POWER_SLEEP: case HCI_POWER_SLEEP:
// do nothing // do nothing
@ -3148,6 +3148,8 @@ static void hci_host_num_completed_packets(void){
static void hci_halting_timeout_handler(btstack_timer_source_t * ds){ static void hci_halting_timeout_handler(btstack_timer_source_t * ds){
UNUSED(ds); UNUSED(ds);
hci_stack->substate = HCI_HALTING_CLOSE; hci_stack->substate = HCI_HALTING_CLOSE;
// allow packet handlers to defer final shutdown
hci_emit_state();
hci_run(); hci_run();
} }
@ -3605,10 +3607,12 @@ static void hci_run(void){
log_info("HCI_STATE_HALTING, substate %x\n", hci_stack->substate); log_info("HCI_STATE_HALTING, substate %x\n", hci_stack->substate);
switch (hci_stack->substate){ switch (hci_stack->substate){
case HCI_HALTING_DISCONNECT_ALL: case HCI_HALTING_DISCONNECT_ALL_NO_TIMER:
// free whitelist entries case HCI_HALTING_DISCONNECT_ALL_TIMER:
#ifdef ENABLE_BLE #ifdef ENABLE_BLE
#ifdef ENABLE_LE_CENTRAL #ifdef ENABLE_LE_CENTRAL
// free whitelist entries
{ {
btstack_linked_list_iterator_t lit; btstack_linked_list_iterator_t lit;
btstack_linked_list_iterator_init(&lit, &hci_stack->le_whitelist); btstack_linked_list_iterator_init(&lit, &hci_stack->le_whitelist);
@ -3643,17 +3647,17 @@ static void hci_run(void){
return; return;
} }
// no connections left, wait a bit (500 ms) to assert that btstack_cyrpto isn't waiting for an HCI event if (hci_stack->substate == HCI_HALTING_DISCONNECT_ALL_TIMER){
log_info("HCI_STATE_HALTING: wait 500 ms"); // no connections left, wait a bit to assert that btstack_cyrpto isn't waiting for an HCI event
hci_stack->substate = HCI_HALTING_W4_TIMER; log_info("HCI_STATE_HALTING: wait 50 ms");
btstack_run_loop_set_timer(&hci_stack->timeout, 500); hci_stack->substate = HCI_HALTING_W4_TIMER;
btstack_run_loop_set_timer_handler(&hci_stack->timeout, hci_halting_timeout_handler); btstack_run_loop_set_timer(&hci_stack->timeout, 50);
btstack_run_loop_add_timer(&hci_stack->timeout); btstack_run_loop_set_timer_handler(&hci_stack->timeout, hci_halting_timeout_handler);
break; btstack_run_loop_add_timer(&hci_stack->timeout);
break;
}
case HCI_HALTING_W4_TIMER: /* explicit fall-through */
// keep waiting
break;
case HCI_HALTING_CLOSE: case HCI_HALTING_CLOSE:
log_info("HCI_STATE_HALTING, calling off"); log_info("HCI_STATE_HALTING, calling off");
@ -3665,6 +3669,11 @@ static void hci_run(void){
hci_emit_state(); hci_emit_state();
log_info("HCI_STATE_HALTING, done"); log_info("HCI_STATE_HALTING, done");
break; break;
case HCI_HALTING_W4_TIMER:
// keep waiting
break;
default: default:
break; break;
} }
@ -5025,3 +5034,15 @@ uint8_t gap_sniff_mode_exit(hci_con_handle_t con_handle){
return 0; return 0;
} }
#endif #endif
void hci_halting_defer(void){
if (hci_stack->state != HCI_STATE_HALTING) return;
switch (hci_stack->substate){
case HCI_HALTING_DISCONNECT_ALL_NO_TIMER:
case HCI_HALTING_CLOSE:
hci_stack->substate = HCI_HALTING_DISCONNECT_ALL_TIMER;
break;
default:
break;
}
}

View File

@ -660,7 +660,8 @@ typedef enum hci_init_state{
HCI_INIT_AFTER_SLEEP, HCI_INIT_AFTER_SLEEP,
HCI_HALTING_DISCONNECT_ALL, HCI_HALTING_DISCONNECT_ALL_NO_TIMER,
HCI_HALTING_DISCONNECT_ALL_TIMER,
HCI_HALTING_W4_TIMER, HCI_HALTING_W4_TIMER,
HCI_HALTING_CLOSE, HCI_HALTING_CLOSE,
@ -1201,6 +1202,11 @@ void hci_disable_l2cap_timeout_check(void);
*/ */
HCI_STATE hci_get_state(void); HCI_STATE hci_get_state(void);
/**
* Defer halt. Used by btstack_crypto to allow current HCI operation to complete
*/
void hci_halting_defer(void);
#if defined __cplusplus #if defined __cplusplus
} }
#endif #endif