From f8ecb1142c7bfe06c09809b017c6c9d145930404 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Mon, 30 Sep 2019 14:38:37 +0200 Subject: [PATCH] l2cap-ertm: on information response verify ertm requirements for outgoing connection only --- src/l2cap.c | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/src/l2cap.c b/src/l2cap.c index afc4d1b64..96080fdba 100644 --- a/src/l2cap.c +++ b/src/l2cap.c @@ -2865,31 +2865,39 @@ static void l2cap_signaling_handler_dispatch(hci_con_handle_t handle, uint8_t * l2cap_channel_t * channel = (l2cap_channel_t *) btstack_linked_list_iterator_next(&it); if (!l2cap_is_dynamic_channel_type(channel->channel_type)) continue; if (channel->con_handle != handle) continue; - // bail if ERTM was requested but is not supported - if ((channel->mode == L2CAP_CHANNEL_MODE_ENHANCED_RETRANSMISSION) && ((connection->l2cap_state.extended_feature_mask & 0x08) == 0)){ - if (channel->ertm_mandatory){ - // channel closed - channel->state = L2CAP_STATE_CLOSED; - // map l2cap connection response result to BTstack status enumeration - l2cap_handle_channel_open_failed(channel, L2CAP_CONNECTION_RESPONSE_RESULT_ERTM_NOT_SUPPORTED); - // discard channel - btstack_linked_list_remove(&l2cap_channels, (btstack_linked_item_t *) channel); - l2cap_free_channel_entry(channel); - continue; + + // incoming connection: ask user for channel configuration, esp. if ertm will be mandatory + if (channel->state == L2CAP_STATE_WAIT_INCOMING_EXTENDED_FEATURES){ + channel->state = L2CAP_STATE_WAIT_CLIENT_ACCEPT_OR_REJECT; + l2cap_emit_incoming_connection(channel); + continue; + } + + // outgoing connection + if (channel->state == L2CAP_STATE_WAIT_OUTGOING_EXTENDED_FEATURES){ + + // verify ERTM requirements + if ((channel->mode == L2CAP_CHANNEL_MODE_ENHANCED_RETRANSMISSION) && ((connection->l2cap_state.extended_feature_mask & 0x08) == 0)){ + // bail if ERTM was requested but is not supported + if (channel->ertm_mandatory){ + // channel closed + channel->state = L2CAP_STATE_CLOSED; + // map l2cap connection response result to BTstack status enumeration + l2cap_handle_channel_open_failed(channel, L2CAP_CONNECTION_RESPONSE_RESULT_ERTM_NOT_SUPPORTED); + // discard channel + btstack_linked_list_remove(&l2cap_channels, (btstack_linked_item_t *) channel); + l2cap_free_channel_entry(channel); + continue; + } } else { // fallback to Basic mode l2cap_emit_simple_event_with_cid(channel, L2CAP_EVENT_ERTM_BUFFER_RELEASED); channel->mode = L2CAP_CHANNEL_MODE_BASIC; } - } - // start connecting - if (channel->state == L2CAP_STATE_WAIT_OUTGOING_EXTENDED_FEATURES){ + + // respond to connection request channel->state = L2CAP_STATE_WILL_SEND_CONNECTION_REQUEST; - } - // respond to connection request - if (channel->state == L2CAP_STATE_WAIT_INCOMING_EXTENDED_FEATURES){ - channel->state = L2CAP_STATE_WAIT_CLIENT_ACCEPT_OR_REJECT; - l2cap_emit_incoming_connection(channel); + continue; } } return;