diff --git a/doc/SW-archi-graph.md b/doc/SW-archi-graph.md index 8f8a6f6e5c..d397d07f43 100644 --- a/doc/SW-archi-graph.md +++ b/doc/SW-archi-graph.md @@ -31,7 +31,6 @@ rx_func_implem[rx_func] --> handle_nr_ulsch subgraph gNB_dlsch_ulsch_scheduler run_pdcp - --> nr_rrc_trigger --> schedule_xxxx end handle_nr_ulsch --> gNB_dlsch_ulsch_scheduler diff --git a/openair2/COMMON/f1ap_messages_def.h b/openair2/COMMON/f1ap_messages_def.h index 5db598409f..7b991e5918 100644 --- a/openair2/COMMON/f1ap_messages_def.h +++ b/openair2/COMMON/f1ap_messages_def.h @@ -39,6 +39,7 @@ MESSAGE_DEF(F1AP_UL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_ul_r //MESSAGE_DEF(F1AP_INITIAL_CONTEXT_SETUP_FAILURE, MESSAGE_PRIORITY_MED, f1ap_initial_context_setup_failure_t, f1ap_initial_context_setup_failure) MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_release_req_t, f1ap_ue_context_release_req) MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_CMD, MESSAGE_PRIORITY_MED, f1ap_ue_context_release_cmd_t, f1ap_ue_context_release_cmd) +MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_COMPLETE, MESSAGE_PRIORITY_MED, f1ap_ue_context_release_complete_t, f1ap_ue_context_release_complete) /* RRC -> F1AP messages */ MESSAGE_DEF(F1AP_DL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_dl_rrc_message_t , f1ap_dl_rrc_message ) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 9d507df8f3..9bdf7f0330 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -41,14 +41,14 @@ #define F1AP_UL_RRC_MESSAGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ul_rrc_message #define F1AP_UE_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_setup_req #define F1AP_UE_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_setup_resp -#define F1AP_UE_CONTEXT_RELEASE_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_resp #define F1AP_UE_CONTEXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_req #define F1AP_UE_CONTEXT_MODIFICATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_resp #define F1AP_UE_CONTEXT_MODIFICATION_FAIL(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_fail #define F1AP_DL_RRC_MESSAGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_dl_rrc_message #define F1AP_UE_CONTEXT_RELEASE_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_req -#define F1AP_UE_CONTEXT_RELEASE_CMD(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_req +#define F1AP_UE_CONTEXT_RELEASE_CMD(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_cmd +#define F1AP_UE_CONTEXT_RELEASE_COMPLETE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_complete #define F1AP_PAGING_IND(mSGpTR) (mSGpTR)->ittiMsg.f1ap_paging_ind @@ -425,8 +425,8 @@ typedef struct f1ap_ue_context_release_s { long cause_value; uint8_t *rrc_container; int rrc_container_length; -} f1ap_ue_context_release_req_t, f1ap_ue_context_release_cmd_t, - f1ap_ue_context_release_cplt_t; + int srb_id; +} f1ap_ue_context_release_req_t, f1ap_ue_context_release_cmd_t, f1ap_ue_context_release_complete_t; typedef struct f1ap_paging_ind_s { uint16_t ueidentityindexvalue; diff --git a/openair2/F1AP/f1ap_common.c b/openair2/F1AP/f1ap_common.c index 9bafbdf2d9..862e701b6d 100644 --- a/openair2/F1AP/f1ap_common.c +++ b/openair2/F1AP/f1ap_common.c @@ -180,7 +180,7 @@ int f1ap_du_add_cu_ue_id(instance_t instanceP, return -1; f1_inst->f1ap_ue[f1ap_uid].cu_ue_f1ap_id = cu_ue_f1ap_id; - LOG_I(F1AP, "Adding cu_ue_f1ap_id %ld for UE with RNTI %x\n", cu_ue_f1ap_id, f1_inst->f1ap_ue[f1ap_uid].rnti); + LOG_D(F1AP, "Adding cu_ue_f1ap_id %ld for UE with RNTI %x\n", cu_ue_f1ap_id, f1_inst->f1ap_ue[f1ap_uid].rnti); return 0; } diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index bfa48a4f88..383f02f20a 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -776,10 +776,10 @@ int CU_handle_UE_CONTEXT_SETUP_FAILURE(instance_t instance, AssertFatal(1==0,"Not implemented yet\n"); } -int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - F1AP_F1AP_PDU_t *pdu) { +int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) +{ + MessageDef *msg = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_UE_CONTEXT_RELEASE_REQ); + f1ap_ue_context_release_req_t *req = &F1AP_UE_CONTEXT_RELEASE_REQ(msg); F1AP_UEContextReleaseRequest_t *container; F1AP_UEContextReleaseRequestIEs_t *ie; DevAssert(pdu); @@ -789,6 +789,8 @@ int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); const rnti_t rnti = f1ap_get_rnti_by_cu_id(true, instance, ie->value.choice.GNB_CU_UE_F1AP_ID); + req->rnti = rnti; + /* GNB_DU_UE_F1AP_ID */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); @@ -796,35 +798,42 @@ int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, ie->value.choice.GNB_DU_UE_F1AP_ID); AssertFatal(rnti == rnti2, "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n", rnti2, rnti); + /* Cause */ - /* We don't care for the moment F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container, F1AP_ProtocolIE_ID_id_Cause, true); switch(ie->value.choice.Cause.present) { case F1AP_Cause_PR_radioNetwork: - //ie->value.choice.Cause.choice.radioNetwork + req->cause = F1AP_CAUSE_RADIO_NETWORK; + req->cause_value = ie->value.choice.Cause.choice.radioNetwork; break; case F1AP_Cause_PR_transport: - //ie->value.choice.Cause.choice.transport + req->cause = F1AP_CAUSE_TRANSPORT; + req->cause_value = ie->value.choice.Cause.choice.transport; break; case F1AP_Cause_PR_protocol: - //ie->value.choice.Cause.choice.protocol + req->cause = F1AP_CAUSE_PROTOCOL; + req->cause_value = ie->value.choice.Cause.choice.protocol; break; case F1AP_Cause_PR_misc: - //ie->value.choice.Cause.choice.misc + req->cause = F1AP_CAUSE_MISC; + req->cause_value = ie->value.choice.Cause.choice.misc; break; case F1AP_Cause_PR_NOTHING: default: + req->cause = F1AP_CAUSE_NOTHING; break; } - */ - LOG_I(F1AP, "Received UE CONTEXT RELEASE REQUEST: Trigger RRC for RNTI %x\n", rnti); - if (f1ap_req(true, instance)->cell_type==CELL_MACRO_GNB) { - AssertFatal(false,"must be devlopped\n"); - } + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container, F1AP_ProtocolIE_ID_id_targetCellsToCancel, false); + if (ie != NULL) { + LOG_W(F1AP, "ignoring list of target cells to cancel in UE Context Release Request: implementation missing\n"); + } + + itti_send_msg_to_task(TASK_RRC_GNB, instance, msg); + return 0; } @@ -900,6 +909,13 @@ int CU_send_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, ie4->value.present = F1AP_UEContextReleaseCommandIEs__value_PR_RRCContainer; OCTET_STRING_fromBuf(&ie4->value.choice.RRCContainer, (const char *)cmd->rrc_container, cmd->rrc_container_length); + + // conditionally have SRBID if RRC Container + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseCommandIEs_t, ie5); + ie5->id = F1AP_ProtocolIE_ID_id_SRBID; + ie5->criticality = F1AP_Criticality_ignore; + ie5->value.present = F1AP_UEContextReleaseCommandIEs__value_PR_SRBID; + ie5->value.choice.SRBID = cmd->srb_id; } /* encode */ diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index 8717382dfc..098f957194 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -165,6 +165,10 @@ void *F1AP_DU_task(void *arg) { &F1AP_UE_CONTEXT_RELEASE_REQ(msg)); break; + case F1AP_UE_CONTEXT_RELEASE_COMPLETE: + DU_send_UE_CONTEXT_RELEASE_COMPLETE(myInstance, &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg)); + break; + case TERMINATE_MESSAGE: LOG_W(F1AP, " *** Exiting F1AP thread\n"); itti_exit_task(); diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index 4c119dd8ad..dfec14e1e3 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -98,8 +98,6 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, if(f1ap_ue_context_setup_req->rnti<0) LOG_E(F1AP, "Could not retrieve UE rnti based on the CU/DU UE id \n"); - else - LOG_I(F1AP, "Retrieved rnti is: %d \n", f1ap_ue_context_setup_req->rnti); /* SpCell_ID */ F1AP_UEContextSetupRequestIEs_t *ieNet; @@ -649,18 +647,13 @@ int DU_send_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, return 0; } -int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - F1AP_F1AP_PDU_t *pdu) { +int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) +{ F1AP_UEContextReleaseCommand_t *container; F1AP_UEContextReleaseCommandIEs_t *ie; - /* ITTI message to NR-RRC for the case of gNB-DU */ - MessageDef *msg_p; // message to NR-RRC - msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_RELEASE_CMD); - f1ap_ue_context_release_req_t *f1ap_ue_context_release_cmd = &F1AP_UE_CONTEXT_RELEASE_CMD(msg_p); - + f1ap_ue_context_release_req_t ue_context_release = {0}; + f1ap_ue_context_release_req_t *f1ap_ue_context_release_cmd = &ue_context_release; DevAssert(pdu); container = &pdu->choice.initiatingMessage->value.choice.UEContextReleaseCommand; @@ -680,26 +673,30 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, F1AP_ProtocolIE_ID_id_RRCContainer, false); - f1ap_ue_context_release_cmd->rrc_container = malloc(ie->value.choice.RRCContainer.size); - memcpy(f1ap_ue_context_release_cmd->rrc_container, ie->value.choice.RRCContainer.buf, ie->value.choice.RRCContainer.size); + if (ie != NULL) { + f1ap_ue_context_release_cmd->rrc_container = malloc(ie->value.choice.RRCContainer.size); + AssertFatal(f1ap_ue_context_release_cmd->rrc_container != NULL, "out of memory\n"); + memcpy(f1ap_ue_context_release_cmd->rrc_container, ie->value.choice.RRCContainer.buf, ie->value.choice.RRCContainer.size); + f1ap_ue_context_release_cmd->rrc_container_length = ie->value.choice.RRCContainer.size; + + // conditionally have SRB ID if there is RRC container + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, F1AP_ProtocolIE_ID_id_SRBID, true); + f1ap_ue_context_release_cmd->srb_id = ie->value.choice.SRBID; + } F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, F1AP_ProtocolIE_ID_id_Cause, true); switch (ie->value.choice.Cause.present){ case F1AP_Cause_PR_radioNetwork: - LOG_W (F1AP, "UE context release command cause is due to radioNetwork with specific code: %ld\n",ie->value.choice.Cause.choice.radioNetwork); f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_RADIO_NETWORK; break; case F1AP_Cause_PR_transport: - LOG_W (F1AP, "UE context release command cause is due to transport with specific code: %ld\n",ie->value.choice.Cause.choice.transport); f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_TRANSPORT; break; case F1AP_Cause_PR_protocol: - LOG_W (F1AP, "UE context release command cause is due to protocol with specific code: %ld\n",ie->value.choice.Cause.choice.protocol); f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_PROTOCOL; break; case F1AP_Cause_PR_misc: - LOG_W (F1AP, "UE context release command cause is misc with specific code: %ld \n",ie->value.choice.Cause.choice.misc); f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_MISC; break; default: @@ -707,12 +704,13 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, break; } - itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p); + + ue_context_release_command(f1ap_ue_context_release_cmd); return 0; } -int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, - f1ap_ue_context_release_cplt_t *cplt) { +int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_ue_context_release_complete_t *complete) +{ F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextReleaseComplete_t *out; /* Create */ @@ -729,14 +727,14 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_UEContextReleaseCompleteIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(DUtype, instance, cplt->rnti); + ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(DUtype, instance, complete->rnti); /* mandatory */ /* c2. GNB_DU_UE_F1AP_ID */ asn1cSequenceAdd(out->protocolIEs.list,F1AP_UEContextReleaseCompleteIEs_t, ie2); ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_UEContextReleaseCompleteIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, cplt->rnti); + ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, complete->rnti); /* optional -> currently not used */ /* c3. CriticalityDiagnostics */ //if (0) { @@ -798,7 +796,7 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, buffer, len, getCxt(false, instance)->default_sctp_stream_id); - f1ap_remove_ue(DUtype, instance, cplt->rnti); + f1ap_remove_ue(DUtype, instance, complete->rnti); return 0; } diff --git a/openair2/F1AP/f1ap_du_ue_context_management.h b/openair2/F1AP/f1ap_du_ue_context_management.h index acf74f69d7..c834b3d84d 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.h +++ b/openair2/F1AP/f1ap_du_ue_context_management.h @@ -63,9 +63,7 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, /* * UE Context Release Complete (gNB-DU initiated) */ -int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, - f1ap_ue_context_release_cplt_t *cplt); - +int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_ue_context_release_complete_t *complete); /* * UE Context Modification (gNB-CU initiated) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 9f80475666..ccb630f63d 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -271,17 +271,6 @@ bool set_ul_ptrs_values(NR_PTRS_UplinkConfig_t *ul_ptrs_config, @returns transformPrecoding value */ long get_transformPrecoding(const NR_UE_UL_BWP_t *current_UL_BWP, nr_dci_format_t dci_format, uint8_t configuredGrant); -void nr_mac_gNB_rrc_ul_failure(const module_id_t Mod_instP, - const int CC_idP, - const frame_t frameP, - const sub_frame_t subframeP, - const rnti_t rntiP); - -void nr_mac_gNB_rrc_ul_failure_reset(const module_id_t Mod_instP, - const frame_t frameP, - const sub_frame_t subframeP, - const rnti_t rntiP); - uint8_t number_of_bits_set(uint8_t buf); void compute_rsrp_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 2d4cd16eb4..d5e3cf30d4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -40,7 +40,7 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" -#include "RRC/NR/nr_rrc_extern.h" +#include "openair2/X2AP/x2ap_eNB.h" #include "nr_pdcp/nr_pdcp_oai_api.h" @@ -174,7 +174,8 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_ void nr_pdcp_tick(int frame, int subframe); nr_rlc_tick(frame, slot >> *scc->ssbSubcarrierSpacing); nr_pdcp_tick(frame, slot >> *scc->ssbSubcarrierSpacing); - nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing); + if (is_x2ap_enabled()) + x2ap_trigger(); } for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index fb78ff0d13..0b5e261c5b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1796,8 +1796,7 @@ static void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, configure_UE_BWP(nr_mac, scc, sched_ctrl, NULL, UE, 0, 0); // Reset uplink failure flags/counters/timers at MAC so gNB will resume again scheduling resources for this UE - sched_ctrl->pusch_consecutive_dtx_cnt = 0; - sched_ctrl->ul_failure = 0; + nr_mac_reset_ul_failure(sched_ctrl); } static void nr_generate_Msg4(module_id_t module_idP, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 4d3d59c12e..3f1ea001b3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -577,7 +577,7 @@ static void pf_dl(module_id_t module_id, NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_DL_BWP_t *current_BWP = &UE->current_DL_BWP; - if (sched_ctrl->ul_failure==1) + if (sched_ctrl->ul_failure) continue; const NR_mac_dir_stats_t *stats = &UE->mac_stats.dl; @@ -898,7 +898,8 @@ void nr_schedule_ue_spec(module_id_t module_id, NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_DL_BWP_t *current_BWP = &UE->current_DL_BWP; - if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue; + if (sched_ctrl->ul_failure && !get_softmodem_params()->phy_test) + continue; NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; UE->mac_stats.dl.current_bytes = 0; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 33bd6831d1..e9a985b670 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2785,6 +2785,19 @@ void nr_mac_update_timers(module_id_t module_id, NR_UEs_t *UE_info = &RC.nrmac[module_id]->UE_info; UE_iterator(UE_info->list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + + if (nr_mac_check_release(sched_ctrl, UE->rnti)) { + nr_rlc_remove_ue(UE->rnti); + mac_remove_nr_ue(RC.nrmac[module_id], UE->rnti); + // go back to examine the next UE, which is at the position the + // current UE was + UE--; + continue; + } + + /* check if UL failure and trigger release request if necessary */ + nr_mac_check_ul_failure(RC.nrmac[module_id], UE->rnti, sched_ctrl); + if (sched_ctrl->rrc_processing_timer > 0) { sched_ctrl->rrc_processing_timer--; if (sched_ctrl->rrc_processing_timer == 0) { @@ -2946,3 +2959,53 @@ void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) DevAssert(bearer->servedRadioBearer->choice.srb_Identity == 1); nr_rlc_add_srb(UE->rnti, DCCH, bearer); } + +void nr_mac_trigger_release_timer(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing) +{ + // trigger 60ms + sched_ctrl->release_timer = 60 << subcarrier_spacing; +} + +bool nr_mac_check_release(NR_UE_sched_ctrl_t *sched_ctrl, int rnti) +{ + if (sched_ctrl->release_timer == 0) + return false; + sched_ctrl->release_timer--; + return sched_ctrl->release_timer == 0; +} + +void nr_mac_trigger_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing) +{ + if (sched_ctrl->ul_failure) { + /* already running */ + return; + } + sched_ctrl->ul_failure = true; + // 30 seconds till triggering release request + sched_ctrl->ul_failure_timer = 30000 << subcarrier_spacing; +} + +void nr_mac_reset_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl) +{ + sched_ctrl->ul_failure = false; + sched_ctrl->ul_failure_timer = 0; + sched_ctrl->pusch_consecutive_dtx_cnt = 0; +} + +void nr_mac_check_ul_failure(const gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ctrl_t *sched_ctrl) +{ + if (!sched_ctrl->ul_failure) + return; + if (sched_ctrl->ul_failure_timer > 0) + sched_ctrl->ul_failure_timer--; + /* to trigger only once: trigger when ul_failure_timer == 1, but timer will + * stop at 0 and we wait for a UE release command from upper layers */ + if (sched_ctrl->ul_failure_timer == 1) { + f1ap_ue_context_release_complete_t complete = { + .rnti = rnti, + .cause = F1AP_CAUSE_RADIO_NETWORK, + .cause_value = 12, // F1AP_CauseRadioNetwork_rl_failure_others + }; + nrmac->mac_rrc.ue_context_release_request(&complete); + } +} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c index 3309e1af34..c384691e87 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c @@ -260,8 +260,7 @@ void nr_schedule_srs(int module_id, frame_t frame, int slot) sched_ctrl->sched_srs.srs_scheduled = false; } - if((sched_ctrl->ul_failure == 1 && get_softmodem_params()->phy_test==0) || - sched_ctrl->rrc_processing_timer > 0) { + if ((sched_ctrl->ul_failure && !get_softmodem_params()->phy_test) || sched_ctrl->rrc_processing_timer > 0) { continue; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index e1716458d2..e09f684d25 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -209,7 +209,7 @@ void nr_csi_meas_reporting(int Mod_idP, NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs]; - if ((sched_ctrl->rrc_processing_timer > 0) || (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0)) { + if ((sched_ctrl->rrc_processing_timer > 0) || (sched_ctrl->ul_failure && !get_softmodem_params()->phy_test)) { continue; } const NR_CSI_MeasConfig_t *csi_measconfig = ul_bwp->csi_MeasConfig; @@ -1216,7 +1216,8 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot) NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs]; - if (sched_ctrl->ul_failure==1 || sched_ctrl->rrc_processing_timer>0) continue; + if (sched_ctrl->ul_failure || sched_ctrl->rrc_processing_timer > 0) + continue; NR_PUCCH_Config_t *pucch_Config = ul_bwp->pucch_Config; if (!pucch_Config || !pucch_Config->schedulingRequestResourceToAddModList) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 80c1652b61..e777fa5e0f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -671,9 +671,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, if (!get_softmodem_params()->phy_test && UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt >= pusch_failure_thres) { LOG_W(NR_MAC,"Detected UL Failure on PUSCH after %d PUSCH DTX, stopping scheduling\n", UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt); - UE->UE_sched_ctrl.ul_failure = 1; - - nr_mac_gNB_rrc_ul_failure(gnb_mod_idP,CC_idP,frameP,slotP,rntiP); + nr_mac_trigger_ul_failure(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs); } } } else if(sduP) { @@ -757,11 +755,9 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n", UE_msg3_stage->rnti, UE_scheduling_control->tpc0, UE_scheduling_control->ta_update); if (ra->cfra) { LOG_A(NR_MAC, "(rnti 0x%04x) CFRA procedure succeeded!\n", ra->rnti); - nr_mac_gNB_rrc_ul_failure_reset(gnb_mod_idP, frameP, slotP, ra->rnti); + nr_mac_reset_ul_failure(UE_scheduling_control); reset_dl_harq_list(UE_scheduling_control); reset_ul_harq_list(UE_scheduling_control); - UE_scheduling_control->pusch_consecutive_dtx_cnt = 0; - UE_scheduling_control->ul_failure = 0; UE_msg3_stage->ra_timer = 0; nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); process_CellGroup(ra->CellGroup, UE_scheduling_control); @@ -793,8 +789,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, return; } else { // The UE identified by C-RNTI still exists at the gNB - // Reset uplink failure flags/counters/timers at RRC - nr_mac_gNB_rrc_ul_failure_reset(gnb_mod_idP, frameP, slotP, ra->crnti); + nr_mac_reset_ul_failure(&UE_C->UE_sched_ctrl); // Reset HARQ processes reset_dl_harq_list(&UE_C->UE_sched_ctrl); @@ -1638,7 +1633,7 @@ static void pf_ul(module_id_t module_id, UE_iterator(UE_list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - if (UE->Msg4_ACKed != true || sched_ctrl->ul_failure == 1) + if (UE->Msg4_ACKed != true || sched_ctrl->ul_failure) continue; LOG_D(NR_MAC,"pf_ul: preparing UL scheduling for UE %04x\n",UE->rnti); @@ -2067,7 +2062,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; UE_iterator( UE_info->list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - if (sched_ctrl->ul_failure == 1 && get_softmodem_params()->phy_test==0) continue; + if (sched_ctrl->ul_failure && !get_softmodem_params()->phy_test) + continue; NR_CellGroupConfig_t *cg = UE->CellGroup; NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index c2cbe8799d..f01a47699a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -440,4 +440,11 @@ void send_initial_ul_rrc_message(gNB_MAC_INST *mac, int rnti, const uint8_t *sdu void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid); +void nr_mac_trigger_release_timer(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing); +bool nr_mac_check_release(NR_UE_sched_ctrl_t *sched_ctrl, int rnti); + +void nr_mac_trigger_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing); +void nr_mac_reset_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl); +void nr_mac_check_ul_failure(const gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ctrl_t *sched_ctrl); + #endif /*__LAYER2_NR_MAC_PROTO_H__*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index e9a01d98f7..6e444b9816 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -147,9 +147,36 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) free(resp.du_to_cu_rrc_information); } +void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd) +{ + /* mark UE as to be deleted after PUSCH failure */ + gNB_MAC_INST *mac = RC.nrmac[0]; + pthread_mutex_lock(&mac->sched_lock); + NR_UE_info_t *UE = find_nr_UE(&mac->UE_info, cmd->rnti); + if (UE->UE_sched_ctrl.ul_failure || cmd->rrc_container_length == 0) { + /* The UE is already not connected anymore or we have nothing to forward*/ + nr_rlc_remove_ue(cmd->rnti); + mac_remove_nr_ue(mac, cmd->rnti); + } else { + /* UE is in sync: forward release message and mark to be deleted + * after UL failure */ + nr_rlc_srb_recv_sdu(cmd->rnti, cmd->srb_id, cmd->rrc_container, cmd->rrc_container_length); + nr_mac_trigger_release_timer(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs); + } + pthread_mutex_unlock(&mac->sched_lock); + + f1ap_ue_context_release_complete_t complete = { + .rnti = cmd->rnti, + }; + mac->mac_rrc.ue_context_release_complete(&complete); + + if (cmd->rrc_container) + free(cmd->rrc_container); +} + int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) { - LOG_I(NR_MAC, "DL RRC Message Transfer with %d bytes for RNTI %04x SRB %d\n", dl_rrc->rrc_container_length, dl_rrc->rnti, dl_rrc->srb_id); + LOG_D(NR_MAC, "DL RRC Message Transfer with %d bytes for RNTI %04x SRB %d\n", dl_rrc->rrc_container_length, dl_rrc->rnti, dl_rrc->srb_id); nr_rlc_srb_recv_sdu(dl_rrc->rnti, dl_rrc->srb_id, dl_rrc->rrc_container, dl_rrc->rrc_container_length); return 0; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h index 25b51c2d84..5ad3794a27 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h @@ -26,6 +26,7 @@ #include "f1ap_messages_types.h" void ue_context_setup_request(const f1ap_ue_context_setup_t *req); +void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd); int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h index 53736a1695..0eb37a8148 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h @@ -26,6 +26,8 @@ #include "f1ap_messages_types.h" typedef void (*ue_context_setup_response_func_t)(const f1ap_ue_context_setup_t* req, const f1ap_ue_context_setup_t *resp); +typedef void (*ue_context_release_request_func_t)(const f1ap_ue_context_release_req_t* req); +typedef void (*ue_context_release_complete_func_t)(const f1ap_ue_context_release_complete_t *complete); typedef void (*initial_ul_rrc_message_transfer_func_t)(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c index eafa544185..e13991529c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c @@ -55,6 +55,22 @@ static void ue_context_setup_response_direct(const f1ap_ue_context_setup_t *req, itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); } +static void ue_context_release_request_direct(const f1ap_ue_context_release_req_t* req) +{ + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_REQ); + f1ap_ue_context_release_req_t *f1ap_msg = &F1AP_UE_CONTEXT_RELEASE_REQ(msg); + *f1ap_msg = *req; + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); +} + +static void ue_context_release_complete_direct(const f1ap_ue_context_release_complete_t *complete) +{ + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_COMPLETE); + f1ap_ue_context_release_complete_t *f1ap_msg = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg); + *f1ap_msg = *complete; + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); +} + static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE); @@ -78,5 +94,7 @@ static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const void mac_rrc_ul_direct_init(struct nr_mac_rrc_ul_if_s *mac_rrc) { mac_rrc->ue_context_setup_response = ue_context_setup_response_direct; + mac_rrc->ue_context_release_request = ue_context_release_request_direct; + mac_rrc->ue_context_release_complete = ue_context_release_complete_direct; mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_direct; } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c index c5bcb8814a..718a595e74 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c @@ -60,6 +60,24 @@ static void ue_context_setup_response_f1ap(const f1ap_ue_context_setup_t *req, c itti_send_msg_to_task(TASK_DU_F1, 0, msg); } +static void ue_context_release_request_f1ap(const f1ap_ue_context_release_req_t* req) +{ + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_REQ); + f1ap_ue_context_release_req_t *f1ap_msg = &F1AP_UE_CONTEXT_RELEASE_REQ(msg); + *f1ap_msg = *req; + itti_send_msg_to_task(TASK_DU_F1, 0, msg); +} + +static void ue_context_release_complete_f1ap(const f1ap_ue_context_release_complete_t *complete) +{ + newGtpuDeleteAllTunnels(0, complete->rnti); + + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_COMPLETE); + f1ap_ue_context_release_complete_t *f1ap_msg = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg); + *f1ap_msg = *complete; + itti_send_msg_to_task(TASK_DU_F1, 0, msg); +} + static void initial_ul_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE); @@ -83,6 +101,8 @@ static void initial_ul_rrc_message_transfer_f1ap(module_id_t module_id, const f1 void mac_rrc_ul_f1ap_init(struct nr_mac_rrc_ul_if_s *mac_rrc) { mac_rrc->ue_context_setup_response = ue_context_setup_response_f1ap; + mac_rrc->ue_context_release_request = ue_context_release_request_f1ap; + mac_rrc->ue_context_release_complete = ue_context_release_complete_f1ap; mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_f1ap; } diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 5f25713650..d9f3ed1188 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -591,7 +591,9 @@ typedef struct { uint8_t current_harq_pid; int pusch_consecutive_dtx_cnt; int pucch_consecutive_dtx_cnt; - int ul_failure; + bool ul_failure; + int ul_failure_timer; + int release_timer; struct CSI_Report CSI_report; bool SR; /// information about every HARQ process @@ -659,8 +661,9 @@ typedef struct NR_bler_options { } NR_bler_options_t; typedef struct nr_mac_rrc_ul_if_s { - /* TODO add other message types as necessary */ ue_context_setup_response_func_t ue_context_setup_response; + ue_context_release_request_func_t ue_context_release_request; + ue_context_release_complete_func_t ue_context_release_complete; initial_ul_rrc_message_transfer_func_t initial_ul_rrc_message_transfer; } nr_mac_rrc_ul_if_t; diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 0157a3596b..7a798d7b81 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -675,8 +675,7 @@ static void deliver_pdu_drb(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, req->offset = GTPU_HEADER_OVERHEAD_MAX; req->ue_id = ue_id; req->bearer_id = rb_id; - LOG_I(PDCP, "%s() (drb %d) sending message to gtp size %d\n", - __func__, rb_id, size); + LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size); extern instance_t CUuniqInstance; itti_send_msg_to_task(TASK_GTPV1_U, CUuniqInstance, message_p); } else { diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 4e9c077afa..74b08e7dfe 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -118,32 +118,3 @@ int8_t nr_mac_rrc_bwp_switch_req(const module_id_t module_idP, return 0; } - -void nr_mac_gNB_rrc_ul_failure(const module_id_t Mod_instP, - const int CC_idP, - const frame_t frameP, - const sub_frame_t subframeP, - const rnti_t rntiP) { - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[Mod_instP], rntiP); - - if (ue_context_p != NULL) { - LOG_D(RRC,"Frame %d, Subframe %d: UE %x UL failure, activating timer\n",frameP,subframeP,rntiP); - if(ue_context_p->ue_context.ul_failure_timer == 0) - ue_context_p->ue_context.ul_failure_timer=1; - } else { - LOG_D(RRC,"Frame %d, Subframe %d: UL failure: UE %x unknown \n",frameP,subframeP,rntiP); - } -} - -void nr_mac_gNB_rrc_ul_failure_reset(const module_id_t Mod_instP, - const frame_t frameP, - const sub_frame_t subframeP, - const rnti_t rntiP) { - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[Mod_instP], rntiP); - if (ue_context_p != NULL) { - LOG_W(RRC,"Frame %d, Subframe %d: UE %x UL failure reset, deactivating timer\n",frameP,subframeP,rntiP); - ue_context_p->ue_context.ul_failure_timer=0; - } else { - LOG_W(RRC,"Frame %d, Subframe %d: UL failure reset: UE %x unknown \n",frameP,subframeP,rntiP); - } -} diff --git a/openair2/RRC/NR/mac_rrc_dl.h b/openair2/RRC/NR/mac_rrc_dl.h index 49ffccd4a7..46c7fc85f8 100644 --- a/openair2/RRC/NR/mac_rrc_dl.h +++ b/openair2/RRC/NR/mac_rrc_dl.h @@ -26,6 +26,7 @@ #include "f1ap_messages_types.h" typedef void (*ue_context_setup_request_func_t)(const f1ap_ue_context_setup_t *req); +typedef void (*ue_context_release_command_func_t)(const f1ap_ue_context_release_cmd_t *cmd); typedef void (*dl_rrc_message_transfer_func_t)(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc); diff --git a/openair2/RRC/NR/mac_rrc_dl_direct.c b/openair2/RRC/NR/mac_rrc_dl_direct.c index be416d6921..b1ec661238 100644 --- a/openair2/RRC/NR/mac_rrc_dl_direct.c +++ b/openair2/RRC/NR/mac_rrc_dl_direct.c @@ -34,5 +34,6 @@ static void dl_rrc_message_transfer_direct(module_id_t module_id, const f1ap_dl_ void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc) { mac_rrc->ue_context_setup_request = ue_context_setup_request; + mac_rrc->ue_context_release_command = ue_context_release_command; mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_direct; } diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c index bfe19a161b..0af1c79bd2 100644 --- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -39,6 +39,14 @@ static void ue_context_setup_request_f1ap(const f1ap_ue_context_setup_t *req) itti_send_msg_to_task(TASK_CU_F1, 0, msg); } +static void ue_context_release_command_f1ap(const f1ap_ue_context_release_cmd_t *cmd) +{ + MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); + f1ap_ue_context_release_cmd_t *msg = &F1AP_UE_CONTEXT_RELEASE_CMD(message_p); + *msg = *cmd; + itti_send_msg_to_task (TASK_CU_F1, 0, message_p); +} + static void dl_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) { /* TODO call F1AP function directly? no real-time constraint here */ @@ -58,5 +66,6 @@ static void dl_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_dl_rr void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc) { mac_rrc->ue_context_setup_request = ue_context_setup_request_f1ap; + mac_rrc->ue_context_release_command = ue_context_release_command_f1ap; mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_f1ap; } diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 1b00c93b9d..8395175e0d 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -313,17 +313,6 @@ typedef struct gNB_RRC_UE_s { int nb_of_pdusessions; rrc_pdu_session_param_t pduSession[NGAP_MAX_PDU_SESSION]; rrc_action_t xids[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER]; - uint32_t ul_failure_timer; - uint32_t ue_release_timer; - uint32_t ue_release_timer_thres; - uint32_t ue_release_timer_s1; - uint32_t ue_release_timer_thres_s1; - uint32_t ue_release_timer_ng; - uint32_t ue_release_timer_thres_ng; - uint32_t ue_release_timer_rrc; - uint32_t ue_release_timer_thres_rrc; - uint32_t ue_reestablishment_timer; - uint32_t ue_reestablishment_timer_thres; uint8_t e_rab_release_command_flag; uint32_t ue_rrc_inactivity_timer; uint32_t ue_reestablishment_counter; @@ -389,8 +378,8 @@ typedef struct { } nr_security_configuration_t; typedef struct nr_mac_rrc_dl_if_s { - /* TODO add other message types as necessary */ ue_context_setup_request_func_t ue_context_setup_request; + ue_context_release_command_func_t ue_context_release_command; dl_rrc_message_transfer_func_t dl_rrc_message_transfer; } nr_mac_rrc_dl_if_t; diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 8cfc1e9132..384269748a 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -111,9 +111,6 @@ rrc_gNB_generate_RRCRelease( \param void *args_p Pointer on arguments to start the task. */ void *rrc_gnb_task(void *args_p); -/* Trigger RRC periodic processing. To be called once per ms. */ -void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe); - /**\ Function to set or overwrite PTRS DL RRC parameters. \ *bwp Pointer to dedicated RC config structure \ *ptrsNrb Pointer to K_ptrs N_RB related parameters diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index d39c3eac35..ff862b1c23 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -360,11 +360,6 @@ static void rrc_gNB_generate_RRCSetup(instance_t instance, size, "[MSG] RRC Setup\n"); - // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE - ue_context_pP->ue_context.ue_release_timer = 1; - // remove UE after 10 frames after RRCConnectionRelease is triggered - ue_context_pP->ue_context.ue_release_timer_thres = 1000; - nr_pdcp_add_srbs(true, rnti, ue_context_pP->ue_context.SRB_configList, 0, NULL, NULL); f1ap_dl_rrc_message_t dl_rrc = { @@ -415,20 +410,11 @@ static int rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t m nr_mac_config_sib1(RC.nrmac[rrc_instance_p->module_id], rrc_instance_p->carrier.siblock1); LOG_I(NR_RRC, " [RAPROC] rnti: %04x Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n", rnti, size); - // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE - ue_context_pP->ue_context.ue_release_timer = 1; - // remove UE after 10 frames after RRCConnectionRelease is triggered - ue_context_pP->ue_context.ue_release_timer_thres = 1000; // configure MAC protocol_ctxt_t ctxt = {0}; PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, 0, GNB_FLAG_YES, rnti, 0, 0); apply_macrlc_config(rrc_instance_p, ue_context_pP, &ctxt); - //nr_pdcp_add_srbs(ctxt_pP->enb_flag, ctxt_pP->rntiMaybeUEid, ue_context_pP->ue_context.SRB_configList, 0, NULL, NULL); - //apply_pdcp_config(ue_context_pP,ctxt_pP); - /* init timers */ - // ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0; - f1ap_dl_rrc_message_t dl_rrc = { .old_gNB_DU_ue_id = 0xFFFFFF, .rrc_container = buf, @@ -1047,8 +1033,6 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co // uint8_t nr_DRB2LCHAN[8]; gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - ue_p->ue_reestablishment_timer = 0; - /* Derive the keys from kgnb */ if (DRB_configList != NULL) { nr_derive_key(UP_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, kUPenc); @@ -1406,12 +1390,7 @@ void RRCReestablishmentComplete_update_ngu_tunnel(const protocol_ctxt_t *const c if (ret != 0) { LOG_E(NR_RRC, "RRC Reestablishment - gtpv1u_update_ngu_tunnel failed,start to release UE %x\n", reestablish_rnti); - ue_p->ue_release_timer_s1 = 1; - ue_p->ue_release_timer_thres_s1 = 100; - ue_p->ue_release_timer = 0; - ue_p->ue_reestablishment_timer = 0; - ue_p->ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ - ue_p->ul_failure_timer = 0; + AssertFatal(false, "not implemented\n"); return; } } @@ -1470,7 +1449,6 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); ue_p->xids[new_xid] = RRC_REESTABLISH_COMPLETE; ue_p->StatusRrc = NR_RRC_CONNECTED; - ue_p->ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED RRCReestablishmentComplete_fill_SRB2_configList(ctxt_pP, ue_context_pP, xid, new_xid); RRCReestablishmentComplete_fill_DRB_configList(ctxt_pP, ue_context_pP, new_xid); RRCReestablishmentComplete_update_ngu_tunnel(ctxt_pP, ue_context_pP, reestablish_rnti); @@ -1665,9 +1643,8 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint * the current one must be removed from MAC/PHY (zombie UE) */ if ((ue_context_p = rrc_gNB_ue_context_random_exist(gnb_rrc_inst, random_value))) { - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; LOG_W(NR_RRC, "new UE rnti (coming with random value) is already there, removing UE %x from MAC/PHY\n", rnti); - UE->ul_failure_timer = 20000; + AssertFatal(false, "not implemented\n"); } ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value); @@ -1693,16 +1670,12 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint // TODO: MAC structures should not be accessed directly from the RRC! An implementation using the F1 interface should be developed. if (!NODE_IS_CU(RC.nrrrc[0]->node_type)) { nr_rrc_mac_remove_ue(ue_context_p->ue_context.rnti); + } else { + AssertFatal(false, "not implemented: need to switch RNTI in MAC via DL RRC Message Transfer\n"); } /* replace rnti in the context */ UE->rnti = rnti; - /* reset timers */ - UE->ul_failure_timer = 0; - UE->ue_release_timer = 0; - UE->ue_reestablishment_timer = 0; - UE->ue_release_timer_s1 = 0; - UE->ue_release_timer_rrc = 0; } else { LOG_I(NR_RRC, "UE %04x 5G-S-TMSI-Part1 doesn't exist, setting ng_5G_S_TMSI_Part1 => %ld\n", rnti, s_tmsi_part1); @@ -1793,28 +1766,9 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint break; } - if (UE->ue_reestablishment_timer > 0) { - LOG_E(NR_RRC, "RRRCReconfigurationComplete(Previous) don't receive, delete the Previous UE,\nprevious Status %d, new Status NR_RRC_RECONFIGURED\n", UE->StatusRrc); - UE->StatusRrc = NR_RRC_RECONFIGURED; - protocol_ctxt_t ctxt_old_p; - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt_old_p, module_id, GNB_FLAG_YES, c_rnti, 0, 0); - rrc_gNB_process_RRCReconfigurationComplete(&ctxt_old_p, ue_context_p, xid); + /* TODO: start timer in ITTI and drop UE if it does not come back */ + (void) xid; /* xid currently not used */ - for (uint8_t pdusessionid = 0; pdusessionid < UE->nb_of_pdusessions; pdusessionid++) { - if (UE->pduSession[pdusessionid].status == PDU_SESSION_STATUS_DONE) { - UE->pduSession[pdusessionid].status = PDU_SESSION_STATUS_ESTABLISHED; - } else { - UE->pduSession[pdusessionid].status = PDU_SESSION_STATUS_FAILED; - } - } - } - - /* reset timers */ - UE->ul_failure_timer = 0; - UE->ue_release_timer = 0; - UE->ue_reestablishment_timer = 0; - // UE->ue_release_timer_s1 = 0; - UE->ue_release_timer_rrc = 0; // Insert C-RNTI to map for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &gnb_rrc_inst->nr_reestablish_rnti_map[i]; @@ -1942,11 +1896,6 @@ static int handle_rrcReestablishmentComplete(const protocol_ctxt_t *const ctxt_p nr_rrc_mac_remove_ue(reestablish_rnti); UE->ue_reestablishment_counter++; - - // UE->ue_release_timer = 0; - UE->ue_reestablishment_timer = 1; - // remove UE after 100 frames after NR_RRCReestablishmentRelease is triggered - UE->ue_reestablishment_timer_thres = 1000; return 0; } @@ -2104,8 +2053,6 @@ static int handle_rrcSetupComplete(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_process_RRCSetupComplete(ctxt_pP, ue_context_p, setup_complete->criticalExtensions.choice.rrcSetupComplete); LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT " UE State = NR_RRC_CONNECTED \n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - - UE->ue_release_timer = 0; return 0; } @@ -2205,9 +2152,9 @@ int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP, break; case NR_UL_DCCH_MessageType__c1_PR_ulInformationTransfer: - LOG_I(NR_RRC, "Recived RRC GNB UL Information Transfer \n"); + LOG_D(NR_RRC, "Recived RRC GNB UL Information Transfer \n"); if (!ue_context_p) { - LOG_I(NR_RRC, "Processing ulInformationTransfer UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid); + LOG_W(NR_RRC, "Processing ulInformationTransfer UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid); break; } @@ -2587,6 +2534,36 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance * messages (UE capability, to be specific) */ } +static void rrc_CU_process_ue_context_release_request(MessageDef *msg_p) +{ + const int instance = 0; + f1ap_ue_context_release_req_t *req = &F1AP_UE_CONTEXT_RELEASE_REQ(msg_p); + gNB_RRC_INST *rrc = RC.nrrrc[instance]; + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, req->rnti); + + /* TODO: marshall types correctly */ + LOG_I(NR_RRC, "received UE Context Release Request for UE %04x, forwarding to AMF\n", req->rnti); + rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(instance, + ue_context_p, + NGAP_CAUSE_RADIO_NETWORK, + NGAP_CAUSE_RADIO_NETWORK_RADIO_CONNECTION_WITH_UE_LOST); +} + +static void rrc_CU_process_ue_context_release_complete(MessageDef *msg_p) +{ + const int instance = 0; + f1ap_ue_context_release_complete_t *complete = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_p); + gNB_RRC_INST *rrc = RC.nrrrc[instance]; + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, complete->rnti); + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + + nr_pdcp_remove_UE(UE->rnti); + newGtpuDeleteAllTunnels(instance, UE->rnti); + rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance, UE->gNB_ue_ngap_id); + LOG_I(NR_RRC, "removed UE %04x \n", UE->rnti); + rrc_gNB_remove_ue_context(rrc, ue_context_p); +} + static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, instance_t instance) { f1ap_ue_context_setup_t *resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p); @@ -2817,90 +2794,6 @@ static int get_dl_mimo_layers(const gNB_RRC_INST *rrc, const NR_UE_NR_Capability return(1); } -void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { - - MessageDef *msg; - gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - rrc_gNB_ue_context_t *ue_context_p = NULL; - RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &rrc->rrc_ue_head) - { - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - ctxt_pP->rntiMaybeUEid = UE->rnti; - - if (UE->ul_failure_timer > 0) { - UE->ul_failure_timer++; - - if (UE->ul_failure_timer >= 20000) { - // remove UE after 20 seconds after MAC (or else) has indicated UL failure - LOG_I(RRC, "Removing UE %x instance, because of uplink failure timer timeout\n", UE->rnti); - if (UE->StatusRrc >= NR_RRC_CONNECTED) { - rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ( - ctxt_pP->module_id, - ue_context_p, - NGAP_CAUSE_RADIO_NETWORK, - NGAP_CAUSE_RADIO_NETWORK_RADIO_CONNECTION_WITH_UE_LOST); - } - - // Remove here the MAC and RRC context when RRC is not connected - if (UE->StatusRrc < NR_RRC_CONNECTED) { - if (!NODE_IS_CU(rrc->node_type)) { - nr_rrc_mac_remove_ue(ctxt_pP->rntiMaybeUEid); - rrc_rlc_remove_ue(ctxt_pP); - nr_pdcp_remove_UE(ctxt_pP->rntiMaybeUEid); - - /* remove RRC UE Context */ - ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, UE->rnti); - if (ue_context_p) { - LOG_I(NR_RRC, "remove UE %04x \n", UE->rnti); - rrc_gNB_remove_ue_context(rrc, ue_context_p); - break; // We must not access this UE context - } - } - // In case of CU trigger UE context release command towards the DU - else { - MessageDef *message_p; - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); - f1ap_ue_context_release_cmd_t *rel_cmd=&F1AP_UE_CONTEXT_RELEASE_CMD (message_p); - rel_cmd->rnti = UE->rnti; - rel_cmd->cause = F1AP_CAUSE_RADIO_NETWORK; - rel_cmd->cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release - itti_send_msg_to_task(TASK_CU_F1, ctxt_pP->module_id, message_p); - } - } - - break; // break RB_FOREACH - } - } - - if (UE->ue_release_timer_rrc > 0) { - UE->ue_release_timer_rrc++; - - if (UE->ue_release_timer_rrc >= UE->ue_release_timer_thres_rrc) { - LOG_I(NR_RRC, "Removing UE %x instance after UE_CONTEXT_RELEASE_Complete (ue_release_timer_rrc timeout)\n", UE->rnti); - UE->ue_release_timer_rrc = 0; - if (!NODE_IS_CU(RC.nrrrc[0]->node_type)) { - nr_rrc_mac_remove_ue(ctxt_pP->rntiMaybeUEid); - } - rrc_rlc_remove_ue(ctxt_pP); - nr_pdcp_remove_UE(ctxt_pP->rntiMaybeUEid); - newGtpuDeleteAllTunnels(ctxt_pP->instance, UE->rnti); - - /* remove RRC UE Context */ - LOG_I(NR_RRC, "remove UE %04x \n", UE->rnti); - - rrc_gNB_remove_ue_context(rrc, ue_context_p); - break; // break RB_FOREACH - } - } - } - - /* send a tick to x2ap */ - if (is_x2ap_enabled()){ - msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_SUBFRAME_PROCESS); - itti_send_msg_to_task(TASK_X2AP, ctxt_pP->module_id, msg); - } -} - int rrc_gNB_process_e1_setup_req(e1ap_setup_req_t *req, instance_t instance) { AssertFatal(req->supported_plmns <= PLMN_LIST_MAX_SIZE, "Supported PLMNs is more than PLMN_LIST_MAX_SIZE\n"); @@ -3031,9 +2924,9 @@ static void write_rrc_stats(const gNB_RRC_INST *rrc) fprintf(f, "NR RRC UE rnti %04x:", rnti); if (ue_ctxt->Initialue_identity_5g_s_TMSI.presence) - fprintf(f, " S-TMSI %x\n", ue_ctxt->Initialue_identity_5g_s_TMSI.fiveg_tmsi); + fprintf(f, " S-TMSI %x", ue_ctxt->Initialue_identity_5g_s_TMSI.fiveg_tmsi); - fprintf(f, " failure timer %d/8\n", ue_ctxt->ul_failure_timer); + fprintf(f, "\n"); if (ue_ctxt->UE_Capability_nr) { fprintf(f, @@ -3091,10 +2984,6 @@ void *rrc_gnb_task(void *args_p) { write_rrc_stats(RC.nrrrc[0]); break; - case RRC_SUBFRAME_PROCESS: - nr_rrc_subframe_process(&RRC_SUBFRAME_PROCESS(msg_p).ctxt, RRC_SUBFRAME_PROCESS(msg_p).CC_id); - break; - case F1AP_INITIAL_UL_RRC_MESSAGE: AssertFatal(NODE_IS_CU(RC.nrrrc[instance]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[instance]->node_type), "should not receive F1AP_INITIAL_UL_RRC_MESSAGE, need call by CU!\n"); @@ -3162,9 +3051,12 @@ void *rrc_gnb_task(void *args_p) { rrc_DU_process_ue_context_modification_request(msg_p, instance); break; - case F1AP_UE_CONTEXT_RELEASE_CMD: - LOG_W(NR_RRC, "Received F1AP_UE_CONTEXT_RELEASE_CMD for processing at the RRC layer of the DU. Processing function " - "implementation is pending\n"); + case F1AP_UE_CONTEXT_RELEASE_REQ: + rrc_CU_process_ue_context_release_request(msg_p); + break; + + case F1AP_UE_CONTEXT_RELEASE_COMPLETE: + rrc_CU_process_ue_context_release_complete(msg_p); break; /* Messages from X2AP */ @@ -3292,6 +3184,24 @@ rrc_gNB_generate_UECapabilityEnquiry( nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc); } +static void rrc_deliver_ue_ctxt_release_cmd(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id) +{ + DevAssert(deliver_pdu_data != NULL); + gNB_RRC_INST *rrc = deliver_pdu_data; + uint8_t *rrc_container = malloc(size); + AssertFatal(rrc_container != NULL, "out of memory\n"); + memcpy(rrc_container, buf, size); + f1ap_ue_context_release_cmd_t ue_context_release_cmd = { + .rnti = ue_id, /* TODO: proper IDs! */ + .cause = F1AP_CAUSE_RADIO_NETWORK, + .cause_value = 10, // 10 = F1AP_CauseRadioNetwork_normal_release + .srb_id = srb_id, + .rrc_container = rrc_container, + .rrc_container_length = size, + }; + rrc->mac_rrc.ue_context_release_command(&ue_context_release_cmd); +} + //----------------------------------------------------------------------------- /* * Generate the RRC Connection Release to UE. @@ -3306,49 +3216,16 @@ rrc_gNB_generate_RRCRelease( { uint8_t buffer[RRC_BUF_SIZE] = {0}; int size = do_NR_RRCRelease(buffer, RRC_BUF_SIZE, rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id)); - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - ue_p->ue_reestablishment_timer = 0; - ue_p->ue_release_timer = 0; - ue_p->ul_failure_timer = 0; - ue_p->ue_release_timer_rrc = 0; LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate RRCRelease (bytes %d)\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), size); - LOG_D(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (rrcRelease MUI %d) --->[PDCP][RB %u]\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - size, - rrc_gNB_mui, - DCCH); gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc); + nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_release_cmd, rrc); - rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(ctxt_pP->instance, ue_context_pP->ue_context.gNB_ue_ngap_id); - ue_context_pP->ue_context.ue_release_timer_rrc = 1; - /* TODO: 38.331 says for RRC Release that the UE should release everything - * after 60ms or if lower layers acked receipt of release. Hence, from the - * gNB POV, we can free the UE's RRC context as soon as we sent the msg. - * Currently, without the F1 interface, the ue_release timer expiration also - * triggers MAC, so we give it some time. If we send an F1 UE Context release - * message, we can free it immediately. The MAC should release it after these - * 60ms, or the ack of the DLSCH transmission. */ - ue_context_pP->ue_context.ue_release_timer_thres_rrc = 5; - LOG_I(RRC, "delaying UE %ld context removal by 5ms\n", ctxt_pP->rntiMaybeUEid); - - if (NODE_IS_CU(rrc->node_type)) { - uint8_t *message_buffer = itti_malloc (TASK_RRC_GNB, TASK_CU_F1, size); - memcpy (message_buffer, buffer, size); - MessageDef *m = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); - F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = ctxt_pP->rntiMaybeUEid; - F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK; - F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release - F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = message_buffer; - F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container_length = size; - itti_send_msg_to_task(TASK_CU_F1, ctxt_pP->module_id, m); - } + /* UE will be freed after UE context release complete */ } int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t instance, uint8_t CC_id){ @@ -3473,14 +3350,3 @@ int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t inst return 0; } - -void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe) -{ - MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_RRC_GNB, 0, RRC_SUBFRAME_PROCESS); - RRC_SUBFRAME_PROCESS(message_p).ctxt = *ctxt; - RRC_SUBFRAME_PROCESS(message_p).CC_id = CC_id; - LOG_D(NR_RRC, "Time in RRC: %u/ %u \n", frame, subframe); - itti_send_msg_to_task(TASK_RRC_GNB, ctxt->module_id, message_p); -} - diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index d499fcf61e..7f5b6ad14b 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -398,12 +398,7 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t int ret = gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, &create_tunnel_resp, nr_pdcp_data_req_drb, sdap_data_req); if (ret != 0) { LOG_E(NR_RRC, "rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE %x\n", UE->rnti); - UE->ue_release_timer_ng = 1; - UE->ue_release_timer_thres_ng = 100; - UE->ue_release_timer = 0; - UE->ue_reestablishment_timer = 0; - UE->ul_failure_timer = 20000; - UE->ul_failure_timer = 0; + AssertFatal(false, "release timer not implemented\n"); return (0); } @@ -655,7 +650,7 @@ rrc_gNB_send_NGAP_UPLINK_NAS( // NGAP_UPLINK_NAS (msg_p).nas_pdu.length, // ue_context_pP); itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p); - LOG_I(NR_RRC,"Send RRC GNB UL Information Transfer \n"); + LOG_D(NR_RRC,"Send RRC GNB UL Information Transfer \n"); } } @@ -1159,8 +1154,6 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_ } gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - UE->ue_release_timer_ng = 0; - UE->ue_release_timer_thres_rrc = 1000; PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0); ctxt.eNB_index = 0; rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p); diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c index c775726e87..831cad4742 100644 --- a/openair2/X2AP/x2ap_eNB.c +++ b/openair2/X2AP/x2ap_eNB.c @@ -767,3 +767,9 @@ mutex_error: LOG_E(X2AP, "mutex error\n"); exit(1); } + +void x2ap_trigger(void) +{ + MessageDef *msg = itti_alloc_new_message(TASK_X2AP, 0, X2AP_SUBFRAME_PROCESS); + itti_send_msg_to_task(TASK_X2AP, 0, msg); +} diff --git a/openair2/X2AP/x2ap_eNB.h b/openair2/X2AP/x2ap_eNB.h index afa6f11b8e..0f83ca64af 100644 --- a/openair2/X2AP/x2ap_eNB.h +++ b/openair2/X2AP/x2ap_eNB.h @@ -47,6 +47,7 @@ int x2ap_eNB_init_sctp (x2ap_eNB_instance_t *instance_p, void *x2ap_task(void *arg); int is_x2ap_enabled(void); +void x2ap_trigger(void); #endif /* X2AP_H_ */ diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index 4d3078493f..607e3e20d1 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -999,6 +999,11 @@ void *nas_nrue_task(void *args_p) case NAS_CONN_RELEASE_IND: LOG_I(NAS, "[UE %ld] Received %s: cause %u\n", instance, ITTI_MSG_NAME (msg_p), NAS_CONN_RELEASE_IND (msg_p).cause); + /* the following is not clean, but probably necessary: we need to give + * time to RLC to Ack the SRB1 PDU which contained the RRC release + * message. Hence, we just below wait some time, before finally + * unblocking the nr-uesoftmodem, which will terminate the process. */ + usleep(100000); itti_wait_tasks_unblock(); /* will unblock ITTI to stop nr-uesoftmodem */ break; diff --git a/openair3/NGAP/ngap_gNB_context_management_procedures.c b/openair3/NGAP/ngap_gNB_context_management_procedures.c index c9db35e8c8..b05f96b899 100644 --- a/openair3/NGAP/ngap_gNB_context_management_procedures.c +++ b/openair3/NGAP/ngap_gNB_context_management_procedures.c @@ -138,6 +138,11 @@ int ngap_ue_context_release_req(instance_t instance, /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: %u\n", ue_release_req_p->gNB_ue_ngap_id); + /* send response to free the UE: we don't know it, but it should be + * released since RRC seems to know it (e.g., there is no AMF) */ + MessageDef *msg = itti_alloc_new_message(TASK_NGAP, 0, NGAP_UE_CONTEXT_RELEASE_COMMAND); + NGAP_UE_CONTEXT_RELEASE_COMMAND(msg).gNB_ue_ngap_id = ue_release_req_p->gNB_ue_ngap_id; + itti_send_msg_to_task(TASK_RRC_GNB, ngap_gNB_instance_p->instance, msg); return -1; }