From 82e83bc6a61363ebab3bc5444c3d0397f17e381c Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 28 Sep 2023 10:40:11 +0200 Subject: [PATCH] nr rlc am: bugfix: correc usage of tx_next tx_next was increased only when all segments of an SDU were sent to lower layers. This may lead to a situation where the receive entity transmits a control PDU that is rejected because it sets its ACK to tx_next+1 (if all segments were not transmitted when the control PDU is sent). What is done now is to increase tx_next as soon as we send the first segment of an SDU to lower layers. A control PDU received from the receive entity is now accepted and processed. Specifications (38.322 5.2.3.1.1) say to increase tx_next when the RLC entity receives an SDU from upper layers. But for us, since the buffering of SDUs is done in the RLC layer and since the buffer size may be big, we may increase tx_next too much. The choice has been made to increase it only when we transmit an SDU to lower layers. We may change this logic if needed. (But it won't be simple.) --- openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c index c2d41cedb4..91985393cb 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c @@ -1638,7 +1638,10 @@ static int generate_tx_pdu(nr_rlc_entity_am_t *entity, char *buffer, int size) entity->common.bstatus.tx_size -= pdu_size; /* assign SN to SDU */ - sdu->sdu->sn = entity->tx_next; + if (sdu->sdu->sn == -1) { + sdu->sdu->sn = entity->tx_next; + entity->tx_next = (entity->tx_next + 1) % entity->sn_modulus; + } /* segment if necessary */ if (pdu_size > size) { @@ -1656,10 +1659,6 @@ static int generate_tx_pdu(nr_rlc_entity_am_t *entity, char *buffer, int size) + next_sdu->size; } - /* update tx_next if the SDU segment is the last */ - if (sdu->is_last) - entity->tx_next = (entity->tx_next + 1) % entity->sn_modulus; - /* put SDU/SDU segment in the wait list */ /* speedup: check end of wait list, probably the new sdu comes after */ if (entity->wait_end == NULL