From 596282403856f723ff3396ba527b912e3299adc6 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Thu, 7 Apr 2022 16:34:16 +0200 Subject: [PATCH] Integrate true reporting of buffer availability of RLC(DU) towards the CU --- openair2/F1AP/f1ap_du_task.c | 2 +- openair2/F1AP/f1ap_itti_messaging.c | 2 +- openair2/LAYER2/nr_rlc/nr_rlc_entity.c | 51 ++++++++++++----------- openair2/LAYER2/nr_rlc/nr_rlc_entity.h | 2 + openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c | 6 +++ openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h | 1 + openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c | 6 +++ openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h | 1 + openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c | 6 +++ openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h | 1 + openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 34 ++++++++++++++- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h | 6 ++- openair2/RRC/NR/rrc_gNB.c | 2 +- openair3/ocp-gtpu/gtp_itf.cpp | 5 ++- 14 files changed, 94 insertions(+), 31 deletions(-) diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index 24a1c44697..4982f7617b 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -175,7 +175,7 @@ void *F1AP_DU_task(void *arg) { break; case F1AP_UL_RRC_MESSAGE: // to rrc - LOG_I(F1AP, "DU Task Received F1AP_UL_RRC_MESSAGE\n"); + LOG_D(F1AP, "DU Task Received F1AP_UL_RRC_MESSAGE\n"); if (RC.nrrrc && RC.nrrrc[0]->node_type == ngran_gNB_DU) { DU_send_UL_NR_RRC_MESSAGE_TRANSFER(myInstance, diff --git a/openair2/F1AP/f1ap_itti_messaging.c b/openair2/F1AP/f1ap_itti_messaging.c index 21096a6518..e45edcc3a3 100644 --- a/openair2/F1AP/f1ap_itti_messaging.c +++ b/openair2/F1AP/f1ap_itti_messaging.c @@ -32,7 +32,7 @@ void f1ap_itti_send_sctp_data_req(bool isCu, instance_t instance, uint8_t *buffe sctp_data_req->buffer = buffer; sctp_data_req->buffer_length = buffer_length; sctp_data_req->stream = stream; - LOG_I(F1AP, "Sending ITTI message to SCTP Task\n"); + LOG_D(F1AP, "Sending ITTI message to SCTP Task\n"); itti_send_msg_to_task(TASK_SCTP, instance, message_p); } diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity.c index fefe2fc77d..1883bbdd6c 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity.c @@ -77,14 +77,15 @@ nr_rlc_entity_t *new_nr_rlc_entity_am( ret->sn_modulus = 1 << ret->sn_field_length; ret->window_size = ret->sn_modulus / 2; - ret->common.recv_pdu = nr_rlc_entity_am_recv_pdu; - ret->common.buffer_status = nr_rlc_entity_am_buffer_status; - ret->common.generate_pdu = nr_rlc_entity_am_generate_pdu; - ret->common.recv_sdu = nr_rlc_entity_am_recv_sdu; - ret->common.set_time = nr_rlc_entity_am_set_time; - ret->common.discard_sdu = nr_rlc_entity_am_discard_sdu; - ret->common.reestablishment = nr_rlc_entity_am_reestablishment; - ret->common.delete = nr_rlc_entity_am_delete; + ret->common.recv_pdu = nr_rlc_entity_am_recv_pdu; + ret->common.buffer_status = nr_rlc_entity_am_buffer_status; + ret->common.generate_pdu = nr_rlc_entity_am_generate_pdu; + ret->common.recv_sdu = nr_rlc_entity_am_recv_sdu; + ret->common.set_time = nr_rlc_entity_am_set_time; + ret->common.discard_sdu = nr_rlc_entity_am_discard_sdu; + ret->common.reestablishment = nr_rlc_entity_am_reestablishment; + ret->common.delete = nr_rlc_entity_am_delete; + ret->common.available_tx_space = nr_rlc_entity_am_available_tx_space; ret->common.deliver_sdu = deliver_sdu; ret->common.deliver_sdu_data = deliver_sdu_data; @@ -127,14 +128,15 @@ nr_rlc_entity_t *new_nr_rlc_entity_um( ret->sn_modulus = 1 << ret->sn_field_length; ret->window_size = ret->sn_modulus / 2; - ret->common.recv_pdu = nr_rlc_entity_um_recv_pdu; - ret->common.buffer_status = nr_rlc_entity_um_buffer_status; - ret->common.generate_pdu = nr_rlc_entity_um_generate_pdu; - ret->common.recv_sdu = nr_rlc_entity_um_recv_sdu; - ret->common.set_time = nr_rlc_entity_um_set_time; - ret->common.discard_sdu = nr_rlc_entity_um_discard_sdu; - ret->common.reestablishment = nr_rlc_entity_um_reestablishment; - ret->common.delete = nr_rlc_entity_um_delete; + ret->common.recv_pdu = nr_rlc_entity_um_recv_pdu; + ret->common.buffer_status = nr_rlc_entity_um_buffer_status; + ret->common.generate_pdu = nr_rlc_entity_um_generate_pdu; + ret->common.recv_sdu = nr_rlc_entity_um_recv_sdu; + ret->common.set_time = nr_rlc_entity_um_set_time; + ret->common.discard_sdu = nr_rlc_entity_um_discard_sdu; + ret->common.reestablishment = nr_rlc_entity_um_reestablishment; + ret->common.delete = nr_rlc_entity_um_delete; + ret->common.available_tx_space = nr_rlc_entity_um_available_tx_space; ret->common.deliver_sdu = deliver_sdu; ret->common.deliver_sdu_data = deliver_sdu_data; @@ -158,14 +160,15 @@ nr_rlc_entity_t *new_nr_rlc_entity_tm( ret->tx_maxsize = tx_maxsize; - ret->common.recv_pdu = nr_rlc_entity_tm_recv_pdu; - ret->common.buffer_status = nr_rlc_entity_tm_buffer_status; - ret->common.generate_pdu = nr_rlc_entity_tm_generate_pdu; - ret->common.recv_sdu = nr_rlc_entity_tm_recv_sdu; - ret->common.set_time = nr_rlc_entity_tm_set_time; - ret->common.discard_sdu = nr_rlc_entity_tm_discard_sdu; - ret->common.reestablishment = nr_rlc_entity_tm_reestablishment; - ret->common.delete = nr_rlc_entity_tm_delete; + ret->common.recv_pdu = nr_rlc_entity_tm_recv_pdu; + ret->common.buffer_status = nr_rlc_entity_tm_buffer_status; + ret->common.generate_pdu = nr_rlc_entity_tm_generate_pdu; + ret->common.recv_sdu = nr_rlc_entity_tm_recv_sdu; + ret->common.set_time = nr_rlc_entity_tm_set_time; + ret->common.discard_sdu = nr_rlc_entity_tm_discard_sdu; + ret->common.reestablishment = nr_rlc_entity_tm_reestablishment; + ret->common.delete = nr_rlc_entity_tm_delete; + ret->common.available_tx_space = nr_rlc_entity_tm_available_tx_space; ret->common.deliver_sdu = deliver_sdu; ret->common.deliver_sdu_data = deliver_sdu_data; diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity.h index b9b638fe07..5cd3bee650 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity.h @@ -50,6 +50,8 @@ typedef struct nr_rlc_entity_t { void (*delete)(struct nr_rlc_entity_t *entity); + int (*available_tx_space)(struct nr_rlc_entity_t *entity); + /* callbacks provided to the RLC module */ void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, char *buf, int size); diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c index af8cb5715a..ba7a4a82ee 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c @@ -1887,3 +1887,9 @@ void nr_rlc_entity_am_delete(nr_rlc_entity_t *_entity) clear_entity(entity); free(entity); } + +int nr_rlc_entity_am_available_tx_space(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + return entity->tx_maxsize - entity->tx_size; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h index 453fe87026..d36876ed72 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h @@ -102,5 +102,6 @@ void nr_rlc_entity_am_set_time(nr_rlc_entity_t *entity, uint64_t now); void nr_rlc_entity_am_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id); void nr_rlc_entity_am_reestablishment(nr_rlc_entity_t *_entity); void nr_rlc_entity_am_delete(nr_rlc_entity_t *entity); +int nr_rlc_entity_am_available_tx_space(nr_rlc_entity_t *entity); #endif /* _NR_RLC_ENTITY_AM_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c index 75408276d1..f85edbba0f 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c @@ -174,3 +174,9 @@ void nr_rlc_entity_tm_delete(nr_rlc_entity_t *_entity) clear_entity(entity); free(entity); } + +int nr_rlc_entity_tm_available_tx_space(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; + return entity->tx_maxsize - entity->tx_size; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h index 7c8c7e40a0..7918703799 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h @@ -51,5 +51,6 @@ void nr_rlc_entity_tm_set_time(nr_rlc_entity_t *entity, uint64_t now); void nr_rlc_entity_tm_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id); void nr_rlc_entity_tm_reestablishment(nr_rlc_entity_t *_entity); void nr_rlc_entity_tm_delete(nr_rlc_entity_t *entity); +int nr_rlc_entity_tm_available_tx_space(nr_rlc_entity_t *entity); #endif /* _NR_RLC_ENTITY_TM_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c index b34a7dc894..5f2fd592a0 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c @@ -695,3 +695,9 @@ void nr_rlc_entity_um_delete(nr_rlc_entity_t *_entity) clear_entity(entity); free(entity); } + +int nr_rlc_entity_um_available_tx_space(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + return entity->tx_maxsize - entity->tx_size; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h index 21063a1ea1..c40e72ada1 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h @@ -75,5 +75,6 @@ void nr_rlc_entity_um_set_time(nr_rlc_entity_t *entity, uint64_t now); void nr_rlc_entity_um_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id); void nr_rlc_entity_um_reestablishment(nr_rlc_entity_t *_entity); void nr_rlc_entity_um_delete(nr_rlc_entity_t *entity); +int nr_rlc_entity_um_available_tx_space(nr_rlc_entity_t *entity); #endif /* _NR_RLC_ENTITY_UM_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index e033aa33b7..dea72d6e42 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -101,6 +101,7 @@ void nr_drb_config(struct NR_RLC_Config *rlc_Config, NR_RLC_Config_PR rlc_config switch (rlc_config_pr){ case NR_RLC_Config_PR_um_Bi_Directional: // RLC UM Bi-directional Bearer configuration + LOG_I(RLC, "RLC UM Bi-directional Bearer configuration selected \n"); rlc_Config->choice.um_Bi_Directional = calloc(1, sizeof(*rlc_Config->choice.um_Bi_Directional)); rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = calloc(1, sizeof(*rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength)); *rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12; @@ -397,6 +398,35 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, return RLC_OP_STATUS_OK; } +int nr_rlc_get_available_tx_space( + const rnti_t rntiP, + const logical_chan_id_t channel_idP) +{ + nr_rlc_ue_t *ue; + nr_rlc_entity_t *rb; + int ret; + + nr_rlc_manager_lock(nr_rlc_ue_manager); + ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP); + + switch (channel_idP) { + case 1 ... 3: rb = ue->srb[channel_idP - 1]; break; + case 4 ... 8: rb = ue->drb[channel_idP - 1]; break; + default: rb = NULL; break; + } + + if (rb != NULL) { + ret = rb->available_tx_space(rb); + } else { + LOG_E(RLC, "[%s] Radio Bearer (channel ID %d) is NULL for UE with rntiP %x\n", __FUNCTION__, channel_idP, rntiP); + ret = -1; + } + + nr_rlc_manager_unlock(nr_rlc_ue_manager); + + return ret; +} + int rlc_module_init(int enb_flag) { static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; @@ -850,11 +880,11 @@ static void add_drb_um(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_ exit(1); } - if (channel_id != drb_id + 3) { + /*if (channel_id != drb_id + 3) { LOG_E(RLC, "%s:%d:%s: todo, remove this limitation\n", __FILE__, __LINE__, __FUNCTION__); exit(1); - } + }*/ logical_channel_group = *l->ul_SpecificParameters->logicalChannelGroup; diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h index 6b3c228163..92fbba9bec 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h @@ -46,4 +46,8 @@ void nr_rlc_bearer_init(NR_RLC_BearerConfig_t *RLC_BearerConfig, NR_RLC_BearerCo void nr_drb_config(struct NR_RLC_Config *rlc_Config, NR_RLC_Config_PR rlc_config_pr); -void nr_rlc_bearer_init_ul_spec(struct NR_LogicalChannelConfig *mac_LogicalChannelConfig); \ No newline at end of file +void nr_rlc_bearer_init_ul_spec(struct NR_LogicalChannelConfig *mac_LogicalChannelConfig); + +int nr_rlc_get_available_tx_space( + const rnti_t rntiP, + const logical_chan_id_t channel_idP); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index d7ff9492a5..11718d49b2 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -3497,7 +3497,7 @@ static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, co gtpv1u_DU_buffer_report_req_t *req=>PV1U_DU_BUFFER_REPORT_REQ(msg); req->pdusession_id = drb_id; req->rnti = rnti; - req->buffer_availability = 1000000; //Hardcoding to be removed and read the actual RLC buffer availability instead + req->buffer_availability = 10000000; //Hardcoding to be removed and read the actual RLC buffer availability instead extern instance_t DUuniqInstance; itti_send_msg_to_task(TASK_GTPV1_U, DUuniqInstance, msg); diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index 20db486561..822825c75a 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -17,6 +17,7 @@ extern "C" { #include #include #include +#include #include "openair2/SDAP/nr_sdap/nr_sdap_gnb.h" //#include @@ -999,6 +1000,8 @@ static int Gtpv1uHandleGpdu(int h, LOG_E(GTPU,"[%d] down layer refused incoming packet\n", h); if(NR_PDCP_PDU_SN > 0 && NR_PDCP_PDU_SN %5 ==0){ LOG_D (GTPU, "Create and send DL DATA Delivery status for the previously received PDU, NR_PDCP_PDU_SN: %u \n", NR_PDCP_PDU_SN); + int rlc_tx_buffer_space = nr_rlc_get_available_tx_space(ctxt.rnti, rb_id); + LOG_D(GTPU, "Available buffer size in RLC for Tx: %d \n", rlc_tx_buffer_space); /*Total size of DDD_status PDU = 1 octet to report extension header length * size of mandatory part + 3 octets for highest transmitted/delivered PDCP SN * 1 octet for padding + 1 octet for next extension header type, @@ -1010,7 +1013,7 @@ static int Gtpv1uHandleGpdu(int h, DlDataDeliveryStatus.deliveredPdcpSn = 0; DlDataDeliveryStatus.transmittedPdcpSn= 1; DlDataDeliveryStatus.pduType = 1; - DlDataDeliveryStatus.drbBufferSize = htonl(1000000); //hardcoded for now but normally we should extract it from RLC + DlDataDeliveryStatus.drbBufferSize = htonl(rlc_tx_buffer_space); //htonl(10000000); //hardcoded for now but normally we should extract it from RLC memcpy(extensionHeader->buffer+1, &DlDataDeliveryStatus, sizeof(DlDataDeliveryStatus_flagsT)); uint8_t offset = sizeof(DlDataDeliveryStatus_flagsT)+1;