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)