Commit e0b31be1 authored by Robert Schmidt's avatar Robert Schmidt

Request release for UEs if DU disconnects

38.473 section 8.2.3.1 says that upon F1 Setup Request, UE associated
signalling should be erased. In this commit, we trigger a release of all
UEs that were still connected to a DU when we received the SCTP
shutdown, i.e., when the DU disconnects.
parent e5e48bb2
......@@ -63,6 +63,7 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,NR_UE_CapabilityRAT_ContainerLi
void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m);
void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti);
void rrc_remove_ue(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p);
void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
NR_ServingCellConfig_t *servingcellconfigdedicated,
......
......@@ -1940,6 +1940,19 @@ static void rrc_delete_ue_data(gNB_RRC_UE_t *UE)
ASN_STRUCT_FREE(asn_DEF_NR_MeasResults, UE->measResults);
}
void rrc_remove_ue(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p)
{
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
/* we call nr_pdcp_remove_UE() in the handler of E1 bearer release, but if we
* are in E1, we also need to free the UE in the CU-CP, so call it twice to
* cover all cases */
nr_pdcp_remove_UE(UE->rrc_ue_id);
rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(0, UE->rrc_ue_id);
LOG_I(NR_RRC, "removed UE CU UE ID %u/RNTI %04x \n", UE->rrc_ue_id, UE->rnti);
rrc_delete_ue_data(UE);
rrc_gNB_remove_ue_context(rrc, ue_context_p);
}
static void rrc_CU_process_ue_context_release_complete(MessageDef *msg_p)
{
const int instance = 0;
......@@ -1950,16 +1963,8 @@ static void rrc_CU_process_ue_context_release_complete(MessageDef *msg_p)
LOG_E(RRC, "could not find UE context for CU UE ID %u, aborting transaction\n", complete->gNB_CU_ue_id);
return;
}
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
/* we call nr_pdcp_remove_UE() in the handler of E1 bearer release, but if we
* are in E1, we also need to free the UE in the CU-CP, so call it twice to
* cover all cases */
nr_pdcp_remove_UE(UE->rrc_ue_id);
rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance, UE->rrc_ue_id);
LOG_I(NR_RRC, "removed UE CU UE ID %u/RNTI %04x \n", UE->rrc_ue_id, UE->rnti);
rrc_delete_ue_data(UE);
rrc_gNB_remove_ue_context(rrc, ue_context_p);
rrc_remove_ue(RC.nrrrc[0], ue_context_p);
}
static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, instance_t instance)
......@@ -2672,23 +2677,6 @@ rrc_gNB_generate_RRCRelease(
};
deliver_ue_ctxt_release_data_t data = {.rrc = rrc, .release_cmd = &ue_context_release_cmd, .assoc_id = ue_data.du_assoc_id};
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_release_cmd, &data);
/* a UE might not be associated to a CU-UP if it never requested a PDU
* session (intentionally, or because of erros) */
if (ue_associated_to_cuup(rrc, UE)) {
sctp_assoc_t assoc_id = get_existing_cuup_for_ue(rrc, UE);
e1ap_bearer_release_cmd_t cmd = {
.gNB_cu_cp_ue_id = UE->rrc_ue_id,
.gNB_cu_up_ue_id = UE->rrc_ue_id,
};
rrc->cucp_cuup.bearer_context_release(assoc_id, &cmd);
}
#ifdef E2_AGENT
signal_rrc_state_changed_to(UE, RC_SM_RRC_IDLE);
#endif
/* UE will be freed after UE context release complete */
}
int rrc_gNB_generate_pcch_msg(sctp_assoc_t assoc_id, const NR_SIB1_t *sib1, uint32_t tmsi, uint8_t paging_drx)
......
......@@ -73,6 +73,10 @@
#include "conversions.h"
#include "RRC/NR/rrc_gNB_radio_bearers.h"
#ifdef E2_AGENT
#include "openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc_extern.h"
#endif
#include "uper_encoder.h"
extern RAN_CONTEXT_t RC;
......@@ -1178,7 +1182,7 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ(MessageDef *msg_p, instance_t in
itti_send_msg_to_task(TASK_NGAP, instance, msg_fail_p);
return (-1);
} else {
/* TODO release context. */
/* Send the response */
MessageDef *msg_resp_p;
msg_resp_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_RESP);
......@@ -1195,7 +1199,7 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ(MessageDef *msg_p, instance_t in
*/
int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_t instance)
{
//-----------------------------------------------------------------------------
gNB_RRC_INST *rrc = RC.nrrrc[0];
uint32_t gNB_ue_ngap_id = 0;
protocol_ctxt_t ctxt;
gNB_ue_ngap_id = NGAP_UE_CONTEXT_RELEASE_COMMAND(msg_p).gNB_ue_ngap_id;
......@@ -1214,9 +1218,34 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_
}
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0);
ctxt.eNB_index = 0;
rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p);
#ifdef E2_AGENT
signal_rrc_state_changed_to(UE, RC_SM_RRC_IDLE);
#endif
/* a UE might not be associated to a CU-UP if it never requested a PDU
* session (intentionally, or because of erros) */
if (ue_associated_to_cuup(rrc, UE)) {
sctp_assoc_t assoc_id = get_existing_cuup_for_ue(rrc, UE);
e1ap_bearer_release_cmd_t cmd = {
.gNB_cu_cp_ue_id = UE->rrc_ue_id,
.gNB_cu_up_ue_id = UE->rrc_ue_id,
};
rrc->cucp_cuup.bearer_context_release(assoc_id, &cmd);
}
/* special case: the DU might be offline, in which case the f1_ue_data exists
* but is set to 0 */
if (cu_exists_f1_ue_data(UE->rrc_ue_id) && cu_get_f1_ue_data(UE->rrc_ue_id).du_assoc_id != 0) {
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0);
ctxt.eNB_index = 0;
rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p);
/* UE will be freed after UE context release complete */
} else {
// the DU is offline already
rrc_remove_ue(rrc, ue_context_p);
}
return 0;
}
......
......@@ -20,6 +20,7 @@
*/
#include "rrc_gNB_du.h"
#include "rrc_gNB_NGAP.h"
#include "common/ran_context.h"
#include "nr_rrc_defs.h"
#include "rrc_gNB_UE_context.h"
......@@ -211,10 +212,14 @@ static int invalidate_du_connections(gNB_RRC_INST *rrc, sctp_assoc_t assoc_id)
f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_id);
if (ue_data.du_assoc_id == assoc_id) {
/* this UE belongs to the DU that disconnected, set du_assoc_id to 0,
* meaning DU is offline */
* meaning DU is offline, then trigger release request */
cu_remove_f1_ue_data(ue_id);
f1_ue_data_t new = {.secondary_ue = ue_data.secondary_ue, .du_assoc_id = 0 };
cu_add_f1_ue_data(ue_id, &new);
ue_data.du_assoc_id = 0;
cu_add_f1_ue_data(ue_id, &ue_data);
rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(0,
ue_context_p,
NGAP_CAUSE_RADIO_NETWORK,
NGAP_CAUSE_RADIO_NETWORK_RADIO_CONNECTION_WITH_UE_LOST);
count++;
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment