|
|
|
@@ -118,10 +118,10 @@ static nr_rlc_entity_t *get_rlc_entity_from_lcid(nr_rlc_ue_t *ue, logical_chan_i
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nr_rlc_release_entity(int rnti, logical_chan_id_t channel_id)
|
|
|
|
|
void nr_rlc_release_entity(int ue_id, logical_chan_id_t channel_id)
|
|
|
|
|
{
|
|
|
|
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
|
|
|
|
if (channel_id == 0) {
|
|
|
|
|
if (ue->srb0 != NULL) {
|
|
|
|
|
free(ue->srb0->deliver_sdu_data);
|
|
|
|
@@ -136,7 +136,7 @@ void nr_rlc_release_entity(int rnti, logical_chan_id_t channel_id)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mac_rlc_data_ind(const module_id_t module_idP,
|
|
|
|
|
const rnti_t rntiP,
|
|
|
|
|
const uint16_t ue_id,
|
|
|
|
|
const eNB_index_t eNB_index,
|
|
|
|
|
const frame_t frameP,
|
|
|
|
|
const eNB_flag_t enb_flagP,
|
|
|
|
@@ -153,11 +153,11 @@ void mac_rlc_data_ind(const module_id_t module_idP,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (enb_flagP)
|
|
|
|
|
T(T_ENB_RLC_MAC_UL, T_INT(module_idP), T_INT(rntiP),
|
|
|
|
|
T(T_ENB_RLC_MAC_UL, T_INT(module_idP), T_INT(ue_id),
|
|
|
|
|
T_INT(channel_idP), T_INT(tb_sizeP));
|
|
|
|
|
|
|
|
|
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
|
|
|
|
|
|
|
|
|
if(ue == NULL)
|
|
|
|
|
LOG_I(RLC, "RLC instance for the given UE was not found \n");
|
|
|
|
@@ -169,8 +169,7 @@ void mac_rlc_data_ind(const module_id_t module_idP,
|
|
|
|
|
rb->set_time(rb, nr_rlc_current_time);
|
|
|
|
|
rb->recv_pdu(rb, buffer_pP, tb_sizeP);
|
|
|
|
|
} else {
|
|
|
|
|
LOG_E(RLC, "Fatal: no RB found (channel ID %d RNTI %d)\n",
|
|
|
|
|
channel_idP, rntiP);
|
|
|
|
|
LOG_E(RLC, "Fatal: no RB found (channel ID %d UE ID %d)\n", channel_idP, ue_id);
|
|
|
|
|
// exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -178,7 +177,7 @@ void mac_rlc_data_ind(const module_id_t module_idP,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tbs_size_t mac_rlc_data_req(const module_id_t module_idP,
|
|
|
|
|
const rnti_t rntiP,
|
|
|
|
|
const uint16_t ue_id,
|
|
|
|
|
const eNB_index_t eNB_index,
|
|
|
|
|
const frame_t frameP,
|
|
|
|
|
const eNB_flag_t enb_flagP,
|
|
|
|
@@ -193,7 +192,7 @@ tbs_size_t mac_rlc_data_req(const module_id_t module_idP,
|
|
|
|
|
int maxsize;
|
|
|
|
|
|
|
|
|
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
|
|
|
|
nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, channel_idP);
|
|
|
|
|
|
|
|
|
|
if (rb != NULL) {
|
|
|
|
@@ -209,14 +208,14 @@ tbs_size_t mac_rlc_data_req(const module_id_t module_idP,
|
|
|
|
|
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
|
|
|
|
|
|
|
|
|
if (enb_flagP)
|
|
|
|
|
T(T_ENB_RLC_MAC_DL, T_INT(module_idP), T_INT(rntiP),
|
|
|
|
|
T(T_ENB_RLC_MAC_DL, T_INT(module_idP), T_INT(ue_id),
|
|
|
|
|
T_INT(channel_idP), T_INT(ret));
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mac_rlc_status_resp_t mac_rlc_status_ind(const module_id_t module_idP,
|
|
|
|
|
const rnti_t rntiP,
|
|
|
|
|
const uint16_t ue_id,
|
|
|
|
|
const eNB_index_t eNB_index,
|
|
|
|
|
const frame_t frameP,
|
|
|
|
|
const sub_frame_t subframeP,
|
|
|
|
@@ -229,7 +228,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind(const module_id_t module_idP,
|
|
|
|
|
mac_rlc_status_resp_t ret;
|
|
|
|
|
|
|
|
|
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
|
|
|
|
nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, channel_idP);
|
|
|
|
|
|
|
|
|
|
if (rb != NULL) {
|
|
|
|
@@ -246,7 +245,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind(const module_id_t module_idP,
|
|
|
|
|
+ buf_stat.tx_size;
|
|
|
|
|
} else {
|
|
|
|
|
if (!(frameP%128) || channel_idP == 0) //to suppress this warning message
|
|
|
|
|
LOG_W(RLC, "[%s] Radio Bearer (channel ID %d) is NULL for UE with rntiP %x\n", __FUNCTION__, channel_idP, rntiP);
|
|
|
|
|
LOG_W(RLC, "Radio Bearer (channel ID %d) is NULL for UE %d\n", channel_idP, ue_id);
|
|
|
|
|
ret.bytes_in_buffer = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -261,7 +260,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind(const module_id_t module_idP,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(const module_id_t module_idP,
|
|
|
|
|
const rnti_t rntiP,
|
|
|
|
|
const uint16_t ue_id,
|
|
|
|
|
const eNB_index_t eNB_index,
|
|
|
|
|
const frame_t frameP,
|
|
|
|
|
const sub_frame_t subframeP,
|
|
|
|
@@ -284,7 +283,7 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(const module_id_t module
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
|
|
|
|
nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, channel_idP);
|
|
|
|
|
|
|
|
|
|
if (rb != NULL) {
|
|
|
|
@@ -302,7 +301,7 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(const module_id_t module
|
|
|
|
|
+ buf_stat.tx_size;
|
|
|
|
|
} else {
|
|
|
|
|
if (!(frameP%128)) //to suppress this warning message
|
|
|
|
|
LOG_W(RLC, "[%s] Radio Bearer (channel ID %d) is NULL for UE with rntiP %x\n", __FUNCTION__, channel_idP, rntiP);
|
|
|
|
|
LOG_W(RLC, "Radio Bearer (channel ID %d) is NULL for UE %d\n", channel_idP, ue_id);
|
|
|
|
|
ret = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -322,18 +321,18 @@ rlc_op_status_t rlc_data_req(const protocol_ctxt_t *const ctxt_pP,
|
|
|
|
|
const uint32_t *const sourceL2Id,
|
|
|
|
|
const uint32_t *const destinationL2Id)
|
|
|
|
|
{
|
|
|
|
|
int rnti = ctxt_pP->rntiMaybeUEid;
|
|
|
|
|
int ue_id = ctxt_pP->rntiMaybeUEid;
|
|
|
|
|
nr_rlc_ue_t *ue;
|
|
|
|
|
nr_rlc_entity_t *rb;
|
|
|
|
|
|
|
|
|
|
LOG_D(RLC, "rnti %d srb_flag %d rb_id %ld mui %d confirm %d sdu_size %d MBMS_flag %d\n",
|
|
|
|
|
rnti, srb_flagP, rb_idP, muiP, confirmP, sdu_sizeP, MBMS_flagP);
|
|
|
|
|
LOG_D(RLC, "UE %d srb_flag %d rb_id %ld mui %d confirm %d sdu_size %d MBMS_flag %d\n",
|
|
|
|
|
ue_id, srb_flagP, rb_idP, muiP, confirmP, sdu_sizeP, MBMS_flagP);
|
|
|
|
|
|
|
|
|
|
if (ctxt_pP->enb_flag)
|
|
|
|
|
T(T_ENB_RLC_DL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rntiMaybeUEid), T_INT(rb_idP), T_INT(sdu_sizeP));
|
|
|
|
|
|
|
|
|
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
|
|
|
|
ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti);
|
|
|
|
|
ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
|
|
|
|
|
|
|
|
|
rb = NULL;
|
|
|
|
|
|
|
|
|
@@ -359,19 +358,18 @@ 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)
|
|
|
|
|
int nr_rlc_get_available_tx_space(const int ue_id, const logical_chan_id_t channel_idP)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
|
|
|
|
nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, channel_idP);
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
LOG_E(RLC, "Radio Bearer (channel ID %d) is NULL for UE %d\n", channel_idP, ue_id);
|
|
|
|
|
ret = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -440,13 +438,11 @@ static void deliver_sdu(void *_ue, nr_rlc_entity_t *entity, char *buf, int size)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LOG_E(RLC, "%s:%d:%s: fatal, no RB found for ue %d\n",
|
|
|
|
|
__FILE__, __LINE__, __FUNCTION__, ue->rnti);
|
|
|
|
|
LOG_E(RLC, "Fatal, no RB found for ue %d\n", ue->ue_id);
|
|
|
|
|
exit(1);
|
|
|
|
|
|
|
|
|
|
rb_found:
|
|
|
|
|
LOG_D(RLC, "%s:%d:%s: delivering SDU (rnti %d is_srb %d rb_id %d) size %d\n",
|
|
|
|
|
__FILE__, __LINE__, __FUNCTION__, ue->rnti, is_srb, rb_id, size);
|
|
|
|
|
LOG_D(RLC, "Delivering SDU (ue_id %d is_srb %d rb_id %d) size %d\n", ue->ue_id, is_srb, rb_id, size);
|
|
|
|
|
|
|
|
|
|
/* unused fields? */
|
|
|
|
|
ctx.instance = 0;
|
|
|
|
@@ -461,9 +457,9 @@ rb_found:
|
|
|
|
|
ctx.module_id = 0;
|
|
|
|
|
/* CU (PDCP, RRC, SDAP) use a different ID than RNTI, so below set the CU UE
|
|
|
|
|
* ID if in gNB, else use RNTI normally */
|
|
|
|
|
ctx.rntiMaybeUEid = ue->rnti;
|
|
|
|
|
ctx.rntiMaybeUEid = ue->ue_id;
|
|
|
|
|
if (is_enb) {
|
|
|
|
|
f1_ue_data_t ue_data = du_get_f1_ue_data(ue->rnti);
|
|
|
|
|
f1_ue_data_t ue_data = du_get_f1_ue_data(ue->ue_id);
|
|
|
|
|
ctx.rntiMaybeUEid = ue_data.secondary_ue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -472,7 +468,7 @@ rb_found:
|
|
|
|
|
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));
|
|
|
|
|
T_INT(ue->ue_id), T_INT(rb_id), T_INT(size));
|
|
|
|
|
|
|
|
|
|
const ngran_node_t type = RC.nrrrc[0 /*ctxt_pP->module_id*/]->node_type;
|
|
|
|
|
AssertFatal(!NODE_IS_CU(type),
|
|
|
|
@@ -491,7 +487,7 @@ rb_found:
|
|
|
|
|
uint8_t *message_buffer = itti_malloc (TASK_RLC_ENB, TASK_DU_F1, size);
|
|
|
|
|
memcpy (message_buffer, buf, size);
|
|
|
|
|
F1AP_UL_RRC_MESSAGE(msg).gNB_CU_ue_id = ctx.rntiMaybeUEid;
|
|
|
|
|
F1AP_UL_RRC_MESSAGE(msg).gNB_DU_ue_id = ue->rnti;
|
|
|
|
|
F1AP_UL_RRC_MESSAGE(msg).gNB_DU_ue_id = ue->ue_id;
|
|
|
|
|
F1AP_UL_RRC_MESSAGE(msg).srb_id = rb_id;
|
|
|
|
|
F1AP_UL_RRC_MESSAGE(msg).rrc_container = message_buffer;
|
|
|
|
|
F1AP_UL_RRC_MESSAGE(msg).rrc_container_length = size;
|
|
|
|
@@ -504,8 +500,8 @@ rb_found:
|
|
|
|
|
req->buffer=(uint8_t*)(req+1);
|
|
|
|
|
memcpy(req->buffer,buf,size);
|
|
|
|
|
req->length=size;
|
|
|
|
|
req->offset=0;
|
|
|
|
|
req->ue_id=ue->rnti; // use RNTI here, which GTP will use to look up TEID
|
|
|
|
|
req->offset = 0;
|
|
|
|
|
req->ue_id = ue->ue_id;
|
|
|
|
|
req->bearer_id=rb_id;
|
|
|
|
|
LOG_D(RLC, "Received uplink user-plane traffic at RLC-DU to be sent to the CU, size %d \n", size);
|
|
|
|
|
extern instance_t DUuniqInstance;
|
|
|
|
@@ -558,8 +554,7 @@ static void successful_delivery(void *_ue, nr_rlc_entity_t *entity, int sdu_id)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LOG_E(RLC, "%s:%d:%s: fatal, no RB found for ue %d\n",
|
|
|
|
|
__FILE__, __LINE__, __FUNCTION__, ue->rnti);
|
|
|
|
|
LOG_E(RLC, "Fatal, no RB found for ue %d\n", ue->ue_id);
|
|
|
|
|
exit(1);
|
|
|
|
|
|
|
|
|
|
rb_found:
|
|
|
|
@@ -616,8 +611,7 @@ static void max_retx_reached(void *_ue, nr_rlc_entity_t *entity)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LOG_E(RLC, "%s:%d:%s: fatal, no RB found for ue %d\n",
|
|
|
|
|
__FILE__, __LINE__, __FUNCTION__, ue->rnti);
|
|
|
|
|
LOG_E(RLC, "Fatal, no RB found for ue %d\n", ue->ue_id);
|
|
|
|
|
exit(1);
|
|
|
|
|
|
|
|
|
|
rb_found:
|
|
|
|
@@ -644,10 +638,10 @@ rb_found:
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nr_rlc_reestablish_entity(int rnti, int lc_id)
|
|
|
|
|
void nr_rlc_reestablish_entity(int ue_id, int lc_id)
|
|
|
|
|
{
|
|
|
|
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
|
|
|
|
|
|
|
|
|
if (ue == NULL) {
|
|
|
|
|
LOG_E(RLC, "RLC instance for the given UE was not found \n");
|
|
|
|
@@ -663,10 +657,11 @@ void nr_rlc_reestablish_entity(int rnti, int lc_id)
|
|
|
|
|
}
|
|
|
|
|
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
|
|
|
|
}
|
|
|
|
|
void nr_rlc_reconfigure_entity(int rnti, int lc_id, NR_RLC_Config_t *rlc_Config)
|
|
|
|
|
|
|
|
|
|
void nr_rlc_reconfigure_entity(int ue_id, int lc_id, NR_RLC_Config_t *rlc_Config)
|
|
|
|
|
{
|
|
|
|
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
|
|
|
|
|
|
|
|
|
if (ue == NULL)
|
|
|
|
|
LOG_E(RLC, "RLC instance for the given UE was not found \n");
|
|
|
|
@@ -737,7 +732,7 @@ void nr_rlc_reconfigure_entity(int rnti, int lc_id, NR_RLC_Config_t *rlc_Config)
|
|
|
|
|
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig)
|
|
|
|
|
void nr_rlc_add_srb(int ue_id, int srb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig)
|
|
|
|
|
{
|
|
|
|
|
struct NR_RLC_Config *r = rlc_BearerConfig->rlc_Config;
|
|
|
|
|
int t_status_prohibit;
|
|
|
|
@@ -778,7 +773,7 @@ void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_Beare
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
|
|
|
|
AssertFatal(rlc_BearerConfig->servedRadioBearer &&
|
|
|
|
|
(rlc_BearerConfig->servedRadioBearer->present ==
|
|
|
|
|
NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity),
|
|
|
|
@@ -787,7 +782,7 @@ void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_Beare
|
|
|
|
|
ue->lcid2rb[local_id].type = NR_RLC_SRB;
|
|
|
|
|
ue->lcid2rb[local_id].choice.srb_id = rlc_BearerConfig->servedRadioBearer->choice.srb_Identity;
|
|
|
|
|
if (ue->srb[srb_id-1] != NULL) {
|
|
|
|
|
LOG_E(RLC, "%s:%d:%s: SRB %d already exists for UE with RNTI %04x, do nothing\n", __FILE__, __LINE__, __FUNCTION__, srb_id, rnti);
|
|
|
|
|
LOG_E(RLC, "SRB %d already exists for UE %d, do nothing\n", srb_id, ue_id);
|
|
|
|
|
} else {
|
|
|
|
|
nr_rlc_entity_t *nr_rlc_am = new_nr_rlc_entity_am(RLC_RX_MAXSIZE,
|
|
|
|
|
RLC_TX_MAXSIZE,
|
|
|
|
@@ -800,12 +795,12 @@ void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_Beare
|
|
|
|
|
sn_field_length);
|
|
|
|
|
nr_rlc_ue_add_srb_rlc_entity(ue, srb_id, nr_rlc_am);
|
|
|
|
|
|
|
|
|
|
LOG_I(RLC, "Added srb %d to UE with RNTI 0x%x\n", srb_id, rnti);
|
|
|
|
|
LOG_I(RLC, "Added srb %d to UE %d\n", srb_id, ue_id);
|
|
|
|
|
}
|
|
|
|
|
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void add_drb_am(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig)
|
|
|
|
|
static void add_drb_am(int ue_id, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig)
|
|
|
|
|
{
|
|
|
|
|
struct NR_RLC_Config *r = rlc_BearerConfig->rlc_Config;
|
|
|
|
|
|
|
|
|
@@ -843,7 +838,7 @@ static void add_drb_am(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_Be
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
|
|
|
|
AssertFatal(rlc_BearerConfig->servedRadioBearer &&
|
|
|
|
|
(rlc_BearerConfig->servedRadioBearer->present ==
|
|
|
|
|
NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity),
|
|
|
|
@@ -852,7 +847,7 @@ static void add_drb_am(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_Be
|
|
|
|
|
ue->lcid2rb[local_id].type = NR_RLC_DRB;
|
|
|
|
|
ue->lcid2rb[local_id].choice.drb_id = rlc_BearerConfig->servedRadioBearer->choice.drb_Identity;
|
|
|
|
|
if (ue->drb[drb_id-1] != NULL) {
|
|
|
|
|
LOG_E(RLC, "%s:%d:%s: DRB %d already exists for UE with RNTI %04x, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
|
|
|
|
|
LOG_E(RLC, "DRB %d already exists for UE %d, do nothing\n", drb_id, ue_id);
|
|
|
|
|
} else {
|
|
|
|
|
nr_rlc_entity_t *nr_rlc_am = new_nr_rlc_entity_am(RLC_RX_MAXSIZE,
|
|
|
|
|
RLC_TX_MAXSIZE,
|
|
|
|
@@ -865,12 +860,12 @@ static void add_drb_am(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_Be
|
|
|
|
|
sn_field_length);
|
|
|
|
|
nr_rlc_ue_add_drb_rlc_entity(ue, drb_id, nr_rlc_am);
|
|
|
|
|
|
|
|
|
|
LOG_I(RLC, "%s:%d:%s: added drb %d to UE with RNTI 0x%x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
|
|
|
|
|
LOG_I(RLC, "Added drb %d to UE %d\n", drb_id, ue_id);
|
|
|
|
|
}
|
|
|
|
|
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void add_drb_um(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig)
|
|
|
|
|
static void add_drb_um(int ue_id, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig)
|
|
|
|
|
{
|
|
|
|
|
struct NR_RLC_Config *r = rlc_BearerConfig->rlc_Config;
|
|
|
|
|
|
|
|
|
@@ -898,7 +893,7 @@ static void add_drb_um(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_Be
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
|
|
|
|
AssertFatal(rlc_BearerConfig->servedRadioBearer &&
|
|
|
|
|
(rlc_BearerConfig->servedRadioBearer->present ==
|
|
|
|
|
NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity),
|
|
|
|
@@ -907,7 +902,7 @@ static void add_drb_um(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_Be
|
|
|
|
|
ue->lcid2rb[local_id].type = NR_RLC_DRB;
|
|
|
|
|
ue->lcid2rb[local_id].choice.drb_id = rlc_BearerConfig->servedRadioBearer->choice.drb_Identity;
|
|
|
|
|
if (ue->drb[drb_id-1] != NULL) {
|
|
|
|
|
LOG_E(RLC, "DEBUG add_drb_um %s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
|
|
|
|
|
LOG_E(RLC, "DEBUG add_drb_um: warning DRB %d already exist for ue %d, do nothing\n", drb_id, ue_id);
|
|
|
|
|
} else {
|
|
|
|
|
nr_rlc_entity_t *nr_rlc_um = new_nr_rlc_entity_um(RLC_RX_MAXSIZE,
|
|
|
|
|
RLC_TX_MAXSIZE,
|
|
|
|
@@ -916,26 +911,25 @@ static void add_drb_um(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_Be
|
|
|
|
|
sn_field_length);
|
|
|
|
|
nr_rlc_ue_add_drb_rlc_entity(ue, drb_id, nr_rlc_um);
|
|
|
|
|
|
|
|
|
|
LOG_D(RLC, "%s:%d:%s: added drb %d to UE with RNTI 0x%x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
|
|
|
|
|
LOG_D(RLC, "Added drb %d to UE %d\n", drb_id, ue_id);
|
|
|
|
|
}
|
|
|
|
|
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nr_rlc_add_drb(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig)
|
|
|
|
|
void nr_rlc_add_drb(int ue_id, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig)
|
|
|
|
|
{
|
|
|
|
|
switch (rlc_BearerConfig->rlc_Config->present) {
|
|
|
|
|
case NR_RLC_Config_PR_am:
|
|
|
|
|
add_drb_am(rnti, drb_id, rlc_BearerConfig);
|
|
|
|
|
add_drb_am(ue_id, drb_id, rlc_BearerConfig);
|
|
|
|
|
break;
|
|
|
|
|
case NR_RLC_Config_PR_um_Bi_Directional:
|
|
|
|
|
add_drb_um(rnti, drb_id, rlc_BearerConfig);
|
|
|
|
|
add_drb_um(ue_id, drb_id, rlc_BearerConfig);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
LOG_E(RLC, "%s:%d:%s: fatal: unhandled DRB type\n",
|
|
|
|
|
__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
LOG_E(RLC, "Fatal: unhandled DRB type\n");
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
LOG_I(RLC, "%s:%s:%d: added DRB to UE with RNTI 0x%x\n", __FILE__, __FUNCTION__, __LINE__, rnti);
|
|
|
|
|
LOG_I(RLC, "Added DRB to UE %d\n", ue_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Dummy function due to dependency from LTE libraries */
|
|
|
|
@@ -951,66 +945,52 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct srb0_data {
|
|
|
|
|
int rnti;
|
|
|
|
|
int ue_id;
|
|
|
|
|
void *data;
|
|
|
|
|
void (*send_initial_ul_rrc_message)(int rnti,
|
|
|
|
|
const uint8_t *sdu,
|
|
|
|
|
sdu_size_t sdu_len,
|
|
|
|
|
void *data);
|
|
|
|
|
void (*send_initial_ul_rrc_message)(int ue_id, const uint8_t *sdu, sdu_size_t sdu_len, void *data);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void deliver_sdu_srb0(void *deliver_sdu_data, struct nr_rlc_entity_t *entity,
|
|
|
|
|
char *buf, int size)
|
|
|
|
|
{
|
|
|
|
|
struct srb0_data *s0 = (struct srb0_data *)deliver_sdu_data;
|
|
|
|
|
s0->send_initial_ul_rrc_message(s0->rnti, (unsigned char *)buf, size, s0->data);
|
|
|
|
|
s0->send_initial_ul_rrc_message(s0->ue_id, (unsigned char *)buf, size, s0->data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nr_rlc_activate_srb0(int rnti, void *data,
|
|
|
|
|
void (*send_initial_ul_rrc_message)(
|
|
|
|
|
int rnti,
|
|
|
|
|
const uint8_t *sdu,
|
|
|
|
|
sdu_size_t sdu_len,
|
|
|
|
|
void *data))
|
|
|
|
|
void nr_rlc_activate_srb0(int ue_id,
|
|
|
|
|
void *data,
|
|
|
|
|
void (*send_initial_ul_rrc_message)(int ue_id, const uint8_t *sdu, sdu_size_t sdu_len, void *data))
|
|
|
|
|
{
|
|
|
|
|
nr_rlc_entity_t *nr_rlc_tm;
|
|
|
|
|
nr_rlc_ue_t *ue;
|
|
|
|
|
struct srb0_data *srb0_data;
|
|
|
|
|
|
|
|
|
|
srb0_data = calloc(1, sizeof(struct srb0_data));
|
|
|
|
|
struct srb0_data *srb0_data = calloc(1, sizeof(struct srb0_data));
|
|
|
|
|
AssertFatal(srb0_data != NULL, "out of memory\n");
|
|
|
|
|
|
|
|
|
|
srb0_data->rnti = rnti;
|
|
|
|
|
srb0_data->data = data;
|
|
|
|
|
srb0_data->ue_id = ue_id;
|
|
|
|
|
srb0_data->data = data;
|
|
|
|
|
srb0_data->send_initial_ul_rrc_message = send_initial_ul_rrc_message;
|
|
|
|
|
|
|
|
|
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
|
|
|
|
ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
|
|
|
|
if (ue->srb0 != NULL) {
|
|
|
|
|
LOG_W(RLC, "SRB0 already exists for UE with RNTI 0x%x, do nothing\n", rnti);
|
|
|
|
|
LOG_W(RLC, "SRB0 already exists for UE %d, do nothing\n", ue_id);
|
|
|
|
|
free(srb0_data);
|
|
|
|
|
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nr_rlc_tm = new_nr_rlc_entity_tm(10000,
|
|
|
|
|
nr_rlc_entity_t *nr_rlc_tm = new_nr_rlc_entity_tm(10000,
|
|
|
|
|
deliver_sdu_srb0, srb0_data);
|
|
|
|
|
nr_rlc_ue_add_srb_rlc_entity(ue, 0, nr_rlc_tm);
|
|
|
|
|
|
|
|
|
|
LOG_I(RLC, "activated srb0 for UE with RNTI 0x%x\n", rnti);
|
|
|
|
|
LOG_I(RLC, "Activated srb0 for UE %d\n", ue_id);
|
|
|
|
|
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rlc_op_status_t rrc_rlc_config_req (
|
|
|
|
|
const protocol_ctxt_t* const ctxt_pP,
|
|
|
|
|
const srb_flag_t srb_flagP,
|
|
|
|
|
const MBMS_flag_t mbms_flagP,
|
|
|
|
|
const config_action_t actionP,
|
|
|
|
|
const rb_id_t rb_idP)
|
|
|
|
|
rlc_op_status_t rrc_rlc_config_req(const protocol_ctxt_t* const ctxt_pP,
|
|
|
|
|
const srb_flag_t srb_flagP,
|
|
|
|
|
const MBMS_flag_t mbms_flagP,
|
|
|
|
|
const config_action_t actionP,
|
|
|
|
|
const rb_id_t rb_idP)
|
|
|
|
|
{
|
|
|
|
|
nr_rlc_ue_t *ue;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
if (mbms_flagP) {
|
|
|
|
|
LOG_E(RLC, "%s:%d:%s: todo (MBMS NOT supported)\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
exit(1);
|
|
|
|
@@ -1029,8 +1009,8 @@ rlc_op_status_t rrc_rlc_config_req (
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
|
|
|
|
LOG_D(RLC, "%s:%d:%s: remove rb %ld (is_srb %d) for UE RNTI %lx\n", __FILE__, __LINE__, __FUNCTION__, rb_idP, srb_flagP, ctxt_pP->rntiMaybeUEid);
|
|
|
|
|
ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ctxt_pP->rntiMaybeUEid);
|
|
|
|
|
LOG_D(RLC, "%s:%d:%s: remove rb %ld (is_srb %d) for UE %lx\n", __FILE__, __LINE__, __FUNCTION__, rb_idP, srb_flagP, ctxt_pP->rntiMaybeUEid);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ctxt_pP->rntiMaybeUEid);
|
|
|
|
|
if (srb_flagP) {
|
|
|
|
|
if (ue->srb[rb_idP-1] != NULL) {
|
|
|
|
|
ue->srb[rb_idP-1]->delete_entity(ue->srb[rb_idP-1]);
|
|
|
|
@@ -1045,6 +1025,7 @@ rlc_op_status_t rrc_rlc_config_req (
|
|
|
|
|
LOG_W(RLC, "removing non allocated DRB %ld, do nothing\n", rb_idP);
|
|
|
|
|
}
|
|
|
|
|
/* remove UE if it has no more RB configured */
|
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < 2; i++)
|
|
|
|
|
if (ue->srb[i] != NULL)
|
|
|
|
|
break;
|
|
|
|
@@ -1059,11 +1040,11 @@ rlc_op_status_t rrc_rlc_config_req (
|
|
|
|
|
return RLC_OP_STATUS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nr_rlc_remove_ue(int rnti)
|
|
|
|
|
void nr_rlc_remove_ue(int ue_id)
|
|
|
|
|
{
|
|
|
|
|
LOG_W(RLC, "remove UE %x\n", rnti);
|
|
|
|
|
LOG_W(RLC, "Remove UE %d\n", ue_id);
|
|
|
|
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
|
|
|
|
nr_rlc_manager_remove_ue(nr_rlc_ue_manager, rnti);
|
|
|
|
|
nr_rlc_manager_remove_ue(nr_rlc_ue_manager, ue_id);
|
|
|
|
|
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -1073,17 +1054,17 @@ rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x)
|
|
|
|
|
return RLC_OP_STATUS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool nr_rlc_update_rnti(int from_rnti, int to_rnti)
|
|
|
|
|
bool nr_rlc_update_id(int from_id, int to_id)
|
|
|
|
|
{
|
|
|
|
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, from_rnti);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, from_id);
|
|
|
|
|
if (ue == NULL) {
|
|
|
|
|
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
|
|
|
|
LOG_E(RLC, "Cannot find RLC entity for UE %04x\n", from_rnti);
|
|
|
|
|
LOG_E(RLC, "Cannot find RLC entity for UE %d\n", from_id);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
ue->rnti = to_rnti;
|
|
|
|
|
LOG_I(RLC, "Update old UE RNTI %04x context to RNTI %04x\n", from_rnti, to_rnti);
|
|
|
|
|
ue->ue_id = to_id;
|
|
|
|
|
LOG_I(RLC, "Update old UE ID %d context to ID %d\n", from_id, to_id);
|
|
|
|
|
for (int i = 0; i < sizeof(ue->srb) / sizeof(ue->srb[0]); ++i)
|
|
|
|
|
if (ue->srb[i])
|
|
|
|
|
ue->srb[i]->reestablishment(ue->srb[i]);
|
|
|
|
@@ -1096,13 +1077,13 @@ bool nr_rlc_update_rnti(int from_rnti, int to_rnti)
|
|
|
|
|
|
|
|
|
|
/* This function is for testing purposes. At least on a COTS UE, it will
|
|
|
|
|
* trigger a reestablishment. */
|
|
|
|
|
void nr_rlc_test_trigger_reestablishment(int rnti)
|
|
|
|
|
void nr_rlc_test_trigger_reestablishment(int ue_id)
|
|
|
|
|
{
|
|
|
|
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
|
|
|
|
if (ue == NULL) {
|
|
|
|
|
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
|
|
|
|
LOG_E(RLC, "Cannot find RLC entity for UE %04x\n", rnti);
|
|
|
|
|
LOG_E(RLC, "Cannot find RLC entity for UE %04x\n", ue_id);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
/* we simply assume the SRB exists, because the scheduler creates it as soon
|
|
|
|
@@ -1132,16 +1113,13 @@ void rlc_tick(int a, int b)
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nr_rlc_activate_avg_time_to_tx(
|
|
|
|
|
const rnti_t rnti,
|
|
|
|
|
const logical_chan_id_t channel_id,
|
|
|
|
|
const bool is_on)
|
|
|
|
|
void nr_rlc_activate_avg_time_to_tx(const int ue_id,
|
|
|
|
|
const logical_chan_id_t channel_id,
|
|
|
|
|
const bool is_on)
|
|
|
|
|
{
|
|
|
|
|
nr_rlc_ue_t *ue;
|
|
|
|
|
nr_rlc_entity_t *rb;
|
|
|
|
|
|
|
|
|
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
|
|
|
|
ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
|
|
|
|
|
|
|
|
|
switch (channel_id) {
|
|
|
|
|
case 1 ... 3: rb = ue->srb[channel_id - 1]; break;
|
|
|
|
@@ -1153,27 +1131,20 @@ void nr_rlc_activate_avg_time_to_tx(
|
|
|
|
|
rb->avg_time_is_on = is_on;
|
|
|
|
|
time_average_reset(rb->txsdu_avg_time_to_tx);
|
|
|
|
|
} else {
|
|
|
|
|
LOG_E(RLC, "[%s] Radio Bearer (channel ID %d) is NULL for UE with rnti %x\n", __FUNCTION__, channel_id, rnti);
|
|
|
|
|
LOG_E(RLC, "Radio Bearer (channel ID %d) is NULL for UE %d\n", channel_id, ue_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* returns false in case of error, true if everything ok */
|
|
|
|
|
bool nr_rlc_get_statistics(
|
|
|
|
|
int rnti,
|
|
|
|
|
int srb_flag,
|
|
|
|
|
int rb_id,
|
|
|
|
|
nr_rlc_statistics_t *out)
|
|
|
|
|
bool nr_rlc_get_statistics(int ue_id, int srb_flag, int rb_id, nr_rlc_statistics_t *out)
|
|
|
|
|
{
|
|
|
|
|
nr_rlc_ue_t *ue;
|
|
|
|
|
nr_rlc_entity_t *rb;
|
|
|
|
|
bool ret;
|
|
|
|
|
|
|
|
|
|
bool ret;
|
|
|
|
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
|
|
|
|
ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
|
|
|
|
|
|
|
|
|
rb = NULL;
|
|
|
|
|
nr_rlc_entity_t *rb = NULL;
|
|
|
|
|
|
|
|
|
|
if (srb_flag) {
|
|
|
|
|
if (rb_id >= 1 && rb_id <= 2)
|
|
|
|
@@ -1201,23 +1172,21 @@ bool nr_rlc_get_statistics(
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nr_rlc_srb_recv_sdu(const int rnti, const logical_chan_id_t channel_id, unsigned char *buf, int size)
|
|
|
|
|
void nr_rlc_srb_recv_sdu(const int ue_id, const logical_chan_id_t channel_id, unsigned char *buf, int size)
|
|
|
|
|
{
|
|
|
|
|
nr_rlc_ue_t *ue;
|
|
|
|
|
nr_rlc_entity_t *rb;
|
|
|
|
|
|
|
|
|
|
T(T_ENB_RLC_DL, T_INT(0), T_INT(rnti), T_INT(0), T_INT(size));
|
|
|
|
|
T(T_ENB_RLC_DL, T_INT(0), T_INT(ue_id), T_INT(0), T_INT(size));
|
|
|
|
|
|
|
|
|
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
|
|
|
|
ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti);
|
|
|
|
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
|
|
|
|
|
|
|
|
|
nr_rlc_entity_t *rb = NULL;
|
|
|
|
|
if (channel_id == 0) {
|
|
|
|
|
rb = ue->srb0;
|
|
|
|
|
} else {
|
|
|
|
|
rb = ue->srb[channel_id - 1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AssertFatal(rb != NULL, "SDU sent to unknown RB RNTI %04x SRB %d\n", rnti, channel_id);
|
|
|
|
|
AssertFatal(rb != NULL, "SDU sent to unknown RB UE-ID %d SRB %d\n", ue_id, channel_id);
|
|
|
|
|
|
|
|
|
|
rb->set_time(rb, nr_rlc_current_time);
|
|
|
|
|
rb->recv_sdu(rb, (char *)buf, size, -1);
|
|
|
|
|