From 62041d70a971cde12dc39702fc7892f620b4fa7b Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Mon, 17 Jul 2017 17:33:30 +0200 Subject: [PATCH] l2cap-ertm: send RR with poll=1 if packet is not acknowledged --- src/l2cap.c | 21 +++++++++++++++++++++ src/l2cap.h | 4 ++++ 2 files changed, 25 insertions(+) diff --git a/src/l2cap.c b/src/l2cap.c index 247a79fb2..7bedcfe8c 100644 --- a/src/l2cap.c +++ b/src/l2cap.c @@ -569,6 +569,13 @@ static void l2cap_ertm_next_tx_write_index(l2cap_channel_t * channel){ if (channel->tx_write_index < channel->num_tx_buffers) return; channel->tx_write_index = 0; } +static void l2cap_ertm_retransmission_timeout_callback(btstack_timer_source_t * ts){ + UNUSED(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 int l2cap_ertm_send_information_frame(l2cap_channel_t * channel, int index){ l2cap_ertm_tx_packet_state_t * tx_state = &channel->tx_packets_state[index]; hci_reserve_packet_buffer(); @@ -595,6 +602,11 @@ static int l2cap_ertm_send(l2cap_channel_t * channel, uint8_t * data, uint16_t l // update channel->next_tx_seq = l2cap_next_ertm_seq_nr(channel->next_tx_seq); l2cap_ertm_next_tx_write_index(channel); + // set retransmission timer + btstack_run_loop_set_timer_handler(&tx_state->retransmission_timer, &l2cap_ertm_retransmission_timeout_callback); + 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_add_timer(&tx_state->retransmission_timer); // try to send l2cap_run(); return 0; @@ -972,6 +984,13 @@ static void l2cap_run(void){ l2cap_ertm_send_supervisor_frame(channel, control); continue; } + if (channel->send_supervisor_frame_receiver_ready_poll){ + channel->send_supervisor_frame_receiver_ready_poll = 0;; + log_info("Send S-Frame: RR %u with poll=1 ", channel->req_seq); + uint16_t control = l2cap_encanced_control_field_for_supevisor_frame( L2CAP_SUPERVISORY_FUNCTION_RR_RECEIVER_READY, 1, 0, channel->req_seq); + l2cap_ertm_send_supervisor_frame(channel, control); + continue; + } if (channel->send_supervisor_frame_receiver_not_ready){ channel->send_supervisor_frame_receiver_not_ready = 0;; log_info("Send S-Frame: RNR %u", channel->req_seq); @@ -1735,6 +1754,8 @@ static void l2cap_ertm_handle_req_seq(l2cap_channel_t * l2cap_channel, uint8_t r tx_state = &l2cap_channel->tx_packets_state[l2cap_channel->tx_read_index]; if ( ((req_seq - 1) & 0x3f) == tx_state->tx_seq){ log_info("RR seq %u == seq of oldest tx packet -> packet done", req_seq); + // stop retransmission timer + btstack_run_loop_remove_timer(&tx_state->retransmission_timer); l2cap_channel->tx_read_index++; if (l2cap_channel->tx_read_index >= l2cap_channel->num_rx_buffers){ l2cap_channel->tx_read_index = 0; diff --git a/src/l2cap.h b/src/l2cap.h index 1b9acfd40..8c999e9b3 100644 --- a/src/l2cap.h +++ b/src/l2cap.h @@ -122,6 +122,7 @@ typedef struct { } l2cap_ertm_rx_packet_state_t; typedef struct { + btstack_timer_source_t retransmission_timer; uint8_t tx_seq; uint16_t len; } l2cap_ertm_tx_packet_state_t; @@ -226,6 +227,9 @@ typedef struct { // receiver: send RR frame - flag uint8_t send_supervisor_frame_receiver_ready; + // receiver: send RR frame with poll bit set + uint8_t send_supervisor_frame_receiver_ready_poll; + // receiver: send RNR frame - flag uint8_t send_supervisor_frame_receiver_not_ready;