diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index 4b895c2f6..8c659ac18 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -38,6 +38,7 @@ #include #include #include +#include #include "mme/s1ap_common.h" #include "mme/s1ap_mngmt_proc.h" #include "mme/s1ap_nas_transport.h" @@ -59,23 +60,19 @@ public: int get_s1_mme(); void delete_enb_ctx(int32_t assoc_id); + void delete_ues_in_enb(uint16_t enb_id); + bool handle_s1ap_rx_pdu(srslte::byte_buffer_t *pdu, struct sctp_sndrcvinfo *enb_sri); - bool handle_initiating_message(LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *msg, struct sctp_sndrcvinfo *enb_sri); bool handle_s1_setup_request(LIBLTE_S1AP_MESSAGE_S1SETUPREQUEST_STRUCT *msg, struct sctp_sndrcvinfo *enb_sri); - bool send_s1_setup_failure(struct sctp_sndrcvinfo *enb_sri); - bool send_s1_setup_response(struct sctp_sndrcvinfo *enb_sri); - bool handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSAGE_STRUCT *init_ue, struct sctp_sndrcvinfo *enb_sri); - + bool handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSAGE_STRUCT *init_ue, struct sctp_sndrcvinfo *enb_sri); bool handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRANSPORT_STRUCT *ul_xport, struct sctp_sndrcvinfo *enb_sri); - bool handle_nas_authentication_response(srslte::byte_buffer_t *nas_buffer, srslte::byte_buffer_t *reply_buffer, ue_ctx_t *ue_ctx); - bool handle_nas_security_mode_complete(srslte::byte_buffer_t *nas_msg, srslte::byte_buffer_t *reply_msg, ue_ctx_t *ue_ctx); @@ -91,11 +88,11 @@ private: hss *m_hss; int m_s1mme; - std::map m_active_enbs; - std::map m_sctp_to_enb_id; - std::map m_active_ues; - - uint32_t m_next_mme_ue_s1ap_id; + std::map m_active_enbs; + std::map m_sctp_to_enb_id; + std::map m_active_ues; + std::map > m_enb_id_to_ue_ids; + uint32_t m_next_mme_ue_s1ap_id; s1ap_mngmt_proc m_s1ap_mngmt_proc; s1ap_nas_transport m_s1ap_nas_transport; diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index a4c1b6d5f..3ed3a11ca 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -71,6 +71,7 @@ s1ap::stop() { m_s1ap_log->info("Deleting eNB context. eNB Id: 0x%x\n", it->second->enb_id); m_s1ap_log->console("Deleting eNB context. eNB Id: 0x%x\n", it->second->enb_id); + delete_ues_in_enb(it->second->enb_id); delete it->second; m_active_enbs.erase(it++); } @@ -79,23 +80,49 @@ s1ap::stop() void s1ap::delete_enb_ctx(int32_t assoc_id) -{ +{ std::map::iterator it_assoc = m_sctp_to_enb_id.find(assoc_id); uint16_t enb_id = it_assoc->second; + std::map::iterator it_ctx = m_active_enbs.find(enb_id); if(it_ctx == m_active_enbs.end() || it_assoc == m_sctp_to_enb_id.end()) { m_s1ap_log->error("Could not find eNB to delete. Association: %d\n",assoc_id); return; } + + m_s1ap_log->info("Deleting eNB context. eNB Id: 0x%x\n", enb_id); + m_s1ap_log->console("Deleting eNB context. eNB Id: 0x%x\n", enb_id); + + //Delete connected UEs ctx + delete_ues_in_enb(enb_id); + + //Delete eNB delete it_ctx->second; m_active_enbs.erase(it_ctx); m_sctp_to_enb_id.erase(it_assoc); - m_s1ap_log->info("Deleting eNB context. eNB Id: 0x%x\n", enb_id); - m_s1ap_log->console("Deleting eNB context. eNB Id: 0x%x\n", enb_id); - return; + return; } +void +s1ap::delete_ues_in_enb(uint16_t enb_id) +{ + //delete UEs ctx + std::map >::iterator ues_in_enb = m_enb_id_to_ue_ids.find(enb_id); + std::set::iterator ue_id = ues_in_enb->second.begin(); + while(ue_id != ues_in_enb->second.end() ) + { + std::map::iterator ue_ctx = m_active_ues.find(*ue_id); + m_s1ap_log->info("Deleting UE context. UE IMSI: %lu\n", ue_ctx->second->imsi); + m_s1ap_log->console("Deleting UE context. UE IMSI: %lu\n", ue_ctx->second->imsi); + delete ue_ctx->second; //delete UE context + m_active_ues.erase(ue_ctx); //remove from general MME map + ues_in_enb->second.erase(ue_id++); //erase from the eNB's UE set + } + +} + + int s1ap::get_s1_mme() { @@ -170,11 +197,11 @@ s1ap::handle_s1ap_rx_pdu(srslte::byte_buffer_t *pdu, struct sctp_sndrcvinfo *enb break; case LIBLTE_S1AP_S1AP_PDU_CHOICE_SUCCESSFULOUTCOME: m_s1ap_log->info("Received Succeseful Outcome PDU\n"); - return true;//handle_successfuloutcome(&rx_pdu.choice.successfulOutcome); + return true;//TODO handle_successfuloutcome(&rx_pdu.choice.successfulOutcome); break; case LIBLTE_S1AP_S1AP_PDU_CHOICE_UNSUCCESSFULOUTCOME: m_s1ap_log->info("Received Unsucceseful Outcome PDU\n"); - return true;//handle_unsuccessfuloutcome(&rx_pdu.choice.unsuccessfulOutcome); + return true;//TODO handle_unsuccessfuloutcome(&rx_pdu.choice.unsuccessfulOutcome); break; default: m_s1ap_log->error("Unhandled PDU type %d\n", rx_pdu.choice_type); @@ -240,10 +267,12 @@ s1ap::handle_s1_setup_request(LIBLTE_S1AP_MESSAGE_S1SETUPREQUEST_STRUCT *msg, st else { //new eNB + std::set ue_set; enb_ctx_t *enb_ptr = new enb_ctx_t; memcpy(enb_ptr,&enb_ctx,sizeof(enb_ctx)); m_active_enbs.insert(std::pair(enb_ptr->enb_id,enb_ptr)); m_sctp_to_enb_id.insert(std::pair(enb_sri->sinfo_assoc_id, enb_ptr->enb_id)); + m_enb_id_to_ue_ids.insert(std::pair >(enb_ptr->enb_id,ue_set)); } m_s1ap_mngmt_proc.pack_s1_setup_response(m_s1ap_args, &reply_msg); @@ -317,10 +346,15 @@ s1ap::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSAGE_STRUCT *ini ue_ctx.imsi = imsi; ue_ctx.mme_ue_s1ap_id = m_next_mme_ue_s1ap_id++; - ue_ctx_t *ue_ptr = new ue_ctx_t;//TODO use buffer pool here? + ue_ctx_t *ue_ptr = new ue_ctx_t; memcpy(ue_ptr,&ue_ctx,sizeof(ue_ctx)); m_active_ues.insert(std::pair(ue_ptr->mme_ue_s1ap_id,ue_ptr)); + std::map::iterator it_enb = m_sctp_to_enb_id.find(enb_sri->sinfo_assoc_id); + uint16_t enb_id = it_enb->second; + std::map >::iterator it_ue_id = m_enb_id_to_ue_ids.find(enb_id); + it_ue_id->second.insert(ue_ptr->mme_ue_s1ap_id); + //Pack NAS Authentication Request in Downlink NAS Transport msg srslte::byte_buffer_t *reply_msg = m_pool->allocate(); m_s1ap_nas_transport.pack_authentication_request(reply_msg, ue_ctx.enb_ue_s1ap_id, ue_ctx.mme_ue_s1ap_id, autn, rand);