Merge remote-tracking branch 'origin/NR_UE_trigger_reestablishment' into integration_2024_w46 (!2777)

NR UE trigger for re-establishment

The implementation in this MR triggers RRC re-establishment at the UE in case
of radio link failure either for out of sync messages from lower layers or in
case maximum number of RLC retransmissions is reached.
This commit is contained in:
Jaroslava Fiedlerova
2024-11-18 10:12:25 +01:00
20 changed files with 283 additions and 104 deletions
+3
View File
@@ -85,3 +85,6 @@ MESSAGE_DEF(NRRRC_FRAME_PROCESS, MESSAGE_PRIORITY_MED, NRRrcFramePr
// eNB: RLC -> RRC messages
MESSAGE_DEF(RLC_SDU_INDICATION, MESSAGE_PRIORITY_MED, RlcSduIndication, rlc_sdu_indication)
MESSAGE_DEF(NAS_PDU_SESSION_REQ, MESSAGE_PRIORITY_MED, nas_pdu_session_req_t, nas_pdu_session_req)
// UE: RLC -> RRC messages
MESSAGE_DEF(NR_RRC_RLC_MAXRTX, MESSAGE_PRIORITY_MED, RlcMaxRtxIndication, nr_rlc_maxrtx_indication)
+6
View File
@@ -97,6 +97,8 @@
#define NAS_OAI_TUN_NSA(mSGpTR) (mSGpTR)->ittiMsg.nas_oai_tun_nsa
#define NAS_PDU_SESSION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_pdu_session_req
#define NR_RRC_RLC_MAXRTX(mSGpTR) (mSGpTR)->ittiMsg.nr_rlc_maxrtx_indication
//-------------------------------------------------------------------------------------------//
typedef struct RrcStateInd_s {
Rrc_State_t state;
@@ -453,4 +455,8 @@ typedef struct rlc_sdu_indication_s {
int message_id;
} RlcSduIndication;
typedef struct {
int ue_id;
} RlcMaxRtxIndication;
#endif /* RRC_MESSAGES_TYPES_H_ */
+2 -3
View File
@@ -1611,8 +1611,7 @@ static void configure_timeAlignmentTimer(NR_timer_t *time_alignment_timer, NR_Ti
nr_timer_start(time_alignment_timer);
}
void nr_rrc_mac_config_req_reset(module_id_t module_id,
NR_UE_MAC_reset_cause_t cause)
void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t cause)
{
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
int ret = pthread_mutex_lock(&mac->if_mutex);
@@ -1621,8 +1620,8 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id,
switch (cause) {
case GO_TO_IDLE:
reset_ra(mac, true);
release_mac_configuration(mac, cause);
nr_ue_init_mac(mac);
release_mac_configuration(mac, cause);
nr_ue_mac_default_configs(mac);
// new sync but no target cell id -> -1
nr_ue_send_synch_request(mac, module_id, 0, &sync_req);
+9
View File
@@ -183,6 +183,15 @@ typedef enum {
#undef UE_STATE
} NR_UE_L2_STATE_t;
typedef struct {
pucch_format_nr_t format;
uint8_t startingSymbolIndex;
uint8_t nrofSymbols;
uint16_t PRB_offset;
uint8_t nb_CS_indexes;
uint8_t initial_CS_indexes[MAX_NB_CYCLIC_SHIFT];
} initial_pucch_resource_t;
typedef enum {
GO_TO_IDLE,
DETACH,
+1 -1
View File
@@ -209,7 +209,7 @@ void set_harq_status(NR_UE_MAC_INST_t *mac,
int slot);
bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sched_t *pucch);
initial_pucch_resource_t get_initial_pucch_resource(const int idx);
void multiplex_pucch_resource(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, int num_res);
int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
+7 -3
View File
@@ -1514,6 +1514,11 @@ void set_harq_status(NR_UE_MAC_INST_t *mac,
current_harq->dai_cumul);
}
initial_pucch_resource_t get_initial_pucch_resource(const int idx)
{
return initial_pucch_resource[idx];
}
int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
int slot,
frame_t frame,
@@ -1534,10 +1539,9 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
LOG_D(NR_MAC, "initial_pucch_id %d, pucch_resource %p\n", pucch->initial_pucch_id, pucch->pucch_resource);
// configure pucch from Table 9.2.1-1
// only for ack/nack
if (pucch->initial_pucch_id > -1 &&
pucch->pucch_resource == NULL) {
if (pucch->initial_pucch_id > -1 && pucch->pucch_resource == NULL) {
const int idx = *current_UL_BWP->pucch_ConfigCommon->pucch_ResourceCommon;
const initial_pucch_resource_t pucch_resourcecommon = initial_pucch_resource[idx];
const initial_pucch_resource_t pucch_resourcecommon = get_initial_pucch_resource(idx);
pucch_pdu->format_type = pucch_resourcecommon.format;
pucch_pdu->start_symbol_index = pucch_resourcecommon.startingSymbolIndex;
pucch_pdu->nr_of_symbols = pucch_resourcecommon.nrofSymbols;
+60 -42
View File
@@ -1443,13 +1443,16 @@ static void nr_update_sr(NR_UE_MAC_INST_t *mac, bool BSRsent)
// if the UL-SCH resources available for a new transmission do not meet the LCP mapping restrictions
// TODO not implemented
NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP;
NR_PUCCH_Config_t *pucch_Config = current_UL_BWP ? current_UL_BWP->pucch_Config : NULL;
if (!pucch_Config || !pucch_Config->schedulingRequestResourceToAddModList)
return; // cannot schedule SR if there is no schedulingRequestResource configured
if (lc_info->sr_id < 0 || lc_info->sr_id >= NR_MAX_SR_ID)
LOG_E(NR_MAC, "No SR corresponding to this LCID\n"); // TODO not sure what to do here
else {
nr_sr_info_t *sr = &sched_info->sr_info[lc_info->sr_id];
if (!sr->pending) {
NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP;
NR_PUCCH_Config_t *pucch_Config = current_UL_BWP ? current_UL_BWP->pucch_Config : NULL;
if (check_pucchres_for_pending_SR(pucch_Config, lc_info->sr_id)) {
// trigger SR
LOG_D(NR_MAC, "Triggering SR for ID %d\n", lc_info->sr_id);
@@ -2325,7 +2328,11 @@ void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac)
LOG_D(NR_MAC,"Map SSB to RO done\n");
}
static bool schedule_uci_on_pusch(NR_UE_MAC_INST_t *mac, frame_t frame_tx, int slot_tx, const PUCCH_sched_t *pucch)
static bool schedule_uci_on_pusch(NR_UE_MAC_INST_t *mac,
frame_t frame_tx,
int slot_tx,
const PUCCH_sched_t *pucch,
NR_UE_UL_BWP_t *current_UL_BWP)
{
fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = lockGet_ul_iterator(mac, frame_tx, slot_tx);
if (!ulcfg_pdu)
@@ -2340,29 +2347,37 @@ static bool schedule_uci_on_pusch(NR_UE_MAC_INST_t *mac, frame_t frame_tx, int s
NR_PUCCH_Resource_t *pucchres = pucch->pucch_resource;
int nr_of_symbols = 0;
int start_symbol_index = 0;
switch(pucchres->format.present) {
case NR_PUCCH_Resource__format_PR_format0 :
nr_of_symbols = pucchres->format.choice.format0->nrofSymbols;
start_symbol_index = pucchres->format.choice.format0->startingSymbolIndex;
break;
case NR_PUCCH_Resource__format_PR_format1 :
nr_of_symbols = pucchres->format.choice.format1->nrofSymbols;
start_symbol_index = pucchres->format.choice.format1->startingSymbolIndex;
break;
case NR_PUCCH_Resource__format_PR_format2 :
nr_of_symbols = pucchres->format.choice.format2->nrofSymbols;
start_symbol_index = pucchres->format.choice.format2->startingSymbolIndex;
break;
case NR_PUCCH_Resource__format_PR_format3 :
nr_of_symbols = pucchres->format.choice.format3->nrofSymbols;
start_symbol_index = pucchres->format.choice.format3->startingSymbolIndex;
break;
case NR_PUCCH_Resource__format_PR_format4 :
nr_of_symbols = pucchres->format.choice.format4->nrofSymbols;
start_symbol_index = pucchres->format.choice.format4->startingSymbolIndex;
break;
default :
AssertFatal(false, "Undefined PUCCH format \n");
if (pucch->initial_pucch_id > -1 && pucch->pucch_resource == NULL) {
const int idx = *current_UL_BWP->pucch_ConfigCommon->pucch_ResourceCommon;
const initial_pucch_resource_t pucch_resourcecommon = get_initial_pucch_resource(idx);
start_symbol_index = pucch_resourcecommon.startingSymbolIndex;
nr_of_symbols = pucch_resourcecommon.nrofSymbols;
}
else {
switch(pucchres->format.present) {
case NR_PUCCH_Resource__format_PR_format0 :
nr_of_symbols = pucchres->format.choice.format0->nrofSymbols;
start_symbol_index = pucchres->format.choice.format0->startingSymbolIndex;
break;
case NR_PUCCH_Resource__format_PR_format1 :
nr_of_symbols = pucchres->format.choice.format1->nrofSymbols;
start_symbol_index = pucchres->format.choice.format1->startingSymbolIndex;
break;
case NR_PUCCH_Resource__format_PR_format2 :
nr_of_symbols = pucchres->format.choice.format2->nrofSymbols;
start_symbol_index = pucchres->format.choice.format2->startingSymbolIndex;
break;
case NR_PUCCH_Resource__format_PR_format3 :
nr_of_symbols = pucchres->format.choice.format3->nrofSymbols;
start_symbol_index = pucchres->format.choice.format3->startingSymbolIndex;
break;
case NR_PUCCH_Resource__format_PR_format4 :
nr_of_symbols = pucchres->format.choice.format4->nrofSymbols;
start_symbol_index = pucchres->format.choice.format4->startingSymbolIndex;
break;
default :
AssertFatal(false, "Undefined PUCCH format \n");
}
}
int final_symbol = nr_of_symbols + start_symbol_index;
// PUCCH overlapping in time with PUSCH
@@ -2393,22 +2408,25 @@ static bool schedule_uci_on_pusch(NR_UE_MAC_INST_t *mac, frame_t frame_tx, int s
// and does not transmit the PUCCH if the UE does not multiplex aperiodic or semi-persistent CSI reports in the PUSCH
bool mux_done = false;
if (pucch->n_harq > 0) {
pusch_pdu->pusch_uci.harq_ack_bit_length = pucch->n_harq;
pusch_pdu->pusch_uci.harq_payload = pucch->ack_payload;
NR_PUSCH_Config_t *pusch_Config = mac->current_UL_BWP->pusch_Config;
AssertFatal(pusch_Config && pusch_Config->uci_OnPUSCH, "UCI on PUSCH need to be configured\n");
NR_UCI_OnPUSCH_t *onPusch = pusch_Config->uci_OnPUSCH->choice.setup;
AssertFatal(onPusch &&
onPusch->betaOffsets &&
onPusch->betaOffsets->present == NR_UCI_OnPUSCH__betaOffsets_PR_semiStatic,
"Only semistatic beta offset is supported\n");
NR_BetaOffsets_t *beta_offsets = onPusch->betaOffsets->choice.semiStatic;
pusch_pdu->pusch_uci.beta_offset_harq_ack = pucch->n_harq > 2 ?
(pucch->n_harq < 12 ? *beta_offsets->betaOffsetACK_Index2 :
*beta_offsets->betaOffsetACK_Index3) :
*beta_offsets->betaOffsetACK_Index1;
pusch_pdu->pusch_uci.alpha_scaling = onPusch->scaling;
mux_done = true;
if (pusch_Config && pusch_Config->uci_OnPUSCH) {
NR_UCI_OnPUSCH_t *onPusch = pusch_Config->uci_OnPUSCH->choice.setup;
AssertFatal(onPusch &&
onPusch->betaOffsets &&
onPusch->betaOffsets->present == NR_UCI_OnPUSCH__betaOffsets_PR_semiStatic,
"Only semistatic beta offset is supported\n");
NR_BetaOffsets_t *beta_offsets = onPusch->betaOffsets->choice.semiStatic;
pusch_pdu->pusch_uci.harq_ack_bit_length = pucch->n_harq;
pusch_pdu->pusch_uci.harq_payload = pucch->ack_payload;
pusch_pdu->pusch_uci.beta_offset_harq_ack = pucch->n_harq > 2 ?
(pucch->n_harq < 12 ? *beta_offsets->betaOffsetACK_Index2 :
*beta_offsets->betaOffsetACK_Index3) :
*beta_offsets->betaOffsetACK_Index1;
pusch_pdu->pusch_uci.alpha_scaling = onPusch->scaling;
mux_done = true;
} else {
LOG_E(NR_MAC, "UCI on PUSCH need to be configured to schedule UCI on PUSCH\n");
}
}
if (pusch_pdu->pusch_uci.csi_part1_bit_length == 0 && pusch_pdu->pusch_uci.csi_part2_bit_length == 0) {
// To support this we would need to shift some bits into CSI part2 -> need to change the logic
@@ -2471,7 +2489,7 @@ void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP)
mac->nr_ue_emul_l1.num_csi_reports = pucch[j].n_csi;
// checking if we need to schedule pucch[j] on PUSCH
if (schedule_uci_on_pusch(mac, frameP, slotP, &pucch[j]))
if (schedule_uci_on_pusch(mac, frameP, slotP, &pucch[j], mac->current_UL_BWP))
continue;
fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PUCCH);
+30 -24
View File
@@ -114,14 +114,19 @@ logical_chan_id_t nr_rlc_get_lcid_from_rb(int ue_id, bool is_srb, int rb_id)
for (logical_chan_id_t id = 1; id <= 32; id++) {
nr_rlc_rb_t *rb = &ue->lcid2rb[id - 1];
if (is_srb) {
if (rb->type == NR_RLC_SRB && rb->choice.srb_id == rb_id)
if (rb->type == NR_RLC_SRB && rb->choice.srb_id == rb_id) {
nr_rlc_manager_unlock(nr_rlc_ue_manager);
return id;
}
} else {
if (rb->type == NR_RLC_DRB && rb->choice.drb_id == rb_id)
if (rb->type == NR_RLC_DRB && rb->choice.drb_id == rb_id) {
nr_rlc_manager_unlock(nr_rlc_ue_manager);
return id;
}
}
}
LOG_E(RLC, "Couldn't find LCID corresponding to %s %d\n", is_srb ? "SRB" : "DRB", rb_id);
nr_rlc_manager_unlock(nr_rlc_ue_manager);
return 0;
}
@@ -614,10 +619,6 @@ static void max_retx_reached(void *_ue, nr_rlc_entity_t *entity)
int i;
int is_srb;
int rb_id;
#if 0
MessageDef *msg;
#endif
int is_enb;
/* is it SRB? */
for (i = 0; i < 2; i++) {
@@ -645,23 +646,18 @@ rb_found:
is_srb ? "SRB" : "DRB",
rb_id);
/* TODO: do something for DRBs? */
if (is_srb == 0)
return;
if (ue->rlf_handler)
ue->rlf_handler(ue->ue_id);
else
LOG_W(RLC, "UE %04x: RLF detected, but no callable RLF handler registered\n", ue->ue_id);
}
is_enb = nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager);
if (!is_enb)
return;
#if 0
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;
RLC_SDU_INDICATION(msg).srb_id = rb_id;
RLC_SDU_INDICATION(msg).message_id = -1;
/* TODO: accept more than 1 instance? here we send to instance id 0 */
itti_send_msg_to_task(TASK_RRC_ENB, 0, msg);
#endif
void nr_rlc_set_rlf_handler(int ue_id, rlf_handler_t rlf_h)
{
nr_rlc_manager_lock(nr_rlc_ue_manager);
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
ue->rlf_handler = rlf_h;
nr_rlc_manager_unlock(nr_rlc_ue_manager);
}
void nr_rlc_reestablish_entity(int ue_id, int lc_id)
@@ -671,6 +667,7 @@ void nr_rlc_reestablish_entity(int ue_id, int lc_id)
if (ue == NULL) {
LOG_E(RLC, "RLC instance for the given UE was not found \n");
nr_rlc_manager_unlock(nr_rlc_ue_manager);
return;
}
nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, lc_id);
@@ -1099,8 +1096,14 @@ bool nr_rlc_update_id(int from_id, int to_id)
return true;
}
/* This function is for testing purposes. At least on a COTS UE, it will
* trigger a reestablishment. */
/**
* @brief This function is for testing purposes.
* Re-establishment is triggered by resetting RLC counters of the bearer,
* which leads to UE reaching maximum RLC retransmissions, RLF detection
* and RRC triggering re-sync. It is assumed that there is ongoing traffic on the bearer.
* - With COTS UEs, triggers re-establishment on SRB 1, where periodical measurement reports are sent.
* - With OAI UE, triggers re-establishment on DRB 1, assuming there is ongoing data traffic.
*/
void nr_rlc_test_trigger_reestablishment(int ue_id)
{
nr_rlc_manager_lock(nr_rlc_ue_manager);
@@ -1114,6 +1117,9 @@ void nr_rlc_test_trigger_reestablishment(int ue_id)
* as the UE context is created. */
nr_rlc_entity_t *ent = ue->srb[0];
ent->reestablishment(ent);
/* Trigger re-establishment on OAI UE */
nr_rlc_entity_t *drb = ue->drb[0];
drb->reestablishment(drb);
nr_rlc_manager_unlock(nr_rlc_ue_manager);
}
+2
View File
@@ -44,6 +44,8 @@ struct NR_LogicalChannelConfig;
void nr_rlc_add_srb(int ue_id, int srb_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);
void nr_rlc_set_rlf_handler(int ue_id, rlf_handler_t rlf_h);
logical_chan_id_t nr_rlc_get_lcid_from_rb(int ue_id, bool is_srb, int rb_id);
void nr_rlc_reestablish_entity(int ue_id, int lc_id);
void nr_rlc_remove_ue(int ue_id);
@@ -37,12 +37,15 @@ typedef struct nr_rlc_rb_t {
} choice;
} nr_rlc_rb_t;
typedef void (*rlf_handler_t)(int rnti);
typedef struct nr_rlc_ue_t {
int ue_id;
nr_rlc_entity_t *srb0;
nr_rlc_entity_t *srb[3];
nr_rlc_entity_t *drb[MAX_DRBS_PER_UE];
nr_rlc_rb_t lcid2rb[32];
rlf_handler_t rlf_handler;
} nr_rlc_ue_t;
/***********************************************************************/
+43
View File
@@ -151,6 +151,11 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc,
static void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measConfig, NR_UE_Timers_Constants_t *timers);
NR_UE_RRC_INST_t* get_NR_UE_rrc_inst(int instance)
{
return &NR_UE_rrc_inst[instance];
}
static NR_RB_status_t get_DRB_status(const NR_UE_RRC_INST_t *rrc, NR_DRB_Identity_t drb_id)
{
AssertFatal(drb_id > 0 && drb_id < 33, "Invalid DRB ID %ld\n", drb_id);
@@ -873,6 +878,13 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc,
return 0;
}
static void nr_rrc_signal_maxrtxindication(int ue_id)
{
MessageDef *msg = itti_alloc_new_message(TASK_RLC_UE, ue_id, NR_RRC_RLC_MAXRTX);
NR_RRC_RLC_MAXRTX(msg).ue_id = ue_id;
itti_send_msg_to_task(TASK_RRC_NRUE, ue_id, msg);
}
static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc,
const NR_CellGroupConfig_t *cellGroupConfig)
{
@@ -901,9 +913,11 @@ static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc,
if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) {
NR_SRB_Identity_t srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity;
nr_rlc_add_srb(rrc->ue_id, srb_id, rlc_bearer);
nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication);
} else { // DRB
NR_DRB_Identity_t drb_id = rlc_bearer->servedRadioBearer->choice.drb_Identity;
nr_rlc_add_drb(rrc->ue_id, drb_id, rlc_bearer);
nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication);
}
}
}
@@ -1843,6 +1857,15 @@ void *rrc_nrue(void *notUsed)
nr_rrc_going_to_IDLE(rrc, release_cause, NULL);
break;
case NR_RRC_RLC_MAXRTX:
// detection of RLF upon indication from RLC that the maximum number of retransmissions has been reached
LOG_W(NR_RRC,
"[UE %ld ID %d] Received indication that RLC reached max retransmissions\n",
instance,
NR_RRC_RLC_MAXRTX(msg_p).ue_id);
handle_rlf_detection(rrc);
break;
case NR_RRC_MAC_MSG3_IND:
nr_rrc_handle_msg3_indication(rrc, NR_RRC_MAC_MSG3_IND(msg_p).rnti);
break;
@@ -2285,6 +2308,26 @@ void handle_RRCRelease(NR_UE_RRC_INST_t *rrc)
asn1cFreeStruc(asn_DEF_NR_RRCRelease, rrc->RRCRelease);
}
void handle_rlf_detection(NR_UE_RRC_INST_t *rrc)
{
// 5.3.10.3 in 38.331
bool srb2 = rrc->Srb[2] != RB_NOT_PRESENT;
bool any_drb = false;
for (int i = 0; i < MAX_DRBS_PER_UE; i++) {
if (rrc->status_DRBs[i] != RB_NOT_PRESENT) {
any_drb = true;
break;
}
}
if (rrc->as_security_activated && srb2 && any_drb) // initiate the connection re-establishment procedure
nr_rrc_initiate_rrcReestablishment(rrc, NR_ReestablishmentCause_otherFailure, 0);
else {
NR_Release_Cause_t cause = rrc->as_security_activated ? RRC_CONNECTION_FAILURE : OTHER;
nr_rrc_going_to_IDLE(rrc, cause, NULL);
}
}
void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
NR_Release_Cause_t release_cause,
NR_RRCRelease_t *RRCRelease)
+2 -1
View File
@@ -42,7 +42,7 @@
#include "common/utils/ocp_itti/intertask_interface.h"
NR_UE_RRC_INST_t *nr_rrc_init_ue(char* uecap_file, int nb_inst, int num_ant_tx);
NR_UE_RRC_INST_t* get_NR_UE_rrc_inst(int instance);
void init_nsa_message (NR_UE_RRC_INST_t *rrc, char* reconfig_file, char* rbconfig_file);
void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message, int msg_len);
@@ -63,6 +63,7 @@ void *rrc_nrue_task(void *args_p);
void *rrc_nrue(void *args_p);
void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc);
void handle_rlf_detection(NR_UE_RRC_INST_t *rrc);
/**\brief RRC NSA UE task.
\param void *args_p Pointer on arguments to start the task. */
@@ -157,10 +157,9 @@ void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc)
bool t310_expired = nr_timer_tick(&timers->T310);
if(t310_expired) {
LOG_W(NR_RRC, "Timer T310 expired\n");
// TODO
// handle detection of radio link failure
// as described in 5.3.10.3 of 38.331
AssertFatal(false, "Radio link failure! Not handled yet!\n");
handle_rlf_detection(rrc);
}
bool t311_expired = nr_timer_tick(&timers->T311);