mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-01-27 06:35:20 +00:00
l2cap: emit L2CAP_EVENT_CHANNEL_OPENED with status L2CAP_CONNECTION_BASEBAND_DISCONNECT on HCI Disconnect Event before channel was opened
This commit is contained in:
parent
6e0288c29c
commit
2053036d0c
@ -138,8 +138,9 @@ typedef uint8_t sm_key_t[16];
|
|||||||
#define L2CAP_CONNECTION_RESPONSE_RESULT_REFUSED_PSM 0x65
|
#define L2CAP_CONNECTION_RESPONSE_RESULT_REFUSED_PSM 0x65
|
||||||
#define L2CAP_CONNECTION_RESPONSE_RESULT_REFUSED_SECURITY 0x66
|
#define L2CAP_CONNECTION_RESPONSE_RESULT_REFUSED_SECURITY 0x66
|
||||||
#define L2CAP_CONNECTION_RESPONSE_RESULT_REFUSED_RESOURCES 0x67
|
#define L2CAP_CONNECTION_RESPONSE_RESULT_REFUSED_RESOURCES 0x67
|
||||||
#define L2CAP_CONNECTION_RESPONSE_RESULT_ERTM_NOT_SUPPORTD 0x68
|
// should be L2CAP_CONNECTION_RTX_TIMEOUT
|
||||||
#define L2CAP_CONNECTION_RESPONSE_RESULT_RTX_TIMEOUT 0x69
|
#define L2CAP_CONNECTION_RESPONSE_RESULT_RTX_TIMEOUT 0x68
|
||||||
|
#define L2CAP_CONNECTION_BASEBAND_DISCONNECT 0x69
|
||||||
#define L2CAP_SERVICE_ALREADY_REGISTERED 0x6A
|
#define L2CAP_SERVICE_ALREADY_REGISTERED 0x6A
|
||||||
#define L2CAP_DATA_LEN_EXCEEDS_REMOTE_MTU 0x6B
|
#define L2CAP_DATA_LEN_EXCEEDS_REMOTE_MTU 0x6B
|
||||||
#define L2CAP_SERVICE_DOES_NOT_EXIST 0x6C
|
#define L2CAP_SERVICE_DOES_NOT_EXIST 0x6C
|
||||||
|
65
src/l2cap.c
65
src/l2cap.c
@ -1799,6 +1799,56 @@ static void l2cap_notify_channel_can_send(void){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef L2CAP_USES_CHANNELS
|
||||||
|
|
||||||
|
static int l2cap_send_open_failed_on_hci_disconnect(l2cap_channel_t * channel){
|
||||||
|
// open cannot fail for for incoming connections
|
||||||
|
if (channel->state_var & L2CAP_CHANNEL_STATE_VAR_INCOMING) return 0;
|
||||||
|
|
||||||
|
// check state
|
||||||
|
switch (channel->state){
|
||||||
|
case L2CAP_STATE_WILL_SEND_CREATE_CONNECTION:
|
||||||
|
case L2CAP_STATE_WAIT_CONNECTION_COMPLETE:
|
||||||
|
case L2CAP_STATE_WAIT_REMOTE_SUPPORTED_FEATURES:
|
||||||
|
case L2CAP_STATE_WAIT_OUTGOING_SECURITY_LEVEL_UPDATE:
|
||||||
|
case L2CAP_STATE_WAIT_CLIENT_ACCEPT_OR_REJECT:
|
||||||
|
case L2CAP_STATE_WAIT_OUTGOING_EXTENDED_FEATURES:
|
||||||
|
case L2CAP_STATE_WAIT_CONNECT_RSP:
|
||||||
|
case L2CAP_STATE_CONFIG:
|
||||||
|
case L2CAP_STATE_WILL_SEND_CONNECTION_REQUEST:
|
||||||
|
case L2CAP_STATE_WILL_SEND_LE_CONNECTION_REQUEST:
|
||||||
|
case L2CAP_STATE_WAIT_LE_CONNECTION_RESPONSE:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case L2CAP_STATE_OPEN:
|
||||||
|
case L2CAP_STATE_CLOSED:
|
||||||
|
case L2CAP_STATE_WAIT_INCOMING_EXTENDED_FEATURES:
|
||||||
|
case L2CAP_STATE_WAIT_DISCONNECT:
|
||||||
|
case L2CAP_STATE_WILL_SEND_CONNECTION_RESPONSE_INSUFFICIENT_SECURITY:
|
||||||
|
case L2CAP_STATE_WILL_SEND_CONNECTION_RESPONSE_DECLINE:
|
||||||
|
case L2CAP_STATE_WILL_SEND_CONNECTION_RESPONSE_ACCEPT:
|
||||||
|
case L2CAP_STATE_WILL_SEND_DISCONNECT_REQUEST:
|
||||||
|
case L2CAP_STATE_WILL_SEND_DISCONNECT_RESPONSE:
|
||||||
|
case L2CAP_STATE_WILL_SEND_LE_CONNECTION_RESPONSE_DECLINE:
|
||||||
|
case L2CAP_STATE_WILL_SEND_LE_CONNECTION_RESPONSE_ACCEPT:
|
||||||
|
case L2CAP_STATE_INVALID:
|
||||||
|
case L2CAP_STATE_WAIT_INCOMING_SECURITY_LEVEL_UPDATE:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void l2cap_handle_hci_disconnect_event(l2cap_channel_t * channel){
|
||||||
|
if (l2cap_send_open_failed_on_hci_disconnect(channel)){
|
||||||
|
l2cap_emit_channel_opened(channel, L2CAP_CONNECTION_BASEBAND_DISCONNECT);
|
||||||
|
} else {
|
||||||
|
l2cap_emit_channel_closed(channel);
|
||||||
|
}
|
||||||
|
btstack_memory_l2cap_channel_free(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void l2cap_hci_event_handler(uint8_t packet_type, uint16_t cid, uint8_t *packet, uint16_t size){
|
static void l2cap_hci_event_handler(uint8_t packet_type, uint16_t cid, uint8_t *packet, uint16_t size){
|
||||||
|
|
||||||
UNUSED(packet_type);
|
UNUSED(packet_type);
|
||||||
@ -1854,33 +1904,32 @@ static void l2cap_hci_event_handler(uint8_t packet_type, uint16_t cid, uint8_t *
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef L2CAP_USES_CHANNELS
|
||||||
// handle disconnection complete events
|
// handle disconnection complete events
|
||||||
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
||||||
// send l2cap disconnect events for all channels on this handle and free them
|
|
||||||
#ifdef ENABLE_CLASSIC
|
|
||||||
handle = little_endian_read_16(packet, 3);
|
handle = little_endian_read_16(packet, 3);
|
||||||
|
// send l2cap open failed or closed events for all channels on this handle and free them
|
||||||
|
#ifdef ENABLE_CLASSIC
|
||||||
btstack_linked_list_iterator_init(&it, &l2cap_channels);
|
btstack_linked_list_iterator_init(&it, &l2cap_channels);
|
||||||
while (btstack_linked_list_iterator_has_next(&it)){
|
while (btstack_linked_list_iterator_has_next(&it)){
|
||||||
l2cap_channel_t * channel = (l2cap_channel_t *) btstack_linked_list_iterator_next(&it);
|
l2cap_channel_t * channel = (l2cap_channel_t *) btstack_linked_list_iterator_next(&it);
|
||||||
if (channel->con_handle != handle) continue;
|
if (channel->con_handle != handle) continue;
|
||||||
l2cap_emit_channel_closed(channel);
|
|
||||||
l2cap_stop_rtx(channel);
|
|
||||||
btstack_linked_list_iterator_remove(&it);
|
btstack_linked_list_iterator_remove(&it);
|
||||||
btstack_memory_l2cap_channel_free(channel);
|
l2cap_stop_rtx(channel);
|
||||||
|
l2cap_handle_hci_disconnect_event(channel);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_LE_DATA_CHANNELS
|
#ifdef ENABLE_LE_DATA_CHANNELS
|
||||||
handle = little_endian_read_16(packet, 3);
|
|
||||||
btstack_linked_list_iterator_init(&it, &l2cap_le_channels);
|
btstack_linked_list_iterator_init(&it, &l2cap_le_channels);
|
||||||
while (btstack_linked_list_iterator_has_next(&it)){
|
while (btstack_linked_list_iterator_has_next(&it)){
|
||||||
l2cap_channel_t * channel = (l2cap_channel_t *) btstack_linked_list_iterator_next(&it);
|
l2cap_channel_t * channel = (l2cap_channel_t *) btstack_linked_list_iterator_next(&it);
|
||||||
if (channel->con_handle != handle) continue;
|
if (channel->con_handle != handle) continue;
|
||||||
l2cap_emit_channel_closed(channel);
|
|
||||||
btstack_linked_list_iterator_remove(&it);
|
btstack_linked_list_iterator_remove(&it);
|
||||||
btstack_memory_l2cap_channel_free(channel);
|
l2cap_handle_hci_disconnect_event(channel);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
// HCI Connection Timeouts
|
// HCI Connection Timeouts
|
||||||
#ifdef ENABLE_CLASSIC
|
#ifdef ENABLE_CLASSIC
|
||||||
|
Loading…
x
Reference in New Issue
Block a user