mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-04-16 08:42:28 +00:00
l2cap-ertm: disconnect l2cap after monitor timeout and rety count has reached max transmit
This commit is contained in:
parent
20fa474d9d
commit
db55d2e9b3
58
src/l2cap.c
58
src/l2cap.c
@ -569,16 +569,52 @@ static void l2cap_ertm_next_tx_write_index(l2cap_channel_t * channel){
|
|||||||
if (channel->tx_write_index < channel->num_tx_buffers) return;
|
if (channel->tx_write_index < channel->num_tx_buffers) return;
|
||||||
channel->tx_write_index = 0;
|
channel->tx_write_index = 0;
|
||||||
}
|
}
|
||||||
static void l2cap_ertm_retransmission_timeout_callback(btstack_timer_source_t * ts){
|
|
||||||
log_info("l2cap_ertm_retransmission_timeout_callback");
|
|
||||||
l2cap_channel_t * channel = (l2cap_channel_t *) btstack_run_loop_get_timer_context(ts);
|
|
||||||
channel->send_supervisor_frame_receiver_ready_poll = 1;
|
|
||||||
l2cap_run();
|
|
||||||
}
|
|
||||||
static void l2cap_ertm_monitor_timeout_callback(btstack_timer_source_t * ts){
|
static void l2cap_ertm_monitor_timeout_callback(btstack_timer_source_t * ts){
|
||||||
log_info("l2cap_ertm_monitor_timeout_callback");
|
log_info("l2cap_ertm_monitor_timeout_callback");
|
||||||
l2cap_channel_t * channel = (l2cap_channel_t *) btstack_run_loop_get_timer_context(ts);
|
l2cap_channel_t * l2cap_channel = (l2cap_channel_t *) btstack_run_loop_get_timer_context(ts);
|
||||||
channel->send_supervisor_frame_receiver_ready_poll = 1;
|
|
||||||
|
// TODO: we assume that it's the oldest packet
|
||||||
|
l2cap_ertm_tx_packet_state_t * tx_state;
|
||||||
|
tx_state = &l2cap_channel->tx_packets_state[l2cap_channel->tx_read_index];
|
||||||
|
|
||||||
|
// check retry count
|
||||||
|
if (tx_state->retry_count < l2cap_channel->remote_max_transmit){
|
||||||
|
// increment retry count
|
||||||
|
tx_state->retry_count++;
|
||||||
|
|
||||||
|
// start monitor timer
|
||||||
|
btstack_run_loop_set_timer_handler(&tx_state->monitor_timer, &l2cap_ertm_monitor_timeout_callback);
|
||||||
|
btstack_run_loop_set_timer_context(&tx_state->monitor_timer, l2cap_channel);
|
||||||
|
btstack_run_loop_set_timer(&tx_state->monitor_timer, l2cap_channel->local_monitor_timeout_ms);
|
||||||
|
btstack_run_loop_add_timer(&tx_state->monitor_timer);
|
||||||
|
|
||||||
|
// send RR/P=1
|
||||||
|
l2cap_channel->send_supervisor_frame_receiver_ready_poll = 1;
|
||||||
|
} else {
|
||||||
|
log_info("Monitor timer expired & retry count >= max transmit -> disconnect");
|
||||||
|
l2cap_channel->state = L2CAP_STATE_WILL_SEND_DISCONNECT_REQUEST;
|
||||||
|
}
|
||||||
|
l2cap_run();
|
||||||
|
}
|
||||||
|
static void l2cap_ertm_retransmission_timeout_callback(btstack_timer_source_t * ts){
|
||||||
|
log_info("l2cap_ertm_retransmission_timeout_callback");
|
||||||
|
l2cap_channel_t * l2cap_channel = (l2cap_channel_t *) btstack_run_loop_get_timer_context(ts);
|
||||||
|
|
||||||
|
// TODO: we assume that it's the oldest packet
|
||||||
|
l2cap_ertm_tx_packet_state_t * tx_state;
|
||||||
|
tx_state = &l2cap_channel->tx_packets_state[l2cap_channel->tx_read_index];
|
||||||
|
|
||||||
|
// set retry count = 1
|
||||||
|
tx_state->retry_count = 1;
|
||||||
|
|
||||||
|
// start monitor timer
|
||||||
|
btstack_run_loop_set_timer_handler(&tx_state->monitor_timer, &l2cap_ertm_monitor_timeout_callback);
|
||||||
|
btstack_run_loop_set_timer_context(&tx_state->monitor_timer, l2cap_channel);
|
||||||
|
btstack_run_loop_set_timer(&tx_state->monitor_timer, l2cap_channel->local_monitor_timeout_ms);
|
||||||
|
btstack_run_loop_add_timer(&tx_state->monitor_timer);
|
||||||
|
|
||||||
|
// send RR/P=1
|
||||||
|
l2cap_channel->send_supervisor_frame_receiver_ready_poll = 1;
|
||||||
l2cap_run();
|
l2cap_run();
|
||||||
}
|
}
|
||||||
static int l2cap_ertm_send_information_frame(l2cap_channel_t * channel, int index){
|
static int l2cap_ertm_send_information_frame(l2cap_channel_t * channel, int index){
|
||||||
@ -603,6 +639,7 @@ static int l2cap_ertm_send(l2cap_channel_t * channel, uint8_t * data, uint16_t l
|
|||||||
l2cap_ertm_tx_packet_state_t * tx_state = &channel->tx_packets_state[index];
|
l2cap_ertm_tx_packet_state_t * tx_state = &channel->tx_packets_state[index];
|
||||||
tx_state->tx_seq = channel->next_tx_seq;
|
tx_state->tx_seq = channel->next_tx_seq;
|
||||||
tx_state->len = len;
|
tx_state->len = len;
|
||||||
|
tx_state->retry_count = 0;
|
||||||
memcpy(&channel->tx_packets_data[index * channel->local_mtu], data, len);
|
memcpy(&channel->tx_packets_data[index * channel->local_mtu], data, len);
|
||||||
// update
|
// update
|
||||||
channel->next_tx_seq = l2cap_next_ertm_seq_nr(channel->next_tx_seq);
|
channel->next_tx_seq = l2cap_next_ertm_seq_nr(channel->next_tx_seq);
|
||||||
@ -612,11 +649,6 @@ static int l2cap_ertm_send(l2cap_channel_t * channel, uint8_t * data, uint16_t l
|
|||||||
btstack_run_loop_set_timer_context(&tx_state->retransmission_timer, channel);
|
btstack_run_loop_set_timer_context(&tx_state->retransmission_timer, channel);
|
||||||
btstack_run_loop_set_timer(&tx_state->retransmission_timer, channel->local_retransmission_timeout_ms);
|
btstack_run_loop_set_timer(&tx_state->retransmission_timer, channel->local_retransmission_timeout_ms);
|
||||||
btstack_run_loop_add_timer(&tx_state->retransmission_timer);
|
btstack_run_loop_add_timer(&tx_state->retransmission_timer);
|
||||||
// set monitor timer
|
|
||||||
btstack_run_loop_set_timer_handler(&tx_state->monitor_timer, &l2cap_ertm_monitor_timeout_callback);
|
|
||||||
btstack_run_loop_set_timer_context(&tx_state->monitor_timer, channel);
|
|
||||||
btstack_run_loop_set_timer(&tx_state->monitor_timer, channel->local_monitor_timeout_ms);
|
|
||||||
btstack_run_loop_add_timer(&tx_state->monitor_timer);
|
|
||||||
// try to send
|
// try to send
|
||||||
l2cap_run();
|
l2cap_run();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -124,8 +124,9 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
btstack_timer_source_t retransmission_timer;
|
btstack_timer_source_t retransmission_timer;
|
||||||
btstack_timer_source_t monitor_timer;
|
btstack_timer_source_t monitor_timer;
|
||||||
uint8_t tx_seq;
|
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
|
uint8_t tx_seq;
|
||||||
|
uint8_t retry_count;
|
||||||
} l2cap_ertm_tx_packet_state_t;
|
} l2cap_ertm_tx_packet_state_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,6 +69,7 @@ static uint16_t handle;
|
|||||||
static uint16_t local_cid;
|
static uint16_t local_cid;
|
||||||
static int l2cap_ertm;
|
static int l2cap_ertm;
|
||||||
static int l2cap_ertm_mandatory;
|
static int l2cap_ertm_mandatory;
|
||||||
|
static int l2cap_max_transmit = 2; // some tests require > 1
|
||||||
|
|
||||||
static btstack_packet_callback_registration_t hci_event_callback_registration;
|
static btstack_packet_callback_registration_t hci_event_callback_registration;
|
||||||
static uint8_t ertm_buffer[10000];
|
static uint8_t ertm_buffer[10000];
|
||||||
@ -113,7 +114,7 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
|
|||||||
uint16_t l2cap_cid = little_endian_read_16(packet, 12);
|
uint16_t l2cap_cid = little_endian_read_16(packet, 12);
|
||||||
if (l2cap_ertm){
|
if (l2cap_ertm){
|
||||||
printf("L2CAP Accepting incoming connection request in ERTM\n");
|
printf("L2CAP Accepting incoming connection request in ERTM\n");
|
||||||
l2cap_accept_ertm_connection(l2cap_cid, l2cap_ertm_mandatory, 1, 2000, 12000, 4, 4, ertm_buffer, sizeof(ertm_buffer));
|
l2cap_accept_ertm_connection(l2cap_cid, l2cap_ertm_mandatory, l2cap_max_transmit, 2000, 12000, 4, 4, ertm_buffer, sizeof(ertm_buffer));
|
||||||
} else {
|
} else {
|
||||||
printf("L2CAP Accepting incoming connection request in Basic Mode\n");
|
printf("L2CAP Accepting incoming connection request in Basic Mode\n");
|
||||||
l2cap_accept_connection(l2cap_cid);
|
l2cap_accept_connection(l2cap_cid);
|
||||||
@ -156,7 +157,7 @@ static void stdin_process(char buffer){
|
|||||||
case 'c':
|
case 'c':
|
||||||
printf("Creating L2CAP Connection to %s, PSM SDP\n", bd_addr_to_str(remote));
|
printf("Creating L2CAP Connection to %s, PSM SDP\n", bd_addr_to_str(remote));
|
||||||
if (l2cap_ertm){
|
if (l2cap_ertm){
|
||||||
l2cap_create_ertm_channel(packet_handler, remote, BLUETOOTH_PROTOCOL_SDP, l2cap_ertm_mandatory, 1, 2000, 12000, 4, 4, ertm_buffer, sizeof(ertm_buffer), &local_cid);
|
l2cap_create_ertm_channel(packet_handler, remote, BLUETOOTH_PROTOCOL_SDP, l2cap_ertm_mandatory, l2cap_max_transmit, 2000, 12000, 4, 4, ertm_buffer, sizeof(ertm_buffer), &local_cid);
|
||||||
} else {
|
} else {
|
||||||
l2cap_create_channel(packet_handler, remote, BLUETOOTH_PROTOCOL_SDP, 100, &local_cid);
|
l2cap_create_channel(packet_handler, remote, BLUETOOTH_PROTOCOL_SDP, 100, &local_cid);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user