mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-03 20:54:18 +00:00
l2cap-ertm: renegotiate basic mode if ERTM not requested
This commit is contained in:
parent
5b1804341c
commit
ac8f130048
90
src/l2cap.c
90
src/l2cap.c
@ -649,9 +649,9 @@ static uint16_t l2cap_setup_options(l2cap_channel_t * channel, uint8_t * config_
|
||||
int send_retransmission_and_flow_control_option = 0;
|
||||
int options_size;
|
||||
#ifdef ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE
|
||||
if (channel->mode == L2CAP_CHANNEL_MODE_ENHANCED_RETRANSMISSION){
|
||||
send_retransmission_and_flow_control_option = 1;
|
||||
}
|
||||
// if (channel->mode == L2CAP_CHANNEL_MODE_ENHANCED_RETRANSMISSION){
|
||||
send_retransmission_and_flow_control_option = 1;
|
||||
// }
|
||||
#endif
|
||||
if (send_retransmission_and_flow_control_option){
|
||||
#ifdef ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE
|
||||
@ -849,13 +849,21 @@ static void l2cap_run(void){
|
||||
channelStateVarSetFlag(channel, L2CAP_CHANNEL_STATE_VAR_SENT_CONF_RSP);
|
||||
}
|
||||
if (channel->state_var & L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP_INVALID){
|
||||
channelStateVarClearFlag(channel, L2CAP_CHANNEL_STATE_VAR_SENT_CONF_RSP);
|
||||
l2cap_send_signaling_packet(channel->con_handle, CONFIGURE_RESPONSE, channel->remote_sig_id, channel->remote_cid, flags, L2CAP_CONF_RESULT_UNKNOWN_OPTIONS, 0, NULL);
|
||||
} else if (channel->state_var & L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP_MTU){
|
||||
#ifdef ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE
|
||||
} else if (channel->state_var & L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP_REJECTED){
|
||||
channelStateVarClearFlag(channel,L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP_REJECTED);
|
||||
channelStateVarClearFlag(channel, L2CAP_CHANNEL_STATE_VAR_SENT_CONF_RSP);
|
||||
uint16_t options_size = l2cap_setup_options(channel, config_options);
|
||||
l2cap_send_signaling_packet(channel->con_handle, CONFIGURE_RESPONSE, channel->remote_sig_id, channel->remote_cid, flags, 0, options_size, &config_options);
|
||||
l2cap_send_signaling_packet(channel->con_handle, CONFIGURE_RESPONSE, channel->remote_sig_id, channel->remote_cid, flags, L2CAP_CONF_RESULT_UNACCEPTABLE_PARAMETERS, options_size, &config_options);
|
||||
#endif
|
||||
} else if (channel->state_var & L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP_MTU){
|
||||
channelStateVarClearFlag(channel,L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP_MTU);
|
||||
uint16_t options_size = l2cap_setup_options(channel, config_options);
|
||||
l2cap_send_signaling_packet(channel->con_handle, CONFIGURE_RESPONSE, channel->remote_sig_id, channel->remote_cid, flags, L2CAP_CONF_RESULT_SUCCESS, options_size, &config_options);
|
||||
} else {
|
||||
l2cap_send_signaling_packet(channel->con_handle, CONFIGURE_RESPONSE, channel->remote_sig_id, channel->remote_cid, flags, 0, 0, NULL);
|
||||
l2cap_send_signaling_packet(channel->con_handle, CONFIGURE_RESPONSE, channel->remote_sig_id, channel->remote_cid, flags, L2CAP_CONF_RESULT_SUCCESS, 0, NULL);
|
||||
}
|
||||
channelStateVarClearFlag(channel, L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP_CONT);
|
||||
}
|
||||
@ -1596,15 +1604,41 @@ static void l2cap_signaling_handle_configure_request(l2cap_channel_t *channel, u
|
||||
#ifdef ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE
|
||||
// Retransmission and Flow Control Option
|
||||
if (option_type == 4 && length == 9){
|
||||
if (channel->mode == L2CAP_CHANNEL_MODE_ENHANCED_RETRANSMISSION && channel->ertm_mandatory){
|
||||
// ertm mandatory, but remote doens't offer ERTM -> disconnect
|
||||
l2cap_channel_mode_t mode = (l2cap_channel_mode_t) command[pos];
|
||||
if (mode != L2CAP_CHANNEL_MODE_ENHANCED_RETRANSMISSION){
|
||||
channel->state = L2CAP_STATE_WILL_SEND_DISCONNECT_REQUEST;
|
||||
}
|
||||
} else {
|
||||
// TODO store and evaluate configuration
|
||||
channelStateVarSetFlag(channel, L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP_MTU);
|
||||
l2cap_channel_mode_t mode = (l2cap_channel_mode_t) command[pos];
|
||||
switch(channel->mode){
|
||||
case L2CAP_CHANNEL_MODE_ENHANCED_RETRANSMISSION:
|
||||
if (channel->ertm_mandatory){
|
||||
// ERTM mandatory, but remote doens't offer ERTM -> disconnect
|
||||
if (mode != L2CAP_CHANNEL_MODE_ENHANCED_RETRANSMISSION){
|
||||
channel->state = L2CAP_STATE_WILL_SEND_DISCONNECT_REQUEST;
|
||||
} else {
|
||||
// Both sides selected ERTM
|
||||
// TODO store and evaluate configuration
|
||||
channelStateVarSetFlag(channel, L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP_MTU);
|
||||
}
|
||||
} else {
|
||||
// ERTM is optional
|
||||
channelStateVarSetFlag(channel, L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP_MTU);
|
||||
}
|
||||
break;
|
||||
case L2CAP_CHANNEL_MODE_BASIC:
|
||||
switch (mode){
|
||||
case L2CAP_CHANNEL_MODE_ENHANCED_RETRANSMISSION:
|
||||
// remote asks for ERTM, but we want basic mode. disconnect if this happens a second time
|
||||
if (channel->state_var & L2CAP_CHANNEL_STATE_VAR_BASIC_FALLBACK_TRIED){
|
||||
channel->state = L2CAP_STATE_WILL_SEND_DISCONNECT_REQUEST;
|
||||
}
|
||||
channelStateVarSetFlag(channel, L2CAP_CHANNEL_STATE_VAR_BASIC_FALLBACK_TRIED);
|
||||
channelStateVarSetFlag(channel, L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP_REJECTED);
|
||||
break;
|
||||
default: // case L2CAP_CHANNEL_MODE_BASIC:
|
||||
// TODO store and evaluate configuration
|
||||
channelStateVarSetFlag(channel, L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP_MTU);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -1631,15 +1665,25 @@ static void l2cap_signaling_handle_configure_response(l2cap_channel_t *channel,
|
||||
|
||||
// Retransmission and Flow Control Option
|
||||
if (option_type == 4 && length == 9){
|
||||
if (channel->mode == L2CAP_CHANNEL_MODE_ENHANCED_RETRANSMISSION){
|
||||
if (channel->ertm_mandatory){
|
||||
//
|
||||
} else {
|
||||
// On 'Reject - Unacceptable Parameters', fall back to BASIC mode
|
||||
if (result == 1){
|
||||
channel->mode = L2CAP_CHANNEL_MODE_BASIC;
|
||||
switch (channel->mode){
|
||||
case L2CAP_CHANNEL_MODE_ENHANCED_RETRANSMISSION:
|
||||
if (channel->ertm_mandatory){
|
||||
// ??
|
||||
} else {
|
||||
// On 'Reject - Unacceptable Parameters' to our optional ERTM request, fall back to BASIC mode
|
||||
if (result == L2CAP_CONF_RESULT_UNACCEPTABLE_PARAMETERS){
|
||||
channel->mode = L2CAP_CHANNEL_MODE_BASIC;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case L2CAP_CHANNEL_MODE_BASIC:
|
||||
if (result == L2CAP_CONF_RESULT_UNACCEPTABLE_PARAMETERS){
|
||||
// On 'Reject - Unacceptable Parameters' to our Basic mode request, disconnect
|
||||
channel->state = L2CAP_STATE_WILL_SEND_DISCONNECT_REQUEST;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
28
src/l2cap.h
28
src/l2cap.h
@ -97,19 +97,21 @@ typedef enum {
|
||||
} L2CAP_STATE;
|
||||
|
||||
typedef enum {
|
||||
L2CAP_CHANNEL_STATE_VAR_NONE = 0,
|
||||
L2CAP_CHANNEL_STATE_VAR_RCVD_CONF_REQ = 1 << 0,
|
||||
L2CAP_CHANNEL_STATE_VAR_RCVD_CONF_RSP = 1 << 1,
|
||||
L2CAP_CHANNEL_STATE_VAR_SEND_CONF_REQ = 1 << 2,
|
||||
L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP = 1 << 3,
|
||||
L2CAP_CHANNEL_STATE_VAR_SENT_CONF_REQ = 1 << 4,
|
||||
L2CAP_CHANNEL_STATE_VAR_SENT_CONF_RSP = 1 << 5,
|
||||
L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP_MTU = 1 << 6, // in CONF RSP, add MTU field
|
||||
L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP_CONT = 1 << 7, // in CONF RSP, set CONTINUE flag
|
||||
L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP_INVALID = 1 << 8, // in CONF RSP, send UNKNOWN OPTIONS
|
||||
L2CAP_CHANNEL_STATE_VAR_SEND_CMD_REJ_UNKNOWN = 1 << 9, // send CMD_REJ with reason unknown
|
||||
L2CAP_CHANNEL_STATE_VAR_SEND_CONN_RESP_PEND = 1 << 10, // send Connection Respond with pending
|
||||
L2CAP_CHANNEL_STATE_VAR_INCOMING = 1 << 15, // channel is incoming
|
||||
L2CAP_CHANNEL_STATE_VAR_NONE = 0,
|
||||
L2CAP_CHANNEL_STATE_VAR_RCVD_CONF_REQ = 1 << 0,
|
||||
L2CAP_CHANNEL_STATE_VAR_RCVD_CONF_RSP = 1 << 1,
|
||||
L2CAP_CHANNEL_STATE_VAR_SEND_CONF_REQ = 1 << 2,
|
||||
L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP = 1 << 3,
|
||||
L2CAP_CHANNEL_STATE_VAR_SENT_CONF_REQ = 1 << 4,
|
||||
L2CAP_CHANNEL_STATE_VAR_SENT_CONF_RSP = 1 << 5,
|
||||
L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP_MTU = 1 << 6, // in CONF RSP, add MTU field
|
||||
L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP_CONT = 1 << 7, // in CONF RSP, set CONTINUE flag
|
||||
L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP_INVALID = 1 << 8, // in CONF RSP, send UNKNOWN OPTIONS
|
||||
L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP_REJECTED = 1 << 9, // in CONF RSP, send Unacceptable Parameters (ERTM)
|
||||
L2CAP_CHANNEL_STATE_VAR_BASIC_FALLBACK_TRIED = 1 << 10, // set when ERTM was requested but we want only Basic mode (ERM)
|
||||
L2CAP_CHANNEL_STATE_VAR_SEND_CMD_REJ_UNKNOWN = 1 << 11, // send CMD_REJ with reason unknown
|
||||
L2CAP_CHANNEL_STATE_VAR_SEND_CONN_RESP_PEND = 1 << 12, // send Connection Respond with pending
|
||||
L2CAP_CHANNEL_STATE_VAR_INCOMING = 1 << 15, // channel is incoming
|
||||
} L2CAP_CHANNEL_STATE_VAR;
|
||||
|
||||
// info regarding an actual connection
|
||||
|
Loading…
x
Reference in New Issue
Block a user