Perform S1 UE Context Release Complete after corresponding F1 message
This commits isolates the S1 UE Ctxt Rel Complete and GTP Tunnel Delete Requests in functions and calls these function in the original place (rrc_rx_tx()). The same functions are then used in the F1 UE Ctxt Rel Complete handler to perform the same functionality, i.e. forward the UE Ctxt Rel Complete message to the MME and free outstanding resources (RRC context, GTP tunnels, S1 context).
This commit is contained in:
@@ -41,6 +41,7 @@
|
||||
#include "rrc_extern.h"
|
||||
#include "rrc_eNB_UE_context.h"
|
||||
#include "rrc_eNB_S1AP.h"
|
||||
#include "rrc_eNB_GTPV1U.h"
|
||||
|
||||
extern f1ap_setup_req_t *f1ap_du_data_from_du;
|
||||
extern f1ap_cudu_ue_inst_t f1ap_cu_ue[MAX_eNB];
|
||||
@@ -962,6 +963,28 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
|
||||
// F1AP_CriticalityDiagnostics_IE_List
|
||||
}
|
||||
|
||||
struct rrc_eNB_ue_context_s *ue_context_p =
|
||||
rrc_eNB_get_ue_context(RC.rrc[instance], rnti);
|
||||
|
||||
/* The following is normally done in the function rrc_rx_tx() */
|
||||
rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(instance,
|
||||
ue_context_p->ue_context.eNB_ue_s1ap_id);
|
||||
|
||||
rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(instance, ue_context_p);
|
||||
// erase data of GTP tunnels in UE context
|
||||
for (int e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
|
||||
ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0;
|
||||
memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab],
|
||||
0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
|
||||
ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0;
|
||||
}
|
||||
|
||||
struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids =
|
||||
rrc_eNB_S1AP_get_ue_ids(RC.rrc[instance], 0,
|
||||
ue_context_p->ue_context.eNB_ue_s1ap_id);
|
||||
if (rrc_ue_s1ap_ids)
|
||||
rrc_eNB_S1AP_remove_ue_ids(RC.rrc[instance], rrc_ue_s1ap_ids);
|
||||
|
||||
/* The following is normally done in the function release_UE_in_freeList() */
|
||||
/* remove PDCP entry */
|
||||
protocol_ctxt_t ctxt;
|
||||
@@ -969,10 +992,8 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
|
||||
pdcp_remove_UE(&ctxt);
|
||||
|
||||
/* trigger UE release in RRC */
|
||||
struct rrc_eNB_ue_context_s *ue_context_pP;
|
||||
ue_context_pP = rrc_eNB_get_ue_context(RC.rrc[instance], rnti);
|
||||
if (ue_context_pP)
|
||||
rrc_eNB_remove_ue_context(&ctxt, RC.rrc[instance], ue_context_pP);
|
||||
if (ue_context_p)
|
||||
rrc_eNB_remove_ue_context(&ctxt, RC.rrc[instance], ue_context_p);
|
||||
|
||||
/* notify the agent */
|
||||
if (flexran_agent_get_rrc_xface(instance))
|
||||
|
||||
+11
-25
@@ -8226,40 +8226,26 @@ rrc_rx_tx(
|
||||
#if defined(ENABLE_USE_MME)
|
||||
#if defined(ENABLE_ITTI)
|
||||
if (RC.rrc[ctxt_pP->module_id]->node_type != ngran_eNB_DU) {
|
||||
int e_rab;
|
||||
MessageDef *msg_complete_p = NULL;
|
||||
MessageDef *msg_delete_tunnels_p = NULL;
|
||||
uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id;
|
||||
if(rrc_release_info.RRC_release_ctrl[release_num].flag == 4){
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_RRC_ENB,
|
||||
MSC_S1AP_ENB,
|
||||
NULL,0,
|
||||
"0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ",
|
||||
eNB_ue_s1ap_id);
|
||||
msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE);
|
||||
S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id;
|
||||
itti_send_msg_to_task(TASK_S1AP, ctxt_pP->module_id, msg_complete_p);
|
||||
rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(ctxt_pP->module_id,
|
||||
ue_context_p->ue_context.eNB_ue_s1ap_id);
|
||||
}
|
||||
MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id);
|
||||
msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ);
|
||||
memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p)));
|
||||
// do not wait response
|
||||
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
|
||||
for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
|
||||
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] =
|
||||
ue_context_p->ue_context.enb_gtp_ebi[e_rab];
|
||||
// erase data
|
||||
|
||||
rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(ctxt_pP->module_id,
|
||||
ue_context_p);
|
||||
// erase data of GTP tunnels in UE context
|
||||
for (int e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
|
||||
ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0;
|
||||
memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
|
||||
memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab],
|
||||
0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
|
||||
ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0;
|
||||
}
|
||||
itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p);
|
||||
|
||||
struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL;
|
||||
rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(
|
||||
RC.rrc[ctxt_pP->module_id],
|
||||
0,
|
||||
eNB_ue_s1ap_id);
|
||||
ue_context_p->ue_context.eNB_ue_s1ap_id);
|
||||
if (NULL != rrc_ue_s1ap_ids) {
|
||||
rrc_eNB_S1AP_remove_ue_ids(
|
||||
RC.rrc[ctxt_pP->module_id],
|
||||
|
||||
@@ -98,4 +98,32 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(
|
||||
module_id_t enb_mod_idP,
|
||||
const rrc_eNB_ue_context_t* const ue_context_pP
|
||||
)
|
||||
{
|
||||
if (!ue_context_pP) {
|
||||
LOG_W(RRC, "[eNB] In %s: invalid UE\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_RRC_ENB,
|
||||
MSC_GTPU_ENB,
|
||||
NULL,
|
||||
0,
|
||||
"0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", ue_context_pP->ue_context.rnti);
|
||||
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ);
|
||||
memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg)));
|
||||
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).rnti = ue_context_pP->ue_context.rnti;
|
||||
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).num_erab = ue_context_pP->ue_context.nb_of_e_rabs;
|
||||
for (int e_rab = 0; e_rab < ue_context_pP->ue_context.nb_of_e_rabs; e_rab++) {
|
||||
const rb_id_t gtp_ebi = ue_context_pP->ue_context.enb_gtp_ebi[e_rab];
|
||||
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).eps_bearer_id[e_rab] = gtp_ebi;
|
||||
}
|
||||
itti_send_msg_to_task(TASK_GTPV1_U, ENB_MODULE_ID_TO_INSTANCE(enb_mod_idP), msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -47,6 +47,16 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
uint8_t *inde_list
|
||||
);
|
||||
|
||||
/*! \fn rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(module_id_t enb_mod_idP, const rrc_eNB_ue_context_t* const ue_context_pP)
|
||||
*\brief Send GTPV1U_ENB_DELETE_TUNNEL_REQ message to GTPV1U to destroy all UE-related tunnels.
|
||||
*\param module_id Instance ID of eNB.
|
||||
*\param ue_context_pP UE context in the eNB.
|
||||
*/
|
||||
void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(
|
||||
module_id_t enb_mod_idP,
|
||||
const rrc_eNB_ue_context_t* const ue_context_pP
|
||||
);
|
||||
|
||||
# endif
|
||||
# endif /* defined(ENABLE_USE_MME) */
|
||||
#endif /* RRC_ENB_GTPV1U_H_ */
|
||||
|
||||
@@ -1229,6 +1229,23 @@ void rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ (
|
||||
}
|
||||
}
|
||||
|
||||
void rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(
|
||||
module_id_t enb_mod_idP,
|
||||
uint32_t eNB_ue_s1ap_id
|
||||
)
|
||||
{
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_RRC_ENB,
|
||||
MSC_S1AP_ENB,
|
||||
NULL,0,
|
||||
"0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ",
|
||||
eNB_ue_s1ap_id);
|
||||
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE);
|
||||
S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg).eNB_ue_s1ap_id = eNB_ue_s1ap_id;
|
||||
itti_send_msg_to_task(TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_mod_idP), msg);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
int rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND (MessageDef *msg_p, const char *msg_name, instance_t instance)
|
||||
|
||||
@@ -151,6 +151,16 @@ void rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ (
|
||||
const long cause_valueP
|
||||
);
|
||||
|
||||
/*! \fn rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(const module_id_t enb_mod_idP, const struct rrc_eNB_ue_context_s *const ue_context_pP)
|
||||
*\brief create a S1AP_UE_CONTEXT_RELEASE_COMPLETE message, the message is sent by the eNB to S1AP task to acknowledge/complete the release of the UE-associated S1-logical connection over the S1 interface. .
|
||||
*\param enb_mod_idP Instance ID of eNB.
|
||||
*\param eNB_ue_s1ap_id UE's S1AP ID in the eNB.
|
||||
*/
|
||||
void rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(
|
||||
module_id_t enb_mod_idP,
|
||||
uint32_t eNB_ue_s1ap_id
|
||||
);
|
||||
|
||||
/* Down link procedures */
|
||||
|
||||
/*! \fn rrc_eNB_process_S1AP_DOWNLINK_NAS(MessageDef *msg_p, const char *msg_name, instance_t instance, mui_t *rrc_eNB_mui)
|
||||
|
||||
Reference in New Issue
Block a user