Commit 894491f2 authored by Jaroslava Fiedlerova's avatar Jaroslava Fiedlerova

Merge remote-tracking branch 'origin/nr_ue_epoch_target' into integration_2025_w48 (!3659)

UE NTN - Epoch time handling for Target cell

In case of Handover, NTNconfig sent in RRCreconfiguration triggering handover
contains epoch time wrt timing of Target cell. NTNconfig in RRC needs to be
processed only after timing is acquired on the target cell.

In case of Target cell, epoch time is the sfn nearest to the frame timing of the
target cell.
parents 92980ceb f9a8898e
...@@ -210,7 +210,7 @@ static void get_epochtime_from_sib19scheduling(NR_UE_RRC_SI_INFO *SI_info, int * ...@@ -210,7 +210,7 @@ static void get_epochtime_from_sib19scheduling(NR_UE_RRC_SI_INFO *SI_info, int *
slot); slot);
} }
static int eval_epoch_time(NR_UE_RRC_SI_INFO *SI_info, NR_NTN_Config_r17_t *ntncfg, int frame) static int eval_epoch_time(NR_UE_RRC_SI_INFO *SI_info, NR_NTN_Config_r17_t *ntncfg, int frame, bool is_targetcell)
{ {
int epoch_frame = 0, epoch_subframe = 0; int epoch_frame = 0, epoch_subframe = 0;
int diff_frames = 0; int diff_frames = 0;
...@@ -229,11 +229,19 @@ static int eval_epoch_time(NR_UE_RRC_SI_INFO *SI_info, NR_NTN_Config_r17_t *ntnc ...@@ -229,11 +229,19 @@ static int eval_epoch_time(NR_UE_RRC_SI_INFO *SI_info, NR_NTN_Config_r17_t *ntnc
ntncfg->epochTime_r17->sfn_r17 = epoch_frame; ntncfg->epochTime_r17->sfn_r17 = epoch_frame;
ntncfg->epochTime_r17->subFrameNR_r17 = epoch_subframe; ntncfg->epochTime_r17->subFrameNR_r17 = epoch_subframe;
} }
// For serving cell, the field sfn indicates the current SFN or the next upcoming SFN if (is_targetcell) {
// after the frame where the message indicating the epochTime is received // For Target cell,the SFN nearest to the frame needs to be considered
// i.e. Epochframe can be present or future SFN // i.e. Epochframe can be in the past or future
diff_frames = (epoch_frame - frame + 1024) % 1024; // According to 38.331 Epochtime is defined for serving cell like this int diff1 = (frame - epoch_frame + 1024) % 1024;
LOG_I(NR_RRC, "Epoch frame %d, ahead by %d frames\n", epoch_frame, diff_frames); int diff2 = (epoch_frame - frame + 1024) % 1024;
diff_frames = (diff1 < diff2) ? -diff1 : diff2;
} else {
// For serving cell, the field sfn indicates the current SFN or the next upcoming SFN
// after the frame where the message indicating the epochTime is received
// i.e. Epochframe can be present or future SFN
diff_frames = (epoch_frame - frame + 1024) % 1024; // According to 38.331 Epochtime is defined for serving cell like this
}
LOG_I(NR_RRC, "Epoch frame %d ahead by %d frames\n", epoch_frame, diff_frames);
return diff_frames; return diff_frames;
} }
...@@ -257,11 +265,11 @@ static int get_ntn_timervalues(NR_UE_RRC_SI_INFO *SI_info, NR_NTN_Config_r17_t * ...@@ -257,11 +265,11 @@ static int get_ntn_timervalues(NR_UE_RRC_SI_INFO *SI_info, NR_NTN_Config_r17_t *
return sib19_timer_ms; return sib19_timer_ms;
} }
static void nr_rrc_process_ntnconfig(NR_UE_RRC_INST_t *rrc, NR_UE_RRC_SI_INFO *SI_info, NR_NTN_Config_r17_t *ntncfg, int frame) static void nr_rrc_process_ntnconfig(NR_UE_RRC_INST_t *rrc, NR_UE_RRC_SI_INFO *SI_info, NR_NTN_Config_r17_t *ntncfg, int frame, bool is_targetcell)
{ {
SI_info->SInfo_r17.sib19_validity = true; SI_info->SInfo_r17.sib19_validity = true;
// Check if Epochtime is sent or not // Check if Epochtime is sent or not
int diff_frames = eval_epoch_time(SI_info, ntncfg, frame); int diff_frames = eval_epoch_time(SI_info, ntncfg, frame, is_targetcell);
if (ntncfg->ntn_UlSyncValidityDuration_r17) { // ulsyncvalidity duration configured if (ntncfg->ntn_UlSyncValidityDuration_r17) { // ulsyncvalidity duration configured
int val430_ms = 0, sib19_timer_ms = 0; int val430_ms = 0, sib19_timer_ms = 0;
...@@ -361,7 +369,7 @@ static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si, ...@@ -361,7 +369,7 @@ static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si,
sib19 = typeandinfo->choice.sib19_v1700; sib19 = typeandinfo->choice.sib19_v1700;
if (g_log->log_component[NR_RRC].level >= OAILOG_DEBUG) if (g_log->log_component[NR_RRC].level >= OAILOG_DEBUG)
xer_fprint(stdout, &asn_DEF_NR_SIB19_r17, (const void *)sib19); xer_fprint(stdout, &asn_DEF_NR_SIB19_r17, (const void *)sib19);
nr_rrc_process_ntnconfig(rrc, SI_info, sib19->ntn_Config_r17, frame); nr_rrc_process_ntnconfig(rrc, SI_info, sib19->ntn_Config_r17, frame, false);
break; break;
default: default:
break; break;
...@@ -1454,6 +1462,11 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc, ...@@ -1454,6 +1462,11 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc,
uint8_t *const bufferP, uint8_t *const bufferP,
const uint8_t buffer_len) const uint8_t buffer_len)
{ {
// MIB received on the target cell. Now process target ntncfg once new timing is received.
if (phycellid == rrc->phyCellID && rrc->target_ntncfg) {
rrc->process_target_ntncfg = true;
}
NR_BCCH_BCH_Message_t *bcch_message = NULL; NR_BCCH_BCH_Message_t *bcch_message = NULL;
rrc->phyCellID = phycellid; rrc->phyCellID = phycellid;
rrc->arfcn_ssb = ssb_arfcn; rrc->arfcn_ssb = ssb_arfcn;
...@@ -1754,13 +1767,20 @@ static void nr_rrc_process_reconfigurationWithSync(NR_UE_RRC_INST_t *rrc, ...@@ -1754,13 +1767,20 @@ static void nr_rrc_process_reconfigurationWithSync(NR_UE_RRC_INST_t *rrc,
// 3GPP TS38.331 section 5.3.5.5.2 // 3GPP TS38.331 section 5.3.5.5.2
nr_timer_stop(&tac->T430); nr_timer_stop(&tac->T430);
if (rrc->target_ntncfg) {
ASN_STRUCT_FREE(asn_DEF_NR_NTN_Config_r17, rrc->target_ntncfg);
rrc->target_ntncfg = NULL;
rrc->process_target_ntncfg = false;
}
if (reconfigurationWithSync->spCellConfigCommon && if (reconfigurationWithSync->spCellConfigCommon &&
reconfigurationWithSync->spCellConfigCommon->ext2 && reconfigurationWithSync->spCellConfigCommon->ext2 &&
reconfigurationWithSync->spCellConfigCommon->ext2->ntn_Config_r17) { reconfigurationWithSync->spCellConfigCommon->ext2->ntn_Config_r17) {
NR_NTN_Config_r17_t *ntncfg = reconfigurationWithSync->spCellConfigCommon->ext2->ntn_Config_r17; NR_NTN_Config_r17_t *ntncfg = reconfigurationWithSync->spCellConfigCommon->ext2->ntn_Config_r17;
// EPOCH time is always sent if NTN config is sent through DCCH // EPOCH time is always sent if NTN config is sent through DCCH
AssertFatal(ntncfg->epochTime_r17, "NTN-CONFIG sent in dedicated mode should have EPOCHTIME\n"); AssertFatal(ntncfg->epochTime_r17, "NTN-CONFIG sent in dedicated mode should have EPOCHTIME\n");
nr_rrc_process_ntnconfig(rrc, &rrc->perNB[gNB_index].SInfo, ntncfg, rrc->current_frame); const int copy_result = asn_copy(&asn_DEF_NR_NTN_Config_r17, (void **)&rrc->target_ntncfg, ntncfg);
AssertFatal(copy_result == 0, "unable to copy NR_NTN_Config_r17_t\n");
} }
} }
...@@ -2626,6 +2646,13 @@ void *rrc_nrue(void *notUsed) ...@@ -2626,6 +2646,13 @@ void *rrc_nrue(void *notUsed)
nr_rrc_handle_timers(rrc); nr_rrc_handle_timers(rrc);
NR_UE_RRC_SI_INFO *SInfo = &rrc->perNB[NRRRC_FRAME_PROCESS(msg_p).gnb_id].SInfo; NR_UE_RRC_SI_INFO *SInfo = &rrc->perNB[NRRRC_FRAME_PROCESS(msg_p).gnb_id].SInfo;
nr_rrc_SI_timers(SInfo); nr_rrc_SI_timers(SInfo);
if (rrc->process_target_ntncfg) {
// Process target NTNCFG as the target cells timing is acquired
nr_rrc_process_ntnconfig(rrc, &rrc->perNB[NRRRC_FRAME_PROCESS(msg_p).gnb_id].SInfo, rrc->target_ntncfg, rrc->current_frame, true);
ASN_STRUCT_FREE(asn_DEF_NR_NTN_Config_r17, rrc->target_ntncfg);
rrc->target_ntncfg = NULL;
rrc->process_target_ntncfg = false;
}
break; break;
case NR_RRC_MAC_INAC_IND: case NR_RRC_MAC_INAC_IND:
...@@ -2806,6 +2833,14 @@ static void nr_rrc_initiate_rrcReestablishment(NR_UE_RRC_INST_t *rrc, NR_Reestab ...@@ -2806,6 +2833,14 @@ static void nr_rrc_initiate_rrcReestablishment(NR_UE_RRC_INST_t *rrc, NR_Reestab
set_DRB_status(rrc, i, RB_SUSPENDED); set_DRB_status(rrc, i, RB_SUSPENDED);
} }
} }
// Free Target NTNcfg is stored
if (rrc->target_ntncfg) {
ASN_STRUCT_FREE(asn_DEF_NR_NTN_Config_r17, rrc->target_ntncfg);
rrc->target_ntncfg = NULL;
rrc->process_target_ntncfg = false;
}
// release the MCG SCell(s), if configured // release the MCG SCell(s), if configured
// no SCell configured in our implementation // no SCell configured in our implementation
...@@ -2996,6 +3031,13 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, ...@@ -2996,6 +3031,13 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
asn1cFreeStruc(asn_DEF_NR_UE_TimersAndConstants, tac->sib1_TimersAndConstants); asn1cFreeStruc(asn_DEF_NR_UE_TimersAndConstants, tac->sib1_TimersAndConstants);
} }
// Free Target NTNcfg is stored
if (rrc->target_ntncfg) {
ASN_STRUCT_FREE(asn_DEF_NR_NTN_Config_r17, rrc->target_ntncfg);
rrc->target_ntncfg = NULL;
rrc->process_target_ntncfg = false;
}
// reset MAC // reset MAC
NR_UE_MAC_reset_cause_t cause = (rrc->nrRrcState == RRC_STATE_DETACH_NR) ? DETACH : GO_TO_IDLE; NR_UE_MAC_reset_cause_t cause = (rrc->nrRrcState == RRC_STATE_DETACH_NR) ? DETACH : GO_TO_IDLE;
nr_mac_rrc_message_t rrc_msg = {0}; nr_mac_rrc_message_t rrc_msg = {0};
......
...@@ -268,6 +268,8 @@ typedef struct NR_UE_RRC_INST_s { ...@@ -268,6 +268,8 @@ typedef struct NR_UE_RRC_INST_s {
NR_SL_PreconfigurationNR_r16_t *sl_preconfig; NR_SL_PreconfigurationNR_r16_t *sl_preconfig;
// NTN params // NTN params
bool is_NTN_UE; bool is_NTN_UE;
NR_NTN_Config_r17_t *target_ntncfg;
bool process_target_ntncfg;
notifiedFIFO_t *mac_input_nf; notifiedFIFO_t *mac_input_nf;
} NR_UE_RRC_INST_t; } NR_UE_RRC_INST_t;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment