mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-03 20:54:18 +00:00
l2cap-ertm: store ertm config in channel struct, setup rx+tx packet state tracking
This commit is contained in:
parent
501329faba
commit
7b1816297b
62
src/l2cap.c
62
src/l2cap.c
@ -657,11 +657,11 @@ static uint16_t l2cap_setup_options_ertm(l2cap_channel_t * channel, uint8_t * co
|
||||
config_options[0] = 0x04; // RETRANSMISSION AND FLOW CONTROL OPTION
|
||||
config_options[1] = 9; // length
|
||||
config_options[2] = (uint8_t) channel->mode;
|
||||
config_options[3] = 1; // TxWindows size
|
||||
config_options[4] = 1; // max retransmit
|
||||
little_endian_store_16( config_options, 5, 100); // Retransmission timeout: 100 ms
|
||||
little_endian_store_16( config_options, 7, 300); // Monitor timeout: 300 ms
|
||||
little_endian_store_16( config_options, 9, channel->local_mtu); // Max PDU size // TODO: use real MTU
|
||||
config_options[3] = channel->num_rx_buffers; // == TxWindows size
|
||||
config_options[4] = channel->max_transmit;
|
||||
little_endian_store_16( config_options, 5, channel->retransmission_timeout_ms);
|
||||
little_endian_store_16( config_options, 7, channel->monitor_timeout_ms);
|
||||
little_endian_store_16( config_options, 9, channel->local_mtu);
|
||||
return 11;
|
||||
}
|
||||
#endif
|
||||
@ -1167,18 +1167,37 @@ uint8_t l2cap_create_channel(btstack_packet_handler_t channel_packet_handler, bd
|
||||
}
|
||||
|
||||
#ifdef ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE
|
||||
|
||||
static void l2cap_ertm_configure_channel(l2cap_channel_t * channel, int ertm_mandatory, uint8_t max_transmit,
|
||||
uint16_t retransmission_timeout_ms, uint16_t monitor_timeout_ms, uint8_t num_tx_buffers, uint8_t num_rx_buffers, uint8_t * buffer, uint32_t size){
|
||||
|
||||
channel->mode = L2CAP_CHANNEL_MODE_ENHANCED_RETRANSMISSION;
|
||||
channel->ertm_mandatory = ertm_mandatory;
|
||||
channel->max_transmit = max_transmit;
|
||||
channel->retransmission_timeout_ms = retransmission_timeout_ms;
|
||||
channel->monitor_timeout_ms = monitor_timeout_ms;
|
||||
channel->num_rx_buffers = num_rx_buffers;
|
||||
channel->num_tx_buffers = num_tx_buffers;
|
||||
|
||||
// TODO: align buffer pointer
|
||||
uint32_t pos = 0;
|
||||
channel->rx_packets_state = (l2cap_ertm_rx_packet_state_t *) &buffer[pos];
|
||||
pos += num_rx_buffers * sizeof(l2cap_ertm_rx_packet_state_t);
|
||||
channel->tx_packets_state = (l2cap_ertm_tx_packet_state_t *) &buffer[pos];
|
||||
pos += num_tx_buffers * sizeof(l2cap_ertm_tx_packet_state_t);
|
||||
// calculate MTU
|
||||
channel->local_mtu = (size - pos) / (num_rx_buffers + num_tx_buffers);
|
||||
log_info("Local ERTM MTU: %u", channel->local_mtu);
|
||||
channel->rx_packets_data = &buffer[pos];
|
||||
pos += num_rx_buffers * channel->local_mtu;
|
||||
channel->tx_packets_data = &buffer[pos];
|
||||
log_info("RX packets %p, TX packets %p", channel->rx_packets_data, channel->tx_packets_data);
|
||||
}
|
||||
|
||||
uint8_t l2cap_create_ertm_channel(btstack_packet_handler_t packet_handler, bd_addr_t address, uint16_t psm,
|
||||
int ertm_mandatory, uint8_t max_transmit, uint16_t retransmission_timeout_ms, uint16_t monitor_timeout_ms,
|
||||
uint8_t num_tx_buffers, uint8_t num_rx_buffers, uint8_t * buffer, uint32_t size, uint16_t * out_local_cid){
|
||||
|
||||
UNUSED(max_transmit);
|
||||
UNUSED(retransmission_timeout_ms);
|
||||
UNUSED(monitor_timeout_ms);
|
||||
UNUSED(num_rx_buffers);
|
||||
UNUSED(num_tx_buffers);
|
||||
UNUSED(buffer);
|
||||
UNUSED(size);
|
||||
|
||||
// limit MTU to the size of our outtgoing HCI buffer
|
||||
uint16_t local_mtu = l2cap_max_mtu();
|
||||
|
||||
@ -1189,8 +1208,9 @@ uint8_t l2cap_create_ertm_channel(btstack_packet_handler_t packet_handler, bd_ad
|
||||
return BTSTACK_MEMORY_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
channel->mode = L2CAP_CHANNEL_MODE_ENHANCED_RETRANSMISSION;
|
||||
channel->ertm_mandatory = ertm_mandatory;
|
||||
// configure ERTM
|
||||
l2cap_ertm_configure_channel(channel, ertm_mandatory, max_transmit, retransmission_timeout_ms,
|
||||
monitor_timeout_ms, num_tx_buffers, num_rx_buffers, buffer, size);
|
||||
|
||||
// add to connections list
|
||||
btstack_linked_list_add(&l2cap_channels, (btstack_linked_item_t *) channel);
|
||||
@ -1558,14 +1578,6 @@ void l2cap_accept_connection(uint16_t local_cid){
|
||||
void l2cap_accept_ertm_connection(uint16_t local_cid, int ertm_mandatory, uint8_t max_transmit,
|
||||
uint16_t retransmission_timeout_ms, uint16_t monitor_timeout_ms, uint8_t num_tx_buffers, uint8_t num_rx_buffers, uint8_t * buffer, uint32_t size){
|
||||
|
||||
UNUSED(max_transmit);
|
||||
UNUSED(retransmission_timeout_ms);
|
||||
UNUSED(monitor_timeout_ms);
|
||||
UNUSED(num_rx_buffers);
|
||||
UNUSED(num_tx_buffers);
|
||||
UNUSED(buffer);
|
||||
UNUSED(size);
|
||||
|
||||
log_info("L2CAP_ACCEPT_ERTM_CONNECTION local_cid 0x%x", local_cid);
|
||||
l2cap_channel_t * channel = l2cap_get_channel_for_local_cid(local_cid);
|
||||
if (!channel) {
|
||||
@ -1574,9 +1586,9 @@ void l2cap_accept_ertm_connection(uint16_t local_cid, int ertm_mandatory, uint8_
|
||||
}
|
||||
|
||||
// configure L2CAP ERTM
|
||||
channel->mode = L2CAP_CHANNEL_MODE_ENHANCED_RETRANSMISSION;
|
||||
channel->ertm_mandatory = ertm_mandatory;
|
||||
l2cap_ertm_configure_channel(channel, ertm_mandatory, max_transmit, retransmission_timeout_ms, monitor_timeout_ms, num_tx_buffers, num_rx_buffers, buffer, size);
|
||||
|
||||
// continue
|
||||
channel->state = L2CAP_STATE_WILL_SEND_CONNECTION_RESPONSE_ACCEPT;
|
||||
|
||||
// process
|
||||
|
38
src/l2cap.h
38
src/l2cap.h
@ -115,6 +115,17 @@ typedef enum {
|
||||
L2CAP_CHANNEL_STATE_VAR_INCOMING = 1 << 15, // channel is incoming
|
||||
} L2CAP_CHANNEL_STATE_VAR;
|
||||
|
||||
typedef struct {
|
||||
uint8_t tx_seq;
|
||||
uint16_t pos;
|
||||
uint16_t sdu_length;
|
||||
} l2cap_ertm_rx_packet_state_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t tx_seq;
|
||||
} l2cap_ertm_tx_packet_state_t;
|
||||
|
||||
|
||||
// info regarding an actual connection
|
||||
typedef struct {
|
||||
// linked list - assert: first field
|
||||
@ -184,11 +195,36 @@ typedef struct {
|
||||
// l2cap channel mode: basic or enhanced retransmission mode
|
||||
l2cap_channel_mode_t mode;
|
||||
|
||||
// timer config
|
||||
uint16_t retransmission_timeout_ms;
|
||||
uint16_t monitor_timeout_ms;
|
||||
|
||||
// max transmit
|
||||
uint8_t max_transmit;
|
||||
|
||||
// if ertm is not mandatory, allow fallback to L2CAP Basic Mode
|
||||
uint8_t ertm_mandatory;
|
||||
|
||||
// next seq nr used for sending
|
||||
uint8_t next_tx_seq;
|
||||
|
||||
// max um out-of-order packets // tx_window
|
||||
uint8_t num_rx_buffers;
|
||||
|
||||
// max num of unacknowledged outgoing packets
|
||||
uint8_t num_tx_buffers;
|
||||
|
||||
// re-assembly state
|
||||
l2cap_ertm_rx_packet_state_t * rx_packets_state;
|
||||
|
||||
// retransmission state
|
||||
l2cap_ertm_tx_packet_state_t * tx_packets_state;
|
||||
|
||||
// data, each of size local_mtu
|
||||
uint8_t * rx_packets_data;
|
||||
|
||||
// data, each of size local_mtu
|
||||
uint8_t * tx_packets_data;
|
||||
#endif
|
||||
} l2cap_channel_t;
|
||||
|
||||
@ -219,7 +255,7 @@ typedef struct l2cap_signaling_response {
|
||||
uint16_t cid; // source cid for CONNECTION REQUEST
|
||||
uint16_t data; // infoType for INFORMATION REQUEST, result for CONNECTION REQUEST and COMMAND UNKNOWN
|
||||
} l2cap_signaling_response_t;
|
||||
|
||||
|
||||
|
||||
void l2cap_register_fixed_channel(btstack_packet_handler_t packet_handler, uint16_t channel_id);
|
||||
int l2cap_can_send_fixed_channel_packet_now(hci_con_handle_t con_handle, uint16_t channel_id);
|
||||
|
Loading…
x
Reference in New Issue
Block a user