hci: add workaround for Controllers that fail to send command complete/status for connection that does not get established

This commit is contained in:
Matthias Ringwald 2023-11-27 12:08:26 +01:00
parent 515f33be6f
commit f48a558634
3 changed files with 93 additions and 54 deletions

View File

@ -83,7 +83,7 @@ Chipset properties:
BTstack properties:
| \#define | Description |
|-----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------|
|-----------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------|
| ENABLE_CLASSIC | Enable Classic related code in HCI and L2CAP |
| ENABLE_BLE | Enable BLE related code in HCI and L2CAP |
| ENABLE_EHCILL | Enable eHCILL low power mode on TI CC256x/WL18xx chipsets |
@ -136,6 +136,7 @@ BTstack properties:
| ENABLE_LE_WHITELIST_TOUCH_AFTER_RESOLVING_LIST_UPDATE | Enable Workaround for Controller bug |
| ENABLE_LE_SET_ADV_PARAMS_ON_RANDOM_ADDRESS_CHANGE | Send HCI LE Set Advertising Params after HCI LE Set Random Address - workaround for Controller Bug |
| ENABLE_CONTROLLER_DUMP_PACKETS | Dump number of packets in Controller per type for debugging |
| ENABLE_HCI_COMMAND_STATUS_DISCARDED_FOR_FAILED_CONNECTIONS WORKAROUND | Track connection handle for HCI Commands and assume command has failed if disonnect event for connection is received |
Notes:

View File

@ -2781,6 +2781,9 @@ static void handle_command_complete_event(uint8_t * packet, uint16_t size){
#ifdef ENABLE_LE_ISOCHRONOUS_STREAMS
le_audio_cig_t * cig;
#endif
#if defined(ENABLE_BLE) && defined (ENABLE_HCI_COMMAND_STATUS_DISCARDED_FOR_FAILED_CONNECTIONS WORKAROUND)
hci_stack->hci_command_con_handle = HCI_CON_HANDLE_INVALID;
#endif
// get num cmd packets - limit to 1 to reduce complexity
hci_stack->num_cmd_packets = packet[2] ? 1 : 0;
@ -3196,6 +3199,10 @@ static void handle_command_status_event(uint8_t * packet, uint16_t size) {
bd_addr_t addr;
#endif
#if defined(ENABLE_BLE) && defined (ENABLE_HCI_COMMAND_STATUS_DISCARDED_FOR_FAILED_CONNECTIONS)
hci_stack->hci_command_con_handle = HCI_CON_HANDLE_INVALID;
#endif
switch (opcode){
#ifdef ENABLE_CLASSIC
case HCI_OPCODE_HCI_CREATE_CONNECTION:
@ -4156,6 +4163,15 @@ static void event_handler(uint8_t *packet, uint16_t size){
}
#endif
#if defined(ENABLE_BLE) && defined (ENABLE_HCI_COMMAND_STATUS_DISCARDED_FOR_FAILED_CONNECTIONS WORKAROUND)
if ((handle != HCI_CON_HANDLE_INVALID) && (handle == hci_stack->hci_command_con_handle)){
// we did not receive a HCI Command Complete or HCI Command Status event for the disconnected connection
// if needed, we could also track the hci command opcode and simulate a hci command complete with status
// but the connection has failed anyway, so for now, we only set the num hci commands back to 1
hci_stack->num_cmd_packets = 1;
}
#endif
conn = hci_connection_for_handle(handle);
if (!conn) break;
#ifdef ENABLE_CLASSIC
@ -4750,6 +4766,9 @@ static void hci_state_reset(void){
hci_stack->iso_active_operation_type = HCI_ISO_TYPE_INVALID;
hci_stack->iso_active_operation_group_id = HCI_ISO_GROUP_ID_INVALID;
#endif
#ifdef ENABLE_HCI_COMMAND_STATUS_DISCARDED_FOR_FAILED_CONNECTIONS WORKAROUND
hci_stack->hci_command_con_handle = HCI_CON_HANDLE_INVALID;
#endif
}
#ifdef ENABLE_CLASSIC
@ -7638,6 +7657,21 @@ uint8_t hci_send_cmd_packet(uint8_t *packet, int size){
hci_stack->le_connecting_state = LE_CONNECTING_CANCEL;
break;
#endif
#ifdef ENABLE_HCI_COMMAND_STATUS_DISCARDED_FOR_FAILED_CONNECTIONS WORKAROUND
case HCI_OPCODE_HCI_LE_CONNECTION_UPDATE:
case HCI_OPCODE_HCI_LE_READ_REMOTE_USED_FEATURES:
case HCI_OPCODE_HCI_LE_START_ENCRYPTION:
case HCI_OPCODE_HCI_LE_LONG_TERM_KEY_REQUEST_REPLY:
case HCI_OPCODE_HCI_LE_LONG_TERM_KEY_NEGATIVE_REPLY:
case HCI_OPCODE_HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY:
case HCI_OPCODE_HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY:
case HCI_OPCODE_HCI_LE_SET_DATA_LENGTH:
case HCI_OPCODE_HCI_LE_READ_PHY:
case HCI_OPCODE_HCI_LE_SET_PHY:
// conection handle is first command parameter
hci_stack->hci_command_con_handle = little_endian_read_16(packet, 3);
break;
#endif
#endif /* ENABLE_BLE */
default:
break;

View File

@ -1207,6 +1207,10 @@ typedef struct {
uint16_t le_supervision_timeout;
uint16_t le_minimum_ce_length;
uint16_t le_maximum_ce_length;
#ifdef ENABLE_HCI_COMMAND_STATUS_DISCARDED_FOR_FAILED_CONNECTIONS
hci_con_handle_t hci_command_con_handle;
#endif
#endif
#ifdef ENABLE_LE_CENTRAL