From 9b9654a8e8a760396af051ca572a0cd06db86050 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 8 Nov 2019 16:51:19 +0100 Subject: [PATCH] rlc v2: initial UE support --- cmake_targets/CMakeLists.txt | 11 +-- openair2/LAYER2/rlc_v2/rlc_oai_api.c | 101 ++++++++++++++++++++---- openair2/LAYER2/rlc_v2/rlc_ue_manager.c | 10 ++- openair2/LAYER2/rlc_v2/rlc_ue_manager.h | 4 +- 4 files changed, 105 insertions(+), 21 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 68849c0191..b5d2e0bc79 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1639,7 +1639,7 @@ set(NR_RRC_DIR ${OPENAIR2_DIR}/RRC/NR) set(NR_UE_RRC_DIR ${OPENAIR2_DIR}/RRC/NR_UE) set(PDCP_DIR ${OPENAIR2_DIR}/LAYER2/PDCP_v10.1.0) -set(RLC_ENB_V1 +set(RLC_V1 ${RLC_AM_DIR}/rlc_am.c ${RLC_AM_DIR}/rlc_am_init.c ${RLC_AM_DIR}/rlc_am_timer_poll_retransmit.c @@ -1669,7 +1669,7 @@ set(RLC_ENB_V1 ${RLC_DIR}/rlc_mpls.c ) -set(RLC_ENB_V2 +set(RLC_V2 ${OPENAIR2_DIR}/LAYER2/rlc_v2/rlc_oai_api.c ${OPENAIR2_DIR}/LAYER2/rlc_v2/asn1_utils.c ${OPENAIR2_DIR}/LAYER2/rlc_v2/rlc_ue_manager.c @@ -1701,7 +1701,7 @@ set(L2_SRC ${PDCP_DIR}/pdcp_util.c ${PDCP_DIR}/pdcp_security.c ${PDCP_DIR}/pdcp_netlink.c - ${RLC_ENB_V2} + ${RLC_V2} # ${RRC_DIR}/rrc_UE.c ${RRC_DIR}/rrc_eNB.c ${RRC_DIR}/rrc_eNB_endc.c @@ -1715,7 +1715,7 @@ set(L2_SRC ) set(L2_LTE_SRC - ${RLC_ENB_V1} + ${RLC_V1} ) set(L2_NR_SRC @@ -1738,6 +1738,7 @@ set(L2_SRC_UE ${PDCP_DIR}/pdcp_util.c ${PDCP_DIR}/pdcp_security.c ${PDCP_DIR}/pdcp_netlink.c + ${RLC_V2} ${RRC_DIR}/rrc_UE.c ${RRC_DIR}/rrc_common.c ${RRC_DIR}/L2_interface_common.c @@ -1752,7 +1753,7 @@ set(LTE_NR_L2_SRC_UE ${PDCP_DIR}/pdcp_util.c ${PDCP_DIR}/pdcp_security.c ${PDCP_DIR}/pdcp_netlink.c - ${RLC_ENB_V1} + ${RLC_V1} ) set(NR_L2_SRC_UE diff --git a/openair2/LAYER2/rlc_v2/rlc_oai_api.c b/openair2/LAYER2/rlc_v2/rlc_oai_api.c index d789e438be..d543a07ade 100644 --- a/openair2/LAYER2/rlc_v2/rlc_oai_api.c +++ b/openair2/LAYER2/rlc_v2/rlc_oai_api.c @@ -53,7 +53,7 @@ void mac_rlc_data_ind ( rlc_ue_t *ue; rlc_entity_t *rb; - if (module_idP != 0 || eNB_index != 0 || enb_flagP != 1 || MBMS_flagP != 0) { + if (module_idP != 0 || eNB_index != 0 || /*enb_flagP != 1 ||*/ MBMS_flagP != 0) { LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } @@ -102,6 +102,8 @@ tbs_size_t mac_rlc_data_req( int ret; rlc_ue_t *ue; rlc_entity_t *rb; + int is_enb; + int maxsize; rlc_manager_lock(rlc_ue_manager); ue = rlc_manager_get_ue(rlc_ue_manager, rntiP); @@ -114,7 +116,13 @@ tbs_size_t mac_rlc_data_req( if (rb != NULL) { rb->set_time(rb, rlc_current_time); - ret = rb->generate_pdu(rb, buffer_pP, ue->saved_status_ind_tb_size[channel_idP - 1]); + /* UE does not seem to use saved_status_ind_tb_size */ + is_enb = rlc_manager_get_enb_flag(rlc_ue_manager); + if (is_enb) + maxsize = ue->saved_status_ind_tb_size[channel_idP - 1]; + else + maxsize = tb_sizeP; + ret = rb->generate_pdu(rb, buffer_pP, maxsize); } else { LOG_E(RLC, "%s:%d:%s: fatal: data req for unknown RB\n", __FILE__, __LINE__, __FUNCTION__); exit(1); @@ -193,6 +201,61 @@ mac_rlc_status_resp_t mac_rlc_status_ind( return ret; } +rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind( + const module_id_t module_idP, + const rnti_t rntiP, + const eNB_index_t eNB_index, + const frame_t frameP, + const sub_frame_t subframeP, + const eNB_flag_t enb_flagP, + const logical_chan_id_t channel_idP) +{ + rlc_ue_t *ue; + rlc_buffer_occupancy_t ret; + rlc_entity_t *rb; + + if (enb_flagP) { + LOG_E(RLC, "Tx mac_rlc_get_buffer_occupancy_ind function is not implemented for eNB LcId=%u\n", channel_idP); + exit(1); + } + + /* TODO: handle time a bit more properly */ + if (rlc_current_time_last_frame != frameP || + rlc_current_time_last_subframe != subframeP) { + rlc_current_time++; + rlc_current_time_last_frame = frameP; + rlc_current_time_last_subframe = subframeP; + } + + rlc_manager_lock(rlc_ue_manager); + ue = rlc_manager_get_ue(rlc_ue_manager, rntiP); + + switch (channel_idP) { + case 1 ... 2: rb = ue->srb[channel_idP - 1]; break; + case 3 ... 7: rb = ue->drb[channel_idP - 3]; break; + default: rb = NULL; break; + } + + if (rb != NULL) { + rlc_entity_buffer_status_t buf_stat; + rb->set_time(rb, rlc_current_time); + /* 36.321 deals with BSR values up to 3000000 bytes, after what it + * reports '> 3000000' (table 6.1.3.1-2). Passing 4000000 is thus + * more than enough. + */ + buf_stat = rb->buffer_status(rb, 4000000); + ret = buf_stat.status_size + + buf_stat.retx_size + + buf_stat.tx_size; + } else { + ret = 0; + } + + rlc_manager_unlock(rlc_ue_manager); + + return ret; +} + int oai_emulation; rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, @@ -249,7 +312,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, return RLC_OP_STATUS_OK; } -int rlc_module_init(void) +int rlc_module_init(int enb_flag) { static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; static int inited = 0; @@ -263,7 +326,7 @@ int rlc_module_init(void) inited = 1; - rlc_ue_manager = new_rlc_ue_manager(); + rlc_ue_manager = new_rlc_ue_manager(enb_flag); if (pthread_mutex_unlock(&lock)) abort(); @@ -282,6 +345,7 @@ static void deliver_sdu(void *_ue, rlc_entity_t *entity, char *buf, int size) protocol_ctxt_t ctx; mem_block_t *memblock; int i; + int is_enb; /* is it SRB? */ for (i = 0; i < 2; i++) { @@ -327,11 +391,15 @@ rb_found: /* used fields? */ ctx.module_id = 0; ctx.rnti = ue->rnti; - ctx.enb_flag = 1; - T(T_ENB_RLC_UL, - T_INT(0 /*ctxt_pP->module_id*/), - T_INT(ue->rnti), T_INT(rb_id), T_INT(size)); + is_enb = rlc_manager_get_enb_flag(rlc_ue_manager); + ctx.enb_flag = is_enb; + + if (is_enb) { + T(T_ENB_RLC_UL, + T_INT(0 /*ctxt_pP->module_id*/), + T_INT(ue->rnti), T_INT(rb_id), T_INT(size)); + } if (!pdcp_data_ind(&ctx, is_srb, 0, rb_id, size, memblock)) { LOG_E(RLC, "%s:%d:%s: ERROR: pdcp_data_ind failed\n", __FILE__, __LINE__, __FUNCTION__); @@ -346,6 +414,7 @@ static void successful_delivery(void *_ue, rlc_entity_t *entity, int sdu_id) int is_srb; int rb_id; MessageDef *msg; + int is_enb; /* is it SRB? */ for (i = 0; i < 2; i++) { @@ -379,6 +448,10 @@ rb_found: if (is_srb == 0) return; + is_enb = rlc_manager_get_enb_flag(rlc_ue_manager); + if (!is_enb) + return; + msg = itti_alloc_new_message(TASK_RLC_ENB, RLC_SDU_INDICATION); RLC_SDU_INDICATION(msg).rnti = ue->rnti; RLC_SDU_INDICATION(msg).is_successful = 1; @@ -395,6 +468,7 @@ static void max_retx_reached(void *_ue, rlc_entity_t *entity) int is_srb; int rb_id; MessageDef *msg; + int is_enb; /* is it SRB? */ for (i = 0; i < 2; i++) { @@ -427,6 +501,10 @@ rb_found: if (is_srb == 0) return; + is_enb = rlc_manager_get_enb_flag(rlc_ue_manager); + if (!is_enb) + return; + msg = itti_alloc_new_message(TASK_RLC_ENB, RLC_SDU_INDICATION); RLC_SDU_INDICATION(msg).rnti = ue->rnti; RLC_SDU_INDICATION(msg).is_successful = 0; @@ -708,7 +786,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP int rnti = ctxt_pP->rnti; int i; - if (ctxt_pP->enb_flag != 1 || ctxt_pP->module_id != 0 /*|| + if (/*ctxt_pP->enb_flag != 1 ||*/ ctxt_pP->module_id != 0 /*|| ctxt_pP->instance != 0 || ctxt_pP->eNB_index != 0 || ctxt_pP->configured != 1 || ctxt_pP->brOption != 0 */) { LOG_E(RLC, "%s: ctxt_pP not handled (%d %d %d %d %d %d)\n", __FUNCTION__, @@ -757,10 +835,6 @@ rlc_op_status_t rrc_rlc_config_req ( LOG_E(RLC, "%s:%d:%s: todo (mbms not supported)\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } - if (!ctxt_pP->enb_flag) { - LOG_E(RLC, "%s:%d:%s: todo (only eNB supported, not UE)\n", __FILE__, __LINE__, __FUNCTION__); - exit(1); - } if (actionP != CONFIG_ACTION_REMOVE) { LOG_E(RLC, "%s:%d:%s: todo (only CONFIG_ACTION_REMOVE supported)\n", __FILE__, __LINE__, __FUNCTION__); exit(1); @@ -819,4 +893,3 @@ rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x) return RLC_OP_STATUS_OK; } - diff --git a/openair2/LAYER2/rlc_v2/rlc_ue_manager.c b/openair2/LAYER2/rlc_v2/rlc_ue_manager.c index 1d0884bb9c..1fd366fda1 100644 --- a/openair2/LAYER2/rlc_v2/rlc_ue_manager.c +++ b/openair2/LAYER2/rlc_v2/rlc_ue_manager.c @@ -31,9 +31,10 @@ typedef struct { pthread_mutex_t lock; rlc_ue_t **ue_list; int ue_count; + int enb_flag; } rlc_ue_manager_internal_t; -rlc_ue_manager_t *new_rlc_ue_manager(void) +rlc_ue_manager_t *new_rlc_ue_manager(int enb_flag) { rlc_ue_manager_internal_t *ret; @@ -44,10 +45,17 @@ rlc_ue_manager_t *new_rlc_ue_manager(void) } if (pthread_mutex_init(&ret->lock, NULL)) abort(); + ret->enb_flag = enb_flag; return ret; } +int rlc_manager_get_enb_flag(rlc_ue_manager_t *_m) +{ + rlc_ue_manager_internal_t *m = _m; + return m->enb_flag; +} + void rlc_manager_lock(rlc_ue_manager_t *_m) { rlc_ue_manager_internal_t *m = _m; diff --git a/openair2/LAYER2/rlc_v2/rlc_ue_manager.h b/openair2/LAYER2/rlc_v2/rlc_ue_manager.h index 7d5ef18b1e..8cef8c1c3a 100644 --- a/openair2/LAYER2/rlc_v2/rlc_ue_manager.h +++ b/openair2/LAYER2/rlc_v2/rlc_ue_manager.h @@ -40,7 +40,9 @@ typedef struct rlc_ue_t { /* manager functions */ /***********************************************************************/ -rlc_ue_manager_t *new_rlc_ue_manager(void); +rlc_ue_manager_t *new_rlc_ue_manager(int enb_flag); + +int rlc_manager_get_enb_flag(rlc_ue_manager_t *m); void rlc_manager_lock(rlc_ue_manager_t *m); void rlc_manager_unlock(rlc_ue_manager_t *m);