l2cap-ertm: on information response verify ertm requirements for outgoing connection only

This commit is contained in:
Matthias Ringwald 2019-09-30 14:38:37 +02:00
parent 84e3541e4b
commit f8ecb1142c

View File

@ -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;