From 6e500c5b866127672c30d1f88257f72b4cbdaec8 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 19 Mar 2019 16:10:38 +0000 Subject: [PATCH] Changed initilization of the NAS at the EPC, to make it easier to add new interfaces. --- srsepc/hdr/mme/nas.h | 44 +++++-------- srsepc/hdr/mme/s1ap_nas_transport.h | 5 ++ srsepc/src/mme/nas.cc | 99 +++++++++++++++++----------- srsepc/src/mme/s1ap_nas_transport.cc | 40 +++++------ 4 files changed, 100 insertions(+), 88 deletions(-) diff --git a/srsepc/hdr/mme/nas.h b/srsepc/hdr/mme/nas.h index a4c3b3d20..37ad2e145 100644 --- a/srsepc/hdr/mme/nas.h +++ b/srsepc/hdr/mme/nas.h @@ -137,15 +137,17 @@ typedef struct { srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo; } nas_init_t; +typedef struct { + s1ap_interface_nas* s1ap; + gtpc_interface_nas* gtpc; + hss_interface_nas* hss; +} nas_if_t; + class nas { public: nas(); - void init(nas_init_t args, - s1ap_interface_nas* s1ap, - gtpc_interface_nas* gtpc, - hss_interface_nas* hss, - srslte::log* nas_log); + void init(nas_init_t args, nas_if_t itf, srslte::log* nas_log); /*********************** * Initial UE messages * @@ -155,9 +157,7 @@ public: struct sctp_sndrcvinfo* enb_sri, srslte::byte_buffer_t* nas_rx, nas_init_t args, - s1ap_interface_nas* s1ap, - gtpc_interface_nas* gtpc, - hss_interface_nas* hss, + nas_if_t itf, srslte::log* nas_log); static bool handle_imsi_attach_request_unknown_ue(uint32_t enb_ue_s1ap_id, @@ -165,9 +165,7 @@ public: const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT& attach_req, const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT& pdn_con_req, nas_init_t args, - s1ap_interface_nas* s1ap, - gtpc_interface_nas* gtpc, - hss_interface_nas* hss, + nas_if_t itf, srslte::log* nas_log); static bool handle_imsi_attach_request_known_ue(nas* nas_ctx, @@ -177,9 +175,7 @@ public: const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT& pdn_con_req, srslte::byte_buffer_t* nas_rx, nas_init_t args, - s1ap_interface_nas* s1ap, - gtpc_interface_nas* gtpc, - hss_interface_nas* hss, + nas_if_t itf, srslte::log* nas_log); static bool handle_guti_attach_request_unknown_ue(uint32_t enb_ue_s1ap_id, @@ -187,9 +183,7 @@ public: const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT& attach_req, const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT& pdn_con_req, nas_init_t args, - s1ap_interface_nas* s1ap, - gtpc_interface_nas* gtpc, - hss_interface_nas* hss, + nas_if_t itf, srslte::log* nas_log); static bool handle_guti_attach_request_known_ue(nas* nas_ctx, @@ -199,9 +193,7 @@ public: const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT& pdn_con_req, srslte::byte_buffer_t* nas_rx, nas_init_t args, - s1ap_interface_nas* s1ap, - gtpc_interface_nas* gtpc, - hss_interface_nas* hss, + nas_if_t itf, srslte::log* nas_log); // Service request messages @@ -210,9 +202,7 @@ public: struct sctp_sndrcvinfo* enb_sri, srslte::byte_buffer_t* nas_rx, nas_init_t args, - s1ap_interface_nas* s1ap, - gtpc_interface_nas* gtpc, - hss_interface_nas* hss, + nas_if_t itf, srslte::log* nas_log); // Dettach request messages @@ -221,9 +211,7 @@ public: struct sctp_sndrcvinfo* enb_sri, srslte::byte_buffer_t* nas_rx, nas_init_t args, - s1ap_interface_nas* s1ap, - gtpc_interface_nas* gtpc, - hss_interface_nas* hss, + nas_if_t itf, srslte::log* nas_log); // Tracking area update request messages @@ -232,9 +220,7 @@ public: struct sctp_sndrcvinfo* enb_sri, srslte::byte_buffer_t* nas_rx, nas_init_t args, - s1ap_interface_nas* s1ap, - gtpc_interface_nas* gtpc, - hss_interface_nas* hss, + nas_if_t itf, srslte::log* nas_log); /* Uplink NAS messages handling */ diff --git a/srsepc/hdr/mme/s1ap_nas_transport.h b/srsepc/hdr/mme/s1ap_nas_transport.h index f6055ba38..3b889abec 100644 --- a/srsepc/hdr/mme/s1ap_nas_transport.h +++ b/srsepc/hdr/mme/s1ap_nas_transport.h @@ -47,10 +47,12 @@ public: struct sctp_sndrcvinfo* enb_sri, srslte::byte_buffer_t* reply_buffer, bool* reply_flag); + bool handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRANSPORT_STRUCT* ul_xport, struct sctp_sndrcvinfo* enb_sri, srslte::byte_buffer_t* reply_buffer, bool* reply_flag); + bool send_downlink_nas_transport(uint32_t enb_ue_s1ap_id, uint32_t mme_ue_s1ap_id, srslte::byte_buffer_t* nas_msg, @@ -66,6 +68,9 @@ private: s1ap* m_s1ap; hss_interface_nas* m_hss; mme_gtpc* m_mme_gtpc; + + nas_init_t m_nas_init; + nas_if_t m_nas_if; }; } // namespace srsepc diff --git a/srsepc/src/mme/nas.cc b/srsepc/src/mme/nas.cc index 8f6a8168a..5e6d05075 100644 --- a/srsepc/src/mme/nas.cc +++ b/srsepc/src/mme/nas.cc @@ -38,8 +38,7 @@ nas::nas() m_pool = srslte::byte_buffer_pool::get_instance(); } -void nas::init( - nas_init_t args, s1ap_interface_nas* s1ap, gtpc_interface_nas* gtpc, hss_interface_nas* hss, srslte::log* nas_log) +void nas::init(nas_init_t args, nas_if_t itf, srslte::log* nas_log) { m_mcc = args.mcc; m_mnc = args.mnc; @@ -52,9 +51,9 @@ void nas::init( m_sec_ctx.integ_algo = args.integ_algo; m_sec_ctx.cipher_algo = args.cipher_algo; - m_s1ap = s1ap; - m_gtpc = gtpc; - m_hss = hss; + m_s1ap = itf.s1ap; + m_gtpc = itf.gtpc; + m_hss = itf.hss; m_nas_log = nas_log; m_nas_log->info("NAS Context Initialized. MCC: 0x%x, MNC 0x%x\n", m_mcc, m_mnc); } @@ -68,9 +67,7 @@ bool nas::handle_attach_request(uint32_t enb_ue_s1ap_id, struct sctp_sndrcvinfo* enb_sri, srslte::byte_buffer_t* nas_rx, nas_init_t args, - s1ap_interface_nas* s1ap, - gtpc_interface_nas* gtpc, - hss_interface_nas* hss, + nas_if_t itf, srslte::log* nas_log) { uint32_t m_tmsi = 0; @@ -78,6 +75,11 @@ bool nas::handle_attach_request(uint32_t enb_ue_s1ap_id, LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT attach_req; LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT pdn_con_req; + // Interfaces + s1ap_interface_nas* s1ap = itf.s1ap; + hss_interface_nas* hss = itf.hss; + gtpc_interface_nas* gtpc = itf.gtpc; + // Get NAS Attach Request and PDN connectivity request messages LIBLTE_ERROR_ENUM err = liblte_mme_unpack_attach_request_msg((LIBLTE_BYTE_MSG_STRUCT*)nas_rx, &attach_req); if (err != LIBLTE_SUCCESS) { @@ -151,11 +153,9 @@ bool nas::handle_attach_request(uint32_t enb_ue_s1ap_id, if (nas_ctx == NULL) { // Get attach type from attach request if (attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI) { - nas::handle_imsi_attach_request_unknown_ue(enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req, args, s1ap, gtpc, - hss, nas_log); + nas::handle_imsi_attach_request_unknown_ue(enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req, args, itf, nas_log); } else if (attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_GUTI) { - nas::handle_guti_attach_request_unknown_ue(enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req, args, s1ap, gtpc, - hss, nas_log); + nas::handle_guti_attach_request_unknown_ue(enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req, args, itf, nas_log); } else { return false; } @@ -164,10 +164,10 @@ bool nas::handle_attach_request(uint32_t enb_ue_s1ap_id, nas_log->console("Attach Request -- Found previously attach UE.\n"); if (attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI) { nas::handle_imsi_attach_request_known_ue(nas_ctx, enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req, nas_rx, args, - s1ap, gtpc, hss, nas_log); + itf, nas_log); } else if (attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_GUTI) { nas::handle_guti_attach_request_known_ue(nas_ctx, enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req, nas_rx, args, - s1ap, gtpc, hss, nas_log); + itf, nas_log); } else { return false; } @@ -180,15 +180,18 @@ bool nas::handle_imsi_attach_request_unknown_ue(uint32_t const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT& attach_req, const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT& pdn_con_req, nas_init_t args, - s1ap_interface_nas* s1ap, - gtpc_interface_nas* gtpc, - hss_interface_nas* hss, + nas_if_t itf, srslte::log* nas_log) { nas* nas_ctx; srslte::byte_buffer_t* nas_tx; srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); + // Interfaces + s1ap_interface_nas* s1ap = itf.s1ap; + hss_interface_nas* hss = itf.hss; + gtpc_interface_nas* gtpc = itf.gtpc; + // Get IMSI uint64_t imsi = 0; for (int i = 0; i <= 14; i++) { @@ -197,7 +200,7 @@ bool nas::handle_imsi_attach_request_unknown_ue(uint32_t // Create UE context nas_ctx = new nas; - nas_ctx->init(args, s1ap, gtpc, hss, nas_log); + nas_ctx->init(args, itf, nas_log); // Save IMSI, eNB UE S1AP Id, MME UE S1AP Id and make sure UE is EMM_DEREGISTERED nas_ctx->m_emm_ctx.imsi = imsi; @@ -275,12 +278,16 @@ bool nas::handle_imsi_attach_request_known_ue(nas* const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT& pdn_con_req, srslte::byte_buffer_t* nas_rx, nas_init_t args, - s1ap_interface_nas* s1ap, - gtpc_interface_nas* gtpc, - hss_interface_nas* hss, + nas_if_t itf, srslte::log* nas_log) { bool err; + + // Interfaces + s1ap_interface_nas* s1ap = itf.s1ap; + hss_interface_nas* hss = itf.hss; + gtpc_interface_nas* gtpc = itf.gtpc; + // Delete previous GTP-U session gtpc->send_delete_session_request(nas_ctx->m_emm_ctx.imsi); @@ -292,8 +299,7 @@ bool nas::handle_imsi_attach_request_known_ue(nas* s1ap->delete_ue_ctx(nas_ctx->m_emm_ctx.imsi); // Handle new attach - err = nas::handle_imsi_attach_request_unknown_ue(enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req, args, s1ap, gtpc, - hss, nas_log); + err = nas::handle_imsi_attach_request_unknown_ue(enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req, args, itf, nas_log); return err; } @@ -302,9 +308,7 @@ bool nas::handle_guti_attach_request_unknown_ue(uint32_t const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT& attach_req, const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT& pdn_con_req, nas_init_t args, - s1ap_interface_nas* s1ap, - gtpc_interface_nas* gtpc, - hss_interface_nas* hss, + nas_if_t itf, srslte::log* nas_log) { @@ -312,9 +316,14 @@ bool nas::handle_guti_attach_request_unknown_ue(uint32_t srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); srslte::byte_buffer_t* nas_tx; + // Interfaces + s1ap_interface_nas* s1ap = itf.s1ap; + hss_interface_nas* hss = itf.hss; + gtpc_interface_nas* gtpc = itf.gtpc; + // Create new NAS context. nas_ctx = new nas; - nas_ctx->init(args, s1ap, gtpc, hss, nas_log); + nas_ctx->init(args, itf, nas_log); // Could not find IMSI from M-TMSI, send Id request // The IMSI will be set when the identity response is received @@ -377,9 +386,7 @@ bool nas::handle_guti_attach_request_known_ue(nas* const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT& pdn_con_req, srslte::byte_buffer_t* nas_rx, nas_init_t args, - s1ap_interface_nas* s1ap, - gtpc_interface_nas* gtpc, - hss_interface_nas* hss, + nas_if_t itf, srslte::log* nas_log) { bool msg_valid = false; @@ -390,6 +397,11 @@ bool nas::handle_guti_attach_request_known_ue(nas* ecm_ctx_t* ecm_ctx = &nas_ctx->m_ecm_ctx; sec_ctx_t* sec_ctx = &nas_ctx->m_sec_ctx; + // Interfaces + s1ap_interface_nas* s1ap = itf.s1ap; + hss_interface_nas* hss = itf.hss; + gtpc_interface_nas* gtpc = itf.gtpc; + nas_log->console("Found UE context. IMSI: %015" PRIu64 ", old eNB UE S1ap Id %d, old MME UE S1AP Id %d\n", emm_ctx->imsi, ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id); @@ -526,9 +538,7 @@ bool nas::handle_service_request(uint32_t m_tmsi, struct sctp_sndrcvinfo* enb_sri, srslte::byte_buffer_t* nas_rx, nas_init_t args, - s1ap_interface_nas* s1ap, - gtpc_interface_nas* gtpc, - hss_interface_nas* hss, + nas_if_t itf, srslte::log* nas_log) { nas_log->info("Service request -- S-TMSI 0x%x\n", m_tmsi); @@ -540,6 +550,11 @@ bool nas::handle_service_request(uint32_t m_tmsi, LIBLTE_MME_SERVICE_REQUEST_MSG_STRUCT service_req; srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); + // Interfaces + s1ap_interface_nas* s1ap = itf.s1ap; + hss_interface_nas* hss = itf.hss; + gtpc_interface_nas* gtpc = itf.gtpc; + LIBLTE_ERROR_ENUM err = liblte_mme_unpack_service_request_msg((LIBLTE_BYTE_MSG_STRUCT*)nas_rx, &service_req); if (err != LIBLTE_SUCCESS) { nas_log->error("Could not unpack service request\n"); @@ -637,9 +652,7 @@ bool nas::handle_detach_request(uint32_t m_tmsi, struct sctp_sndrcvinfo* enb_sri, srslte::byte_buffer_t* nas_rx, nas_init_t args, - s1ap_interface_nas* s1ap, - gtpc_interface_nas* gtpc, - hss_interface_nas* hss, + nas_if_t itf, srslte::log* nas_log) { nas_log->info("Detach Request -- S-TMSI 0x%x\n", m_tmsi); @@ -650,6 +663,11 @@ bool nas::handle_detach_request(uint32_t m_tmsi, bool mac_valid = false; LIBLTE_MME_DETACH_REQUEST_MSG_STRUCT detach_req; + // Interfaces + s1ap_interface_nas* s1ap = itf.s1ap; + hss_interface_nas* hss = itf.hss; + gtpc_interface_nas* gtpc = itf.gtpc; + LIBLTE_ERROR_ENUM err = liblte_mme_unpack_detach_request_msg((LIBLTE_BYTE_MSG_STRUCT*)nas_rx, &detach_req); if (err != LIBLTE_SUCCESS) { nas_log->error("Could not unpack detach request\n"); @@ -692,9 +710,7 @@ bool nas::handle_tracking_area_update_request(uint32_t m_tmsi, struct sctp_sndrcvinfo* enb_sri, srslte::byte_buffer_t* nas_rx, nas_init_t args, - s1ap_interface_nas* s1ap, - gtpc_interface_nas* gtpc, - hss_interface_nas* hss, + nas_if_t itf, srslte::log* nas_log) { nas_log->info("Tracking Area Update Request -- S-TMSI 0x%x\n", m_tmsi); @@ -705,6 +721,11 @@ bool nas::handle_tracking_area_update_request(uint32_t m_tmsi, nas_log->console("Warning: Tracking area update requests are not handled yet.\n"); nas_log->warning("Tracking area update requests are not handled yet.\n"); + // Interfaces + s1ap_interface_nas* s1ap = itf.s1ap; + hss_interface_nas* hss = itf.hss; + gtpc_interface_nas* gtpc = itf.gtpc; + uint64_t imsi = s1ap->find_imsi_from_m_tmsi(m_tmsi); if (imsi == 0) { nas_log->console("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index d0eb53034..97d90eb61 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -73,8 +73,21 @@ void s1ap_nas_transport::init() m_s1ap_log = m_s1ap->m_s1ap_log; m_pool = srslte::byte_buffer_pool::get_instance(); - m_hss = hss::get_instance(); - m_mme_gtpc = mme_gtpc::get_instance(); + //Init NAS args + m_nas_init.mcc = m_s1ap->m_s1ap_args.mcc; + m_nas_init.mnc = m_s1ap->m_s1ap_args.mnc; + m_nas_init.mme_code = m_s1ap->m_s1ap_args.mme_code; + m_nas_init.mme_group = m_s1ap->m_s1ap_args.mme_group; + m_nas_init.tac = m_s1ap->m_s1ap_args.tac; + m_nas_init.apn = m_s1ap->m_s1ap_args.mme_apn; + m_nas_init.dns = m_s1ap->m_s1ap_args.dns_addr; + m_nas_init.integ_algo = m_s1ap->m_s1ap_args.integrity_algo; + m_nas_init.cipher_algo = m_s1ap->m_s1ap_args.encryption_algo; + + //Init NAS interface + m_nas_if.s1ap = s1ap::get_instance(); + m_nas_if.gtpc = mme_gtpc::get_instance(); + m_nas_if.hss = hss::get_instance(); } bool s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSAGE_STRUCT* init_ue, @@ -96,17 +109,6 @@ bool s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUE m_s1ap_log->console("Initial UE message: %s\n", liblte_nas_msg_type_to_string(msg_type)); m_s1ap_log->info("Initial UE message: %s\n", liblte_nas_msg_type_to_string(msg_type)); - nas_init_t nas_init; - nas_init.mcc = m_s1ap->m_s1ap_args.mcc; - nas_init.mnc = m_s1ap->m_s1ap_args.mnc; - nas_init.mme_code = m_s1ap->m_s1ap_args.mme_code; - nas_init.mme_group = m_s1ap->m_s1ap_args.mme_group; - nas_init.tac = m_s1ap->m_s1ap_args.tac; - nas_init.apn = m_s1ap->m_s1ap_args.mme_apn; - nas_init.dns = m_s1ap->m_s1ap_args.dns_addr; - nas_init.integ_algo = m_s1ap->m_s1ap_args.integrity_algo; - nas_init.cipher_algo = m_s1ap->m_s1ap_args.encryption_algo; - if (init_ue->S_TMSI_present) { srslte::uint8_to_uint32(init_ue->S_TMSI.m_TMSI.buffer, &m_tmsi); } @@ -115,26 +117,24 @@ bool s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUE case LIBLTE_MME_MSG_TYPE_ATTACH_REQUEST: m_s1ap_log->console("Received Initial UE message -- Attach Request\n"); m_s1ap_log->info("Received Initial UE message -- Attach Request\n"); - err = nas::handle_attach_request(enb_ue_s1ap_id, enb_sri, nas_msg, nas_init, m_s1ap, m_mme_gtpc, m_hss, - m_s1ap->m_nas_log); + err = nas::handle_attach_request(enb_ue_s1ap_id, enb_sri, nas_msg, m_nas_init, m_nas_if, m_s1ap->m_nas_log); break; case LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST: m_s1ap_log->console("Received Initial UE message -- Service Request\n"); m_s1ap_log->info("Received Initial UE message -- Service Request\n"); - err = nas::handle_service_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg, nas_init, m_s1ap, m_mme_gtpc, m_hss, + err = nas::handle_service_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg, m_nas_init, m_nas_if, m_s1ap->m_nas_log); break; case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST: m_s1ap_log->console("Received Initial UE message -- Detach Request\n"); m_s1ap_log->info("Received Initial UE message -- Detach Request\n"); - err = nas::handle_detach_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg, nas_init, m_s1ap, m_mme_gtpc, m_hss, - m_s1ap->m_nas_log); + err = nas::handle_detach_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg, m_nas_init, m_nas_if, m_s1ap->m_nas_log); break; case LIBLTE_MME_MSG_TYPE_TRACKING_AREA_UPDATE_REQUEST: m_s1ap_log->console("Received Initial UE message -- Tracking Area Update Request\n"); m_s1ap_log->info("Received Initial UE message -- Tracking Area Update Request\n"); - err = nas::handle_tracking_area_update_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg, nas_init, m_s1ap, - m_mme_gtpc, m_hss, m_s1ap->m_nas_log); + err = nas::handle_tracking_area_update_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg, m_nas_init, m_nas_if, + m_s1ap->m_nas_log); break; default: m_s1ap_log->info("Unhandled Initial UE Message 0x%x \n", msg_type);