Merge remote-tracking branch 'origin/int-f1-ue-ctxt-release' into integration_2023_w21
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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__*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+66
-200
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user