Commit f2bdb6bb authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/NR_UE_timers_and_constants_functions'...

Merge remote-tracking branch 'origin/NR_UE_timers_and_constants_functions' into integration_2023_w23
parents 20366125 527c0164
......@@ -1457,7 +1457,7 @@ set(NR_L2_SRC_UE
${NR_RRC_DIR}/nr_rrc_config.c
${NR_UE_RRC_DIR}/rrc_UE.c
${NR_UE_RRC_DIR}/rrc_nsa.c
${NR_RRC_DIR}/nr_rrc_config.c
${NR_UE_RRC_DIR}/rrc_timers_and_constants.c
)
set (MAC_SRC
......
......@@ -938,6 +938,8 @@ void *UE_thread(void *arg) {
timing_advance = UE->timing_advance;
}
nr_ue_rrc_timer_trigger(UE->Mod_id, curMsg.proc.frame_tx, curMsg.proc.nr_slot_tx);
// Start TX slot processing here. It runs in parallel with RX slot processing
notifiedFIFO_elt_t *newElt = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), curMsg.proc.nr_slot_tx, &txFifo, processSlotTX);
nr_rxtx_thread_data_t *curMsgTx = (nr_rxtx_thread_data_t *) NotifiedFifoData(newElt);
......
......@@ -214,10 +214,6 @@ int create_tasks_nrue(uint32_t ue_nb) {
itti_wait_ready(0);
// Thread to update the RRC timers (in msec) at UE
pthread_t timers_update;
threadCreate(&timers_update, nr_rrc_timers_update, NULL, "nr_rrc_timer_update", -1, OAI_PRIORITY_RT_LOW);
return 0;
}
......
......@@ -38,7 +38,7 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
const int CC_id,
const uint8_t gNB_index,
const frame_t frame,
const sub_frame_t sub_frame,
const int slot,
const rnti_t rnti,
const channel_t channel,
const uint8_t* pduP,
......
......@@ -91,7 +91,7 @@ typedef struct RrcMacBcchDataInd_s {
typedef struct NRRrcMacBcchDataInd_s {
uint32_t frame;
uint8_t sub_frame;
uint8_t slot;
uint32_t sdu_size;
uint8_t sdu[BCCH_SDU_SIZE];
uint8_t gnb_index;
......@@ -140,7 +140,7 @@ typedef struct RrcMacCcchDataInd_s {
typedef struct NRRrcMacCcchDataInd_s {
uint32_t frame;
uint8_t sub_frame;
uint8_t slot;
uint16_t rnti;
uint32_t sdu_size;
uint8_t sdu[CCCH_SDU_SIZE];
......
......@@ -79,6 +79,7 @@ MESSAGE_DEF(NAS_DOWNLINK_DATA_IND, MESSAGE_PRIORITY_MED, NasDlDataInd
// eNB: realtime -> RRC messages
MESSAGE_DEF(RRC_SUBFRAME_PROCESS, MESSAGE_PRIORITY_MED, RrcSubframeProcess, rrc_subframe_process)
MESSAGE_DEF(NRRRC_SLOT_PROCESS, MESSAGE_PRIORITY_MED, NRRrcSlotProcess, nr_rrc_slot_process)
// eNB: RLC -> RRC messages
MESSAGE_DEF(RLC_SDU_INDICATION, MESSAGE_PRIORITY_MED, RlcSduIndication, rlc_sdu_indication)
......@@ -88,6 +88,7 @@
#define NAS_DOWNLINK_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_data_ind
#define RRC_SUBFRAME_PROCESS(mSGpTR) (mSGpTR)->ittiMsg.rrc_subframe_process
#define NRRRC_SLOT_PROCESS(mSGpTR) (mSGpTR)->ittiMsg.nr_rrc_slot_process
#define RLC_SDU_INDICATION(mSGpTR) (mSGpTR)->ittiMsg.rlc_sdu_indication
#define NRDuDlReq(mSGpTR) (mSGpTR)->ittiMsg.nr_du_dl_req
......@@ -460,9 +461,14 @@ typedef dl_info_transfer_ind_t NasDlDataInd;
// eNB: realtime -> RRC messages
typedef struct rrc_subframe_process_s {
protocol_ctxt_t ctxt;
int CC_id;
int CC_id;
} RrcSubframeProcess;
typedef struct nrrrc_slot_process_s {
int frame;
int slot;
} NRRrcSlotProcess;
// eNB: RLC -> RRC messages
typedef struct rlc_sdu_indication_s {
int rnti;
......
......@@ -115,12 +115,12 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance,
ccch_sdu_len = rrccont->value.choice.RRCContainer.size;
memcpy(RRC_MAC_CCCH_DATA_IND (message_p).sdu, rrccont->value.choice.RRCContainer.buf,
ccch_sdu_len);
NR_RRC_MAC_CCCH_DATA_IND (message_p).frame = 0;
NR_RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = 0;
NR_RRC_MAC_CCCH_DATA_IND (message_p).frame = 0;
NR_RRC_MAC_CCCH_DATA_IND (message_p).slot = 0;
NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = ccch_sdu_len;
NR_RRC_MAC_CCCH_DATA_IND (message_p).nr_cellid = nr_cellid; // CU instance
NR_RRC_MAC_CCCH_DATA_IND (message_p).rnti = rnti;
NR_RRC_MAC_CCCH_DATA_IND (message_p).CC_id = CC_id;
NR_RRC_MAC_CCCH_DATA_IND (message_p).rnti = rnti;
NR_RRC_MAC_CCCH_DATA_IND (message_p).CC_id = CC_id;
if (du2cu) {
NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container = malloc(sizeof(OCTET_STRING_t));
NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->size = du2cu->value.choice.DUtoCURRCContainer.size;
......
......@@ -206,8 +206,6 @@ typedef int (nr_ue_dl_indication_f)(nr_downlink_indication_t *dl_info);
*/
typedef int (nr_ue_ul_indication_f)(nr_uplink_indication_t *ul_info);
typedef int (nr_ue_dcireq_f)(nr_dcireq_t *ul_info);
// TODO check this stuff can be reuse of need modification
typedef struct nr_ue_if_module_s {
nr_ue_scheduled_response_f *scheduled_response;
......@@ -215,7 +213,6 @@ typedef struct nr_ue_if_module_s {
nr_ue_synch_request_f *synch_request;
nr_ue_dl_indication_f *dl_indication;
nr_ue_ul_indication_f *ul_indication;
//nr_ue_dcireq_f *dcireq;
uint32_t cc_mask;
uint32_t current_frame;
uint32_t current_slot;
......
......@@ -39,91 +39,90 @@
typedef uint32_t channel_t;
int8_t
nr_mac_rrc_data_ind_ue(
const module_id_t module_id,
const int CC_id,
const uint8_t gNB_index,
const frame_t frame,
const sub_frame_t sub_frame,
const rnti_t rnti,
const channel_t channel,
const uint8_t* pduP,
const sdu_size_t pdu_len){
sdu_size_t sdu_size = 0;
switch(channel){
case NR_BCCH_BCH:
AssertFatal( nr_rrc_ue_decode_NR_BCCH_BCH_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len) == 0, "UE decode BCCH-BCH error!\n");
break;
case NR_BCCH_DL_SCH:
if (pdu_len>0) {
LOG_T(NR_RRC, "[UE %d] Received SDU for NR-BCCH-DL-SCH on SRB %u from gNB %d\n", module_id, channel & RAB_OFFSET,
gNB_index);
MessageDef *message_p;
int msg_sdu_size = BCCH_SDU_SIZE;
if (pdu_len > msg_sdu_size) {
LOG_E(NR_RRC, "SDU larger than NR-BCCH-DL-SCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size);
sdu_size = msg_sdu_size;
} else {
sdu_size = pdu_len;
}
message_p = itti_alloc_new_message(TASK_MAC_UE, 0, NR_RRC_MAC_BCCH_DATA_IND);
memset(NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE);
memcpy(NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, pduP, sdu_size);
NR_RRC_MAC_BCCH_DATA_IND (message_p).frame = frame; //frameP
NR_RRC_MAC_BCCH_DATA_IND (message_p).sub_frame = sub_frame; //sub_frameP
NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = sdu_size;
NR_RRC_MAC_BCCH_DATA_IND (message_p).gnb_index = gNB_index;
itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(module_id), message_p);
int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
const int CC_id,
const uint8_t gNB_index,
const frame_t frame,
const int slot,
const rnti_t rnti,
const channel_t channel,
const uint8_t* pduP,
const sdu_size_t pdu_len)
{
sdu_size_t sdu_size = 0;
switch(channel){
case NR_BCCH_BCH:
AssertFatal(nr_rrc_ue_decode_NR_BCCH_BCH_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len) == 0, "UE decode BCCH-BCH error!\n");
break;
case NR_BCCH_DL_SCH:
if (pdu_len>0) {
LOG_T(NR_RRC, "[UE %d] Received SDU for NR-BCCH-DL-SCH on SRB %u from gNB %d\n", module_id, channel & RAB_OFFSET,
gNB_index);
MessageDef *message_p;
int msg_sdu_size = BCCH_SDU_SIZE;
if (pdu_len > msg_sdu_size) {
LOG_E(NR_RRC, "SDU larger than NR-BCCH-DL-SCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size);
sdu_size = msg_sdu_size;
} else {
sdu_size = pdu_len;
}
break;
case CCCH:
if (pdu_len>0) {
LOG_T(NR_RRC,"[UE %d] Received SDU for CCCH on SRB %u from gNB %d\n",module_id,channel & RAB_OFFSET,gNB_index);
MessageDef *message_p;
int msg_sdu_size = CCCH_SDU_SIZE;
if (pdu_len > msg_sdu_size) {
LOG_E(NR_RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size);
sdu_size = msg_sdu_size;
} else {
sdu_size = pdu_len;
}
message_p = itti_alloc_new_message (TASK_MAC_UE, 0, NR_RRC_MAC_CCCH_DATA_IND);
memset (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE);
memcpy (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, pduP, sdu_size);
NR_RRC_MAC_CCCH_DATA_IND (message_p).frame = frame; //frameP
NR_RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = sub_frame; //sub_frameP
NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = sdu_size;
NR_RRC_MAC_CCCH_DATA_IND (message_p).gnb_index = gNB_index;
NR_RRC_MAC_CCCH_DATA_IND (message_p).rnti = rnti; //rntiP
itti_send_msg_to_task (TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE( module_id ), message_p);
message_p = itti_alloc_new_message(TASK_MAC_UE, 0, NR_RRC_MAC_BCCH_DATA_IND);
memset(NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE);
memcpy(NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, pduP, sdu_size);
NR_RRC_MAC_BCCH_DATA_IND (message_p).frame = frame; //frameP
NR_RRC_MAC_BCCH_DATA_IND (message_p).slot = slot;
NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = sdu_size;
NR_RRC_MAC_BCCH_DATA_IND (message_p).gnb_index = gNB_index;
itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(module_id), message_p);
}
break;
case CCCH:
if (pdu_len>0) {
LOG_T(NR_RRC,"[UE %d] Received SDU for CCCH on SRB %u from gNB %d\n",module_id,channel & RAB_OFFSET,gNB_index);
MessageDef *message_p;
int msg_sdu_size = CCCH_SDU_SIZE;
if (pdu_len > msg_sdu_size) {
LOG_E(NR_RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size);
sdu_size = msg_sdu_size;
} else {
sdu_size = pdu_len;
}
break;
default:
break;
}
message_p = itti_alloc_new_message (TASK_MAC_UE, 0, NR_RRC_MAC_CCCH_DATA_IND);
memset (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE);
memcpy (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, pduP, sdu_size);
NR_RRC_MAC_CCCH_DATA_IND (message_p).frame = frame; //frameP
NR_RRC_MAC_CCCH_DATA_IND (message_p).slot = slot;
NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = sdu_size;
NR_RRC_MAC_CCCH_DATA_IND (message_p).gnb_index = gNB_index;
NR_RRC_MAC_CCCH_DATA_IND (message_p).rnti = rnti; //rntiP
itti_send_msg_to_task (TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE( module_id ), message_p);
}
break;
default:
break;
}
return(0);
return(0);
}
int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
const int CC_id,
const uint8_t gNB_id,
const frame_t frameP,
const rb_id_t Srb_id,
uint8_t *buffer_pP){
switch(Srb_id){
const int CC_id,
const uint8_t gNB_id,
const frame_t frameP,
const rb_id_t Srb_id,
uint8_t *buffer_pP)
{
switch(Srb_id) {
case CCCH:
......@@ -148,9 +147,9 @@ int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index)
{
if (NR_UE_rrc_inst[mod_id].timers_and_constants.T304_active == 1) {
if (NR_UE_rrc_inst[mod_id].timers_and_constants.T304_active == true) {
LOG_W(NR_RRC, "T304 was stoped with value %i\n", NR_UE_rrc_inst[mod_id].timers_and_constants.T304_cnt);
NR_UE_rrc_inst[mod_id].timers_and_constants.T304_active = 0;
NR_UE_rrc_inst[mod_id].timers_and_constants.T304_active = false;
NR_UE_rrc_inst[mod_id].timers_and_constants.T304_cnt = 0;
}
return 0;
......
......@@ -229,7 +229,7 @@ int8_t nr_rrc_ue_decode_secondary_cellgroup_config(const module_id_t module_id,
LOG_E(NR_RRC, "%02x ",buffer[i]);
LOG_E(NR_RRC, "\n");
// free the memory
SEQUENCE_free( &asn_DEF_NR_CellGroupConfig, (void *)cell_group_config, 1 );
SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)cell_group_config, 1);
return -1;
}
......@@ -238,6 +238,9 @@ int8_t nr_rrc_ue_decode_secondary_cellgroup_config(const module_id_t module_id,
else
SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)cell_group_config, 0);
if(cell_group_config->spCellConfig != NULL)
configure_spcell(&NR_UE_rrc_inst[module_id], cell_group_config->spCellConfig);
return 0;
}
......@@ -268,7 +271,7 @@ int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCR
(uint8_t *)rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->buf,
rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->size, 0, 0);
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
}
......@@ -280,6 +283,10 @@ int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCR
SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)NR_UE_rrc_inst[module_id].cell_group_config, 0);
NR_UE_rrc_inst[module_id].cell_group_config = cellGroupConfig;
}
if(cellGroupConfig->spCellConfig != NULL)
configure_spcell(&NR_UE_rrc_inst[module_id], cellGroupConfig->spCellConfig);
if (get_softmodem_params()->nsa) {
nr_rrc_mac_config_req_scg(0, 0, cellGroupConfig);
}
......@@ -386,24 +393,28 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type,
}
NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* rrc_config_path){
int nr_ue;
if(NB_NR_UE_INST > 0){
NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* rrc_config_path)
{
if(NB_NR_UE_INST > 0) {
NR_UE_rrc_inst = (NR_UE_RRC_INST_t *)calloc(NB_NR_UE_INST , sizeof(NR_UE_RRC_INST_t));
for(nr_ue=0;nr_ue<NB_NR_UE_INST;nr_ue++){
for(int nr_ue = 0; nr_ue < NB_NR_UE_INST; nr_ue++) {
NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[nr_ue];
// fill UE-NR-Capability @ UE-CapabilityRAT-Container here.
NR_UE_rrc_inst[nr_ue].selected_plmn_identity = 1;
rrc->selected_plmn_identity = 1;
rrc->bwpd = NULL;
rrc->ubwpd = NULL;
// TODO: Put the appropriate list of SIBs
NR_UE_rrc_inst[nr_ue].requested_SI_List.buf = CALLOC(1,4);
NR_UE_rrc_inst[nr_ue].requested_SI_List.buf[0] = SIB2 | SIB3 | SIB5; // SIB2 - SIB9
NR_UE_rrc_inst[nr_ue].requested_SI_List.buf[1] = 0; // SIB10 - SIB17
NR_UE_rrc_inst[nr_ue].requested_SI_List.buf[2] = 0; // SIB18 - SIB25
NR_UE_rrc_inst[nr_ue].requested_SI_List.buf[3] = 0; // SIB26 - SIB32
NR_UE_rrc_inst[nr_ue].requested_SI_List.size= 4;
NR_UE_rrc_inst[nr_ue].requested_SI_List.bits_unused= 0;
NR_UE_rrc_inst[nr_ue].ra_trigger = RA_NOT_RUNNING;
rrc->requested_SI_List.buf = CALLOC(1,4);
rrc->requested_SI_List.buf[0] = SIB2 | SIB3 | SIB5; // SIB2 - SIB9
rrc->requested_SI_List.buf[1] = 0; // SIB10 - SIB17
rrc->requested_SI_List.buf[2] = 0; // SIB18 - SIB25
rrc->requested_SI_List.buf[3] = 0; // SIB26 - SIB32
rrc->requested_SI_List.size= 4;
rrc->requested_SI_List.bits_unused= 0;
rrc->ra_trigger = RA_NOT_RUNNING;
}
NR_UE_rrc_inst->uecap_file = uecap_file;
......@@ -473,11 +484,6 @@ int8_t nr_ue_process_physical_cell_group_config(NR_PhysicalCellGroupConfig_t *ph
return 0;
}
int8_t nr_ue_process_spcell_config(NR_SpCellConfig_t *spcell_config){
return 0;
}
/*brief decode BCCH-BCH (MIB) message*/
int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message(const module_id_t module_id, const uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len)
{
......@@ -1031,32 +1037,32 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id,
NR_BCCH_DL_SCH_Message_t *bcch_message = NULL;
NR_UE_RRC_SI_INFO *SI_info = &NR_UE_rrc_inst[module_id].SInfo[gNB_index];
NR_SIB1_t *sib1 = SI_info->sib1;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_IN );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_IN);
if (((SI_info->SIStatus & 1) == 1) && sib1->si_SchedulingInfo &&// SIB1 received
(SI_info->SIcnt == sib1->si_SchedulingInfo->schedulingInfoList.list.count)) {
// to prevent memory bloating
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT);
return 0;
}
nr_rrc_set_sub_state( module_id, RRC_SUB_STATE_IDLE_RECEIVING_SIB_NR );
nr_rrc_set_sub_state(module_id, RRC_SUB_STATE_IDLE_RECEIVING_SIB_NR);
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
&asn_DEF_NR_BCCH_DL_SCH_Message,
(void **)&bcch_message,
(const void *)Sdu,
Sdu_len );
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
&asn_DEF_NR_BCCH_DL_SCH_Message,
(void **)&bcch_message,
(const void *)Sdu,
Sdu_len);
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message );
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message);
}
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
LOG_E( NR_RRC, "[UE %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n",
LOG_E(NR_RRC, "[UE %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n",
module_id,
dec_rval.consumed );
log_dump(NR_RRC, Sdu, Sdu_len, LOG_DUMP_CHAR," Received bytes:\n" );
dec_rval.consumed);
log_dump(NR_RRC, Sdu, Sdu_len, LOG_DUMP_CHAR," Received bytes:\n");
// free the memory
SEQUENCE_free( &asn_DEF_NR_BCCH_DL_SCH_Message, (void *)bcch_message, 1 );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT );
......@@ -1067,14 +1073,14 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id,
switch (bcch_message->message.choice.c1->present) {
case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1:
if ((SI_info->SIStatus & 1) == 0) {
if(sib1 != NULL){
SEQUENCE_free(&asn_DEF_NR_SIB1, (void *)sib1, 1 );
if(sib1 != NULL) {
SEQUENCE_free(&asn_DEF_NR_SIB1, (void *)sib1, 1);
}
SI_info->SIStatus |= 1;
sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1;
if (*(int64_t*)sib1 != 1) {
SI_info->sib1 = sib1;
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_SIB1, (const void *) SI_info->sib1);
}
LOG_A(NR_RRC, "SIB1 decoded\n");
......@@ -1083,11 +1089,13 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id,
// FIXME: improve condition for the RA trigger
// Check for on-demand not broadcasted SI
check_requested_SI_List(module_id, NR_UE_rrc_inst[module_id].requested_SI_List, *sib1);
if( nr_rrc_get_state(module_id) <= RRC_STATE_IDLE_NR ) {
if(nr_rrc_get_state(module_id) <= RRC_STATE_IDLE_NR) {
NR_UE_rrc_inst[module_id].ra_trigger = INITIAL_ACCESS_FROM_RRC_IDLE;
LOG_D(PHY,"Setting state to RRC_STATE_IDLE_NR\n");
nr_rrc_set_state (module_id, RRC_STATE_IDLE_NR);
}
// configure timers and constant
nr_rrc_set_sib1_timers_and_constants(&NR_UE_rrc_inst[module_id].timers_and_constants, sib1);
// take ServingCellConfigCommon and configure L1/L2
NR_UE_rrc_inst[module_id].servingCellConfigCommonSIB = sib1->servingCellConfigCommon;
nr_rrc_mac_config_req_sib1(module_id, 0, sib1->servingCellConfigCommon);
......@@ -1135,88 +1143,55 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id,
return 0;
}
//-----------------------------------------------------------------------------
void nr_rrc_ue_process_masterCellGroup(const protocol_ctxt_t *const ctxt_pP,
uint8_t gNB_index,
OCTET_STRING_t *masterCellGroup)
//-----------------------------------------------------------------------------
OCTET_STRING_t *masterCellGroup,
long *fullConfig)
{
NR_CellGroupConfig_t *cellGroupConfig=NULL;
NR_CellGroupConfig_t *cellGroupConfig = NULL;
uper_decode(NULL,
&asn_DEF_NR_CellGroupConfig, //might be added prefix later
(void **)&cellGroupConfig,
(uint8_t *)masterCellGroup->buf,
masterCellGroup->size, 0, 0);
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
}
// TS 38.331 - Section 5.3.5.5.2 Reconfiguration with sync
if (cellGroupConfig->spCellConfig != NULL && cellGroupConfig->spCellConfig->reconfigurationWithSync != NULL) {
LOG_A(NR_RRC, "Received the reconfigurationWithSync in %s\n", __FUNCTION__);
NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[ctxt_pP->module_id];
NR_ReconfigurationWithSync_t *reconfigurationWithSync = cellGroupConfig->spCellConfig->reconfigurationWithSync;
NR_UE_Timers_Constants_t *timers_and_constants = &NR_UE_rrc_inst[ctxt_pP->module_id].timers_and_constants;
timers_and_constants->T304_active = 1;
switch (reconfigurationWithSync->t304) {
case NR_ReconfigurationWithSync__t304_ms100:
timers_and_constants->T304_cnt = 100;
break;
case NR_ReconfigurationWithSync__t304_ms150:
timers_and_constants->T304_cnt = 150;
break;
case NR_ReconfigurationWithSync__t304_ms200:
timers_and_constants->T304_cnt = 200;
break;
case NR_ReconfigurationWithSync__t304_ms500:
timers_and_constants->T304_cnt = 500;
break;
case NR_ReconfigurationWithSync__t304_ms1000:
timers_and_constants->T304_cnt = 1000;
break;
case NR_ReconfigurationWithSync__t304_ms2000:
timers_and_constants->T304_cnt = 2000;
break;
case NR_ReconfigurationWithSync__t304_ms10000:
timers_and_constants->T304_cnt = 10000;
break;
default:
timers_and_constants->T304_cnt = 50;
}
}
if(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config == NULL){
NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config = calloc(1,sizeof(NR_CellGroupConfig_t));
if(rrc->cell_group_config == NULL){
rrc->cell_group_config = calloc(1,sizeof(NR_CellGroupConfig_t));
}
if( cellGroupConfig->rlc_BearerToReleaseList != NULL){
if(cellGroupConfig->rlc_BearerToReleaseList != NULL){
//TODO (perform RLC bearer release as specified in 5.3.5.5.3)
}
if( cellGroupConfig->rlc_BearerToAddModList != NULL){
if(cellGroupConfig->rlc_BearerToAddModList != NULL){
//TODO (perform the RLC bearer addition/modification as specified in 5.3.5.5.4)
if(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList != NULL){
if(rrc->cell_group_config->rlc_BearerToAddModList != NULL){
// Laurent: there are cases where the not NULL value is also not coming from a previous malloc
// so it is better to let the potential memory leak than corrupting the heap //free(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList);
// so it is better to let the potential memory leak than corrupting the heap //free(rrc->cell_group_config->rlc_BearerToAddModList);
}
NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList = calloc(1, sizeof(struct NR_CellGroupConfig__rlc_BearerToAddModList));
memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList,cellGroupConfig->rlc_BearerToAddModList,
rrc->cell_group_config->rlc_BearerToAddModList = calloc(1, sizeof(struct NR_CellGroupConfig__rlc_BearerToAddModList));
memcpy(rrc->cell_group_config->rlc_BearerToAddModList,cellGroupConfig->rlc_BearerToAddModList,
sizeof(struct NR_CellGroupConfig__rlc_BearerToAddModList));
}
if( cellGroupConfig->mac_CellGroupConfig != NULL){
if(cellGroupConfig->mac_CellGroupConfig != NULL){
//TODO (configure the MAC entity of this cell group as specified in 5.3.5.5.5)
LOG_I(RRC, "Received mac_CellGroupConfig from gNB\n");
if(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig != NULL){
if(rrc->cell_group_config->mac_CellGroupConfig != NULL){
LOG_E(RRC, "UE RRC instance already contains mac CellGroupConfig which will be overwritten\n");
// Laurent: there are cases where the not NULL value is also not coming from a previous malloc
// so it is better to let the potential memory leak than corrupting the heap
//free(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig);
//free(rrc->cell_group_config->mac_CellGroupConfig);
}
NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig = malloc(sizeof(struct NR_MAC_CellGroupConfig));
memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig,cellGroupConfig->mac_CellGroupConfig,
rrc->cell_group_config->mac_CellGroupConfig = malloc(sizeof(struct NR_MAC_CellGroupConfig));
memcpy(rrc->cell_group_config->mac_CellGroupConfig,cellGroupConfig->mac_CellGroupConfig,
sizeof(struct NR_MAC_CellGroupConfig));
}
......@@ -1225,21 +1200,34 @@ void nr_rrc_ue_process_masterCellGroup(const protocol_ctxt_t *const ctxt_pP,
}
if(cellGroupConfig->spCellConfig != NULL) {
if (NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config &&
NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig) {
memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig,cellGroupConfig->spCellConfig,
configure_spcell(rrc, cellGroupConfig->spCellConfig);
// TS 38.331 - Section 5.3.5.5.2 Reconfiguration with sync
if (cellGroupConfig->spCellConfig->reconfigurationWithSync != NULL) {
if(fullConfig)
set_default_timers_and_constants(&rrc->timers_and_constants);
LOG_A(NR_RRC, "Received the reconfigurationWithSync in %s\n", __FUNCTION__);
NR_ReconfigurationWithSync_t *reconfigurationWithSync = cellGroupConfig->spCellConfig->reconfigurationWithSync;
nr_rrc_set_T304(&rrc->timers_and_constants, reconfigurationWithSync);
}
if (rrc->cell_group_config &&
rrc->cell_group_config->spCellConfig) {
memcpy(rrc->cell_group_config->spCellConfig,cellGroupConfig->spCellConfig,
sizeof(struct NR_SpCellConfig));
} else {
if (NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config)
NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig = cellGroupConfig->spCellConfig;
if (rrc->cell_group_config)
rrc->cell_group_config->spCellConfig = cellGroupConfig->spCellConfig;
else
NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config = cellGroupConfig;
rrc->cell_group_config = cellGroupConfig;
}
LOG_D(RRC,"Sending CellGroupConfig to MAC\n");
nr_rrc_mac_config_req_mcg(ctxt_pP->module_id, 0, cellGroupConfig);
//TODO (configure the SpCell as specified in 5.3.5.5.7)
}
if(fullConfig)
// full configuration after re-establishment or during RRC resume
nr_rrc_set_sib1_timers_and_constants(&rrc->timers_and_constants, rrc->SInfo[gNB_index].sib1);
if( cellGroupConfig->sCellToAddModList != NULL){
//TODO (perform SCell addition/modification as specified in 5.3.5.5.9)
}
......@@ -1253,6 +1241,51 @@ void nr_rrc_ue_process_masterCellGroup(const protocol_ctxt_t *const ctxt_pP,
}
}
void configure_spcell(NR_UE_RRC_INST_t *rrc, NR_SpCellConfig_t *spcell_config)
{
nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(rrc, spcell_config->rlf_TimersAndConstants);
if(spcell_config->spCellConfigDedicated) {
NR_ServingCellConfig_t *scd = spcell_config->spCellConfigDedicated;
if(scd->firstActiveDownlinkBWP_Id) {
if(*scd->firstActiveDownlinkBWP_Id == 0)
rrc->bwpd = scd->initialDownlinkBWP;
else {
AssertFatal(scd->downlinkBWP_ToAddModList, "No DL BWP list configured\n");
const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = scd->downlinkBWP_ToAddModList;
NR_BWP_Downlink_t *dl_bwp = NULL;
for (int i = 0; i < bwpList->list.count; i++) {
dl_bwp = bwpList->list.array[i];
if(dl_bwp->bwp_Id == *scd->firstActiveDownlinkBWP_Id)
break;
}
AssertFatal(dl_bwp != NULL,"Couldn't find DLBWP corresponding to BWP ID %ld\n", *scd->firstActiveDownlinkBWP_Id);
rrc->bwpd = dl_bwp->bwp_Dedicated;
}
// if any of the reference signal(s) that are used for radio link monitoring are reconfigured by the received spCellConfigDedicated
// reset RLF timers and constants
if (rrc->bwpd->radioLinkMonitoringConfig)
reset_rlf_timers_and_constants(&rrc->timers_and_constants);
}
if(scd->uplinkConfig && scd->uplinkConfig->firstActiveUplinkBWP_Id) {
if(*scd->uplinkConfig->firstActiveUplinkBWP_Id == 0)
rrc->ubwpd = scd->uplinkConfig->initialUplinkBWP;
else {
AssertFatal(scd->uplinkConfig->uplinkBWP_ToAddModList, "No UL BWP list configured\n");
const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = scd->uplinkConfig->uplinkBWP_ToAddModList;
NR_BWP_Uplink_t *ul_bwp = NULL;
for (int i = 0; i < ubwpList->list.count; i++) {
ul_bwp = ubwpList->list.array[i];
if(ul_bwp->bwp_Id == *scd->uplinkConfig->firstActiveUplinkBWP_Id)
break;
}
AssertFatal(ul_bwp != NULL,"Couldn't find DLBWP corresponding to BWP ID %ld\n", *scd->uplinkConfig->firstActiveUplinkBWP_Id);
rrc->ubwpd = ul_bwp->bwp_Dedicated;
}
}
}
}
/*--------------------------------------------------*/
static void rrc_ue_generate_RRCSetupComplete(
const protocol_ctxt_t *const ctxt_pP,
......@@ -1345,7 +1378,7 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB
// Release T300 timer
NR_UE_rrc_inst[ctxt_pP->module_id].timers_and_constants.T300_active = 0;
nr_rrc_ue_process_masterCellGroup(ctxt_pP, gNB_index, &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup);
nr_rrc_ue_process_masterCellGroup(ctxt_pP, gNB_index, &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup, NULL);
nr_rrc_ue_process_RadioBearerConfig(ctxt_pP, gNB_index, &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig);
nr_rrc_set_state(ctxt_pP->module_id, RRC_STATE_CONNECTED_NR);
nr_rrc_set_sub_state(ctxt_pP->module_id, RRC_SUB_STATE_CONNECTED_NR);
......@@ -2044,11 +2077,11 @@ nr_rrc_ue_establish_srb2(
// nr_rrc_ue_process_measConfig(ctxt_pP, gNB_index, ie->measConfig);
}
if((ie->nonCriticalExtension) && (ie->nonCriticalExtension->masterCellGroup!=NULL)) {
nr_rrc_ue_process_masterCellGroup(
ctxt_pP,
gNB_index,
ie->nonCriticalExtension->masterCellGroup);
if((ie->nonCriticalExtension) && (ie->nonCriticalExtension->masterCellGroup != NULL)) {
nr_rrc_ue_process_masterCellGroup(ctxt_pP,
gNB_index,
ie->nonCriticalExtension->masterCellGroup,
ie->nonCriticalExtension->fullConfig);
}
if (ie->radioBearerConfig != NULL) {
......@@ -2231,15 +2264,33 @@ nr_rrc_ue_establish_srb2(
return 0;
}
//-----------------------------------------------------------------------------
void *rrc_nrue_task( void *args_p ) {
MessageDef *msg_p;
instance_t instance;
unsigned int ue_mod_id;
int result;
NR_SRB_INFO *srb_info_p;
protocol_ctxt_t ctxt;
itti_mark_task_ready (TASK_RRC_NRUE);
void nr_rrc_handle_timers(unsigned int mod_id)
{
NR_UE_Timers_Constants_t *timers = &NR_UE_rrc_inst[mod_id].timers_and_constants;
// T304
if (timers->T304_active == true) {
timers->T304_cnt += 10;
if(timers->T304_cnt >= timers->T304_k) {
// TODO
// For T304 of MCG, in case of the handover from NR or intra-NR
// handover, initiate the RRC re-establishment procedure;
// In case of handover to NR, perform the actions defined in the
// specifications applicable for the source RAT.
}
}
}
void *rrc_nrue_task(void *args_p)
{
MessageDef *msg_p;
instance_t instance;
unsigned int ue_mod_id;
int result;
NR_SRB_INFO *srb_info_p;
protocol_ctxt_t ctxt;
itti_mark_task_ready(TASK_RRC_NRUE);
while(1) {
// Wait for a message
......@@ -2257,16 +2308,22 @@ nr_rrc_ue_establish_srb2(
LOG_D(NR_RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p));
break;
case NRRRC_SLOT_PROCESS:
LOG_D(NR_RRC, "[UE %d] Receided %s: frame %d slot %d\n",
ue_mod_id, ITTI_MSG_NAME (msg_p), NRRRC_SLOT_PROCESS (msg_p).frame, NRRRC_SLOT_PROCESS (msg_p).slot);
nr_rrc_handle_timers(ue_mod_id);
break;
case NR_RRC_MAC_BCCH_DATA_IND:
LOG_D(NR_RRC, "[UE %d] Received %s: frameP %d, gNB %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p),
NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index);
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NOT_A_RNTI, NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0,NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index);
nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message (ctxt.module_id,
NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index,
NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu,
NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu_size,
NR_RRC_MAC_BCCH_DATA_IND (msg_p).rsrq,
NR_RRC_MAC_BCCH_DATA_IND (msg_p).rsrp);
NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index,
NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu,
NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu_size,
NR_RRC_MAC_BCCH_DATA_IND (msg_p).rsrq,
NR_RRC_MAC_BCCH_DATA_IND (msg_p).rsrp);
break;
case NR_RRC_MAC_CCCH_DATA_IND:
......@@ -2278,18 +2335,24 @@ nr_rrc_ue_establish_srb2(
NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
srb_info_p = &NR_UE_rrc_inst[ue_mod_id].Srb0[NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index];
memcpy (srb_info_p->Rx_buffer.Payload, NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu,
NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size);
NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size);
srb_info_p->Rx_buffer.payload_size = NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size;
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0);
// PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0, NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
nr_rrc_ue_decode_ccch (&ctxt,
srb_info_p,
NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
// PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0, NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
nr_rrc_ue_decode_ccch (&ctxt,
srb_info_p,
NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
break;
/* PDCP messages */
case NR_RRC_DCCH_DATA_IND:
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, NR_RRC_DCCH_DATA_IND (msg_p).module_id, GNB_FLAG_NO, NR_RRC_DCCH_DATA_IND (msg_p).rnti, NR_RRC_DCCH_DATA_IND (msg_p).frame, 0,NR_RRC_DCCH_DATA_IND (msg_p).gNB_index);
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt,
NR_RRC_DCCH_DATA_IND (msg_p).module_id,
GNB_FLAG_NO,
NR_RRC_DCCH_DATA_IND (msg_p).rnti,
NR_RRC_DCCH_DATA_IND (msg_p).frame,
0,
NR_RRC_DCCH_DATA_IND (msg_p).gNB_index);
LOG_D(NR_RRC, "[UE %d] Received %s: frameP %d, DCCH %d, gNB %d\n",
NR_RRC_DCCH_DATA_IND (msg_p).module_id,
ITTI_MSG_NAME (msg_p),
......@@ -2725,28 +2788,12 @@ void process_lte_nsa_msg(nsa_msg_t *msg, int msg_len)
}
}
void *nr_rrc_timers_update() {
while (1) {
for (int mod_id = 0; mod_id < NB_NR_UE_INST; mod_id++) {
for (int i = 0; i < NB_SIG_CNX_UE; i++) {
NR_UE_Timers_Constants_t *timers = &NR_UE_rrc_inst[mod_id].timers_and_constants;
// T304
if (timers->T304_active == 1) {
if ((timers->T304_cnt % 100) == 0) {
LOG_W(NR_RRC, "T304: %u\n", timers->T304_cnt);
}
if (timers->T304_cnt == 1) {
timers->T304_active = 0;
}
timers->T304_cnt--;
}
}
}
usleep(1000);
}
void nr_ue_rrc_timer_trigger(int module_id, int frame, int slot)
{
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NRRRC_SLOT_PROCESS);
NRRRC_SLOT_PROCESS(message_p).frame = frame;
NRRRC_SLOT_PROCESS(message_p).slot = slot;
LOG_D(NR_RRC, "RRC timer trigger: frame %d slot %d \n", frame, slot);
itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(module_id), message_p);
}
......@@ -224,6 +224,10 @@ typedef struct NR_UE_RRC_INST_s {
NR_MIB_t *mib;
// active BWPs
NR_BWP_DownlinkDedicated_t *bwpd;
NR_BWP_UplinkDedicated_t *ubwpd;
/* KeNB as computed from parameters within USIM card */
uint8_t kgnb[32];
/* Used integrity/ciphering algorithms */
......
......@@ -107,7 +107,7 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
const int CC_id,
const uint8_t gNB_index,
const frame_t frame,
const sub_frame_t sub_frame,
const int slot,
const rnti_t rnti,
const channel_t channel,
const uint8_t* pduP,
......@@ -155,6 +155,16 @@ void process_lte_nsa_msg(nsa_msg_t *msg, int msg_len);
int get_from_lte_ue_fd();
void nr_ue_rrc_timer_trigger(int module_id, int frame, int slot);
void configure_spcell(NR_UE_RRC_INST_t *rrc, NR_SpCellConfig_t *spcell_config);
void reset_rlf_timers_and_constants(NR_UE_Timers_Constants_t *tac);
void set_default_timers_and_constants(NR_UE_Timers_Constants_t *tac);
void nr_rrc_set_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t *sib1);
void nr_rrc_set_T304(NR_UE_Timers_Constants_t *tac, NR_ReconfigurationWithSync_t *reconfigurationWithSync);
void nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(NR_UE_RRC_INST_t *rrc,
struct NR_SetupRelease_RLF_TimersAndConstants *rlf_TimersAndConstants);
/** @}*/
#endif
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "openair2/RRC/NR_UE/rrc_proto.h"
void nr_rrc_set_T304(NR_UE_Timers_Constants_t *tac, NR_ReconfigurationWithSync_t *reconfigurationWithSync)
{
if(reconfigurationWithSync) {
switch (reconfigurationWithSync->t304) {
case NR_ReconfigurationWithSync__t304_ms50 :
tac->T304_k = 50;
break;
case NR_ReconfigurationWithSync__t304_ms100 :
tac->T304_k = 100;
break;
case NR_ReconfigurationWithSync__t304_ms150 :
tac->T304_k = 150;
break;
case NR_ReconfigurationWithSync__t304_ms200 :
tac->T304_k = 200;
break;
case NR_ReconfigurationWithSync__t304_ms500 :
tac->T304_k = 500;
break;
case NR_ReconfigurationWithSync__t304_ms1000 :
tac->T304_k = 1000;
break;
case NR_ReconfigurationWithSync__t304_ms2000 :
tac->T304_k = 2000;
break;
case NR_ReconfigurationWithSync__t304_ms10000 :
tac->T304_k = 10000;
break;
default :
AssertFatal(false, "Invalid T304 %ld\n", reconfigurationWithSync->t304);
}
}
}
void set_rlf_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t *sib1)
{
if(sib1 && sib1->ue_TimersAndConstants) {
switch (sib1->ue_TimersAndConstants->t301) {
case NR_UE_TimersAndConstants__t301_ms100 :
tac->T301_k = 100;
break;
case NR_UE_TimersAndConstants__t301_ms200 :
tac->T301_k = 200;
break;
case NR_UE_TimersAndConstants__t301_ms300 :
tac->T301_k = 300;
break;
case NR_UE_TimersAndConstants__t301_ms400 :
tac->T301_k = 400;
break;
case NR_UE_TimersAndConstants__t301_ms600 :
tac->T301_k = 600;
break;
case NR_UE_TimersAndConstants__t301_ms1000 :
tac->T301_k = 1000;
break;
case NR_UE_TimersAndConstants__t301_ms1500 :
tac->T301_k = 1500;
break;
case NR_UE_TimersAndConstants__t301_ms2000 :
tac->T301_k = 2000;
break;
default :
AssertFatal(false, "Invalid T301 %ld\n", sib1->ue_TimersAndConstants->t301);
}
switch (sib1->ue_TimersAndConstants->t310) {
case NR_UE_TimersAndConstants__t310_ms0 :
tac->T310_k = 0;
break;
case NR_UE_TimersAndConstants__t310_ms50 :
tac->T310_k = 50;
break;
case NR_UE_TimersAndConstants__t310_ms100 :
tac->T310_k = 100;
break;
case NR_UE_TimersAndConstants__t310_ms200 :
tac->T310_k = 200;
break;
case NR_UE_TimersAndConstants__t310_ms500 :
tac->T310_k = 500;
break;
case NR_UE_TimersAndConstants__t310_ms1000 :
tac->T310_k = 1000;
break;
case NR_UE_TimersAndConstants__t310_ms2000 :
tac->T310_k = 2000;
break;
default :
AssertFatal(false, "Invalid T310 %ld\n", sib1->ue_TimersAndConstants->t310);
}
switch (sib1->ue_TimersAndConstants->t311) {
case NR_UE_TimersAndConstants__t311_ms1000 :
tac->T311_k = 1000;
break;
case NR_UE_TimersAndConstants__t311_ms3000 :
tac->T311_k = 3000;
break;
case NR_UE_TimersAndConstants__t311_ms5000 :
tac->T311_k = 5000;
break;
case NR_UE_TimersAndConstants__t311_ms10000 :
tac->T311_k = 10000;
break;
case NR_UE_TimersAndConstants__t311_ms15000 :
tac->T311_k = 15000;
break;
case NR_UE_TimersAndConstants__t311_ms20000 :
tac->T311_k = 20000;
break;
case NR_UE_TimersAndConstants__t311_ms30000 :
tac->T311_k = 30000;
break;
default :
AssertFatal(false, "Invalid T311 %ld\n", sib1->ue_TimersAndConstants->t311);
}
switch (sib1->ue_TimersAndConstants->n310) {
case NR_UE_TimersAndConstants__n310_n1 :
tac->N310_k = 1;
break;
case NR_UE_TimersAndConstants__n310_n2 :
tac->N310_k = 2;
break;
case NR_UE_TimersAndConstants__n310_n3 :
tac->N310_k = 3;
break;
case NR_UE_TimersAndConstants__n310_n4 :
tac->N310_k = 4;
break;
case NR_UE_TimersAndConstants__n310_n6 :
tac->N310_k = 6;
break;
case NR_UE_TimersAndConstants__n310_n8 :
tac->N310_k = 8;
break;
case NR_UE_TimersAndConstants__n310_n10 :
tac->N310_k = 10;
break;
case NR_UE_TimersAndConstants__n310_n20 :
tac->N310_k = 20;
break;
default :
AssertFatal(false, "Invalid N310 %ld\n", sib1->ue_TimersAndConstants->n310);
}
switch (sib1->ue_TimersAndConstants->n311) {
case NR_UE_TimersAndConstants__n311_n1 :
tac->N311_k = 1;
break;
case NR_UE_TimersAndConstants__n311_n2 :
tac->N311_k = 2;
break;
case NR_UE_TimersAndConstants__n311_n3 :
tac->N311_k = 3;
break;
case NR_UE_TimersAndConstants__n311_n4 :
tac->N311_k = 4;
break;
case NR_UE_TimersAndConstants__n311_n5 :
tac->N311_k = 5;
break;
case NR_UE_TimersAndConstants__n311_n6 :
tac->N311_k = 6;
break;
case NR_UE_TimersAndConstants__n311_n8 :
tac->N311_k = 8;
break;
case NR_UE_TimersAndConstants__n311_n10 :
tac->N311_k = 10;
break;
default :
AssertFatal(false, "Invalid N311 %ld\n", sib1->ue_TimersAndConstants->n311);
}
}
else
LOG_E(NR_RRC,"SIB1 should not be NULL and neither UE_Timers_Constants\n");
}
void nr_rrc_set_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t *sib1)
{
set_rlf_sib1_timers_and_constants(tac, sib1);
if(sib1 && sib1->ue_TimersAndConstants) {
switch (sib1->ue_TimersAndConstants->t300) {
case NR_UE_TimersAndConstants__t300_ms100 :
tac->T300_k = 100;
break;
case NR_UE_TimersAndConstants__t300_ms200 :
tac->T300_k = 200;
break;
case NR_UE_TimersAndConstants__t300_ms300 :
tac->T300_k = 300;
break;
case NR_UE_TimersAndConstants__t300_ms400 :
tac->T300_k = 400;
break;
case NR_UE_TimersAndConstants__t300_ms600 :
tac->T300_k = 600;
break;
case NR_UE_TimersAndConstants__t300_ms1000 :
tac->T300_k = 1000;
break;
case NR_UE_TimersAndConstants__t300_ms1500 :
tac->T300_k = 1500;
break;
case NR_UE_TimersAndConstants__t300_ms2000 :
tac->T300_k = 2000;
break;
default :
AssertFatal(false, "Invalid T300 %ld\n", sib1->ue_TimersAndConstants->t300);
}
switch (sib1->ue_TimersAndConstants->t319) {
case NR_UE_TimersAndConstants__t319_ms100 :
tac->T319_k = 100;
break;
case NR_UE_TimersAndConstants__t319_ms200 :
tac->T319_k = 200;
break;
case NR_UE_TimersAndConstants__t319_ms300 :
tac->T319_k = 300;
break;
case NR_UE_TimersAndConstants__t319_ms400 :
tac->T319_k = 400;
break;
case NR_UE_TimersAndConstants__t319_ms600 :
tac->T319_k = 600;
break;
case NR_UE_TimersAndConstants__t319_ms1000 :
tac->T319_k = 1000;
break;
case NR_UE_TimersAndConstants__t319_ms1500 :
tac->T319_k = 1500;
break;
case NR_UE_TimersAndConstants__t319_ms2000 :
tac->T319_k = 2000;
break;
default :
AssertFatal(false, "Invalid T319 %ld\n", sib1->ue_TimersAndConstants->t319);
}
}
else
LOG_E(NR_RRC,"SIB1 should not be NULL and neither UE_Timers_Constants\n");
}
void nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(NR_UE_RRC_INST_t *rrc,
struct NR_SetupRelease_RLF_TimersAndConstants *rlf_TimersAndConstants)
{
if(rlf_TimersAndConstants == NULL)
return;
NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants;
NR_RLF_TimersAndConstants_t *rlf_tac = NULL;
switch(rlf_TimersAndConstants->present){
case NR_SetupRelease_RLF_TimersAndConstants_PR_release :
// use values for timers T301, T310, T311 and constants N310, N311, as included in ue-TimersAndConstants received in SIB1
set_rlf_sib1_timers_and_constants(tac, rrc->SInfo[0].sib1);
break;
case NR_SetupRelease_RLF_TimersAndConstants_PR_setup :
rlf_tac = rlf_TimersAndConstants->choice.setup;
if (rlf_tac == NULL)
return;
// (re-)configure the value of timers and constants in accordance with received rlf-TimersAndConstants
switch (rlf_tac->t310) {
case NR_RLF_TimersAndConstants__t310_ms0 :
tac->T310_k = 0;
break;
case NR_RLF_TimersAndConstants__t310_ms50 :
tac->T310_k = 50;
break;
case NR_RLF_TimersAndConstants__t310_ms100 :
tac->T310_k = 100;
break;
case NR_RLF_TimersAndConstants__t310_ms200 :
tac->T310_k = 200;
break;
case NR_RLF_TimersAndConstants__t310_ms500 :
tac->T310_k = 500;
break;
case NR_RLF_TimersAndConstants__t310_ms1000 :
tac->T310_k = 1000;
break;
case NR_RLF_TimersAndConstants__t310_ms2000 :
tac->T310_k = 2000;
break;
case NR_RLF_TimersAndConstants__t310_ms4000 :
tac->T310_k = 4000;
break;
case NR_RLF_TimersAndConstants__t310_ms6000 :
tac->T310_k = 6000;
break;
default :
AssertFatal(false, "Invalid T310 %ld\n", rlf_tac->t310);
}
switch (rlf_tac->n310) {
case NR_RLF_TimersAndConstants__n310_n1 :
tac->N310_k = 1;
break;
case NR_RLF_TimersAndConstants__n310_n2 :
tac->N310_k = 2;
break;
case NR_RLF_TimersAndConstants__n310_n3 :
tac->N310_k = 3;
break;
case NR_RLF_TimersAndConstants__n310_n4 :
tac->N310_k = 4;
break;
case NR_RLF_TimersAndConstants__n310_n6 :
tac->N310_k = 6;
break;
case NR_RLF_TimersAndConstants__n310_n8 :
tac->N310_k = 8;
break;
case NR_RLF_TimersAndConstants__n310_n10 :
tac->N310_k = 10;
break;
case NR_RLF_TimersAndConstants__n310_n20 :
tac->N310_k = 20;
break;
default :
AssertFatal(false, "Invalid N310 %ld\n", rlf_tac->n310);
}
switch (rlf_tac->n311) {
case NR_RLF_TimersAndConstants__n311_n1 :
tac->N311_k = 1;
break;
case NR_RLF_TimersAndConstants__n311_n2 :
tac->N311_k = 2;
break;
case NR_RLF_TimersAndConstants__n311_n3 :
tac->N311_k = 3;
break;
case NR_RLF_TimersAndConstants__n311_n4 :
tac->N311_k = 4;
break;
case NR_RLF_TimersAndConstants__n311_n5 :
tac->N311_k = 5;
break;
case NR_RLF_TimersAndConstants__n311_n6 :
tac->N311_k = 6;
break;
case NR_RLF_TimersAndConstants__n311_n8 :
tac->N311_k = 8;
break;
case NR_RLF_TimersAndConstants__n311_n10 :
tac->N311_k = 10;
break;
default :
AssertFatal(false, "Invalid N311 %ld\n", rlf_tac->n311);
}
if (rlf_tac->ext1) {
switch (rlf_tac->ext1->t311) {
case NR_RLF_TimersAndConstants__ext1__t311_ms1000 :
tac->T311_k = 1000;
break;
case NR_RLF_TimersAndConstants__ext1__t311_ms3000 :
tac->T311_k = 3000;
break;
case NR_RLF_TimersAndConstants__ext1__t311_ms5000 :
tac->T311_k = 5000;
break;
case NR_RLF_TimersAndConstants__ext1__t311_ms10000 :
tac->T311_k = 10000;
break;
case NR_RLF_TimersAndConstants__ext1__t311_ms15000 :
tac->T311_k = 15000;
break;
case NR_RLF_TimersAndConstants__ext1__t311_ms20000 :
tac->T311_k = 20000;
break;
case NR_RLF_TimersAndConstants__ext1__t311_ms30000 :
tac->T311_k = 30000;
break;
default :
AssertFatal(false, "Invalid T311 %ld\n", rlf_tac->ext1->t311);
}
}
reset_rlf_timers_and_constants(tac);
break;
default :
AssertFatal(false, "Invalid rlf_TimersAndConstants\n");
}
}
void set_default_timers_and_constants(NR_UE_Timers_Constants_t *tac)
{
// 38.331 9.2.3 Default values timers and constants
tac->T310_k = 1000;
tac->N310_k = 1;
tac->T311_k = 30000;
tac->N311_k = 1;
}
void reset_rlf_timers_and_constants(NR_UE_Timers_Constants_t *tac)
{
// stop timer T310 for this cell group, if running
tac->T310_active = false;
tac->T310_cnt = 0;
// reset the counters N310 and N311
tac->N310_cnt = 0;
tac->N311_cnt = 0;
}
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