From d9d6ce374f15d474768db8147336c4541bfa14d5 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 25 Jan 2019 16:37:57 +0100 Subject: [PATCH] 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). --- openair2/F1AP/f1ap_cu_ue_context_management.c | 29 ++++++++++++--- openair2/RRC/LTE/rrc_eNB.c | 36 ++++++------------- openair2/RRC/LTE/rrc_eNB_GTPV1U.c | 28 +++++++++++++++ openair2/RRC/LTE/rrc_eNB_GTPV1U.h | 10 ++++++ openair2/RRC/LTE/rrc_eNB_S1AP.c | 17 +++++++++ openair2/RRC/LTE/rrc_eNB_S1AP.h | 10 ++++++ 6 files changed, 101 insertions(+), 29 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index 8535934d36..660683a4c5 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -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)) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index af091c312b..5afa0c1134 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -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], diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c index 135c6fea8d..2587ac9436 100644 --- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c +++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c @@ -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 diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.h b/openair2/RRC/LTE/rrc_eNB_GTPV1U.h index aedbdeac5e..2c97801359 100644 --- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.h +++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.h @@ -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_ */ diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index db6b10c877..bd4db2ca14 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -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) diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.h b/openair2/RRC/LTE/rrc_eNB_S1AP.h index a924caf254..f16fa30408 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.h +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.h @@ -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)