From a8a370ec21573af390be37d44cbf1e1e99fb85b5 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 22 Nov 2017 11:52:37 +0000 Subject: [PATCH] Starting to add Create Session Request function --- lib/include/srslte/asn1/gtpc.h | 32 ++++++++++-- srsepc/hdr/mme/mme_gtpc.h | 48 +++++++++++++++++ srsepc/hdr/mme/s1ap.h | 16 +++--- srsepc/src/mme/mme_gtpc.cc | 96 ++++++++++++++++++++++++++++++++++ srsepc/src/mme/s1ap.cc | 15 ++++-- srsepc/src/spgw/spgw.cc | 8 +-- 6 files changed, 195 insertions(+), 20 deletions(-) create mode 100644 srsepc/hdr/mme/mme_gtpc.h create mode 100644 srsepc/src/mme/mme_gtpc.cc diff --git a/lib/include/srslte/asn1/gtpc.h b/lib/include/srslte/asn1/gtpc.h index 130ee525b..339a63d74 100644 --- a/lib/include/srslte/asn1/gtpc.h +++ b/lib/include/srslte/asn1/gtpc.h @@ -146,6 +146,20 @@ const uint8_t GTPC_MSG_TYPE_MBMS_SESSION_STOP_RESPONSE = 236; //Other //240 - 255 For future use +/**************************************************************************** + * GTP-C v2 Message + * Ref: 3GPP TS 29.274 v10.14.0 + * + * This is the main structure to represent a GTP-C message. It is composed + * of one GTP-C header and one union of structures, which can hold + * all the possible GTP-C messages + ***************************************************************************/ +typedef struct gtpc_pdu +{ + struct gtpc_header; + union gtpc_msg_choice; +} gtpc_pdu_t; + /**************************************************************************** * GTP-C v2 Header * Ref: 3GPP TS 29.274 v10.14.0 Section 5 @@ -176,6 +190,16 @@ typedef struct gtpc_header uint64_t sequence; } gtpc_header_t; +/**************************************************************************** + * GTP-C v2 Header + * Ref: 3GPP TS 29.274 v10.14.0 Section 5 + * + * Union that hold the different structures for the possible message types. + ***************************************************************************/ +typedef union gtpc_msg_choice +{ + struct gtpc_create_session_request create_session_request; +}; /**************************************************************************** * @@ -186,9 +210,9 @@ typedef struct gtpc_header /* typedef struct gtpc_create_session_request { - bool imsi_present; + bool imsi_present; uint64_t imsi; // C - bool msidn_present; + bool msidn_present; uint64_t msisdn; // C bool mei_present; uint64_t mei; // C/CO @@ -196,11 +220,11 @@ typedef struct gtpc_create_session_request struct user_location_info_ uli; // C/CO bool serving_network_present; struct serving_network_ serving_network; // C/CO - + enum rat_type_ rat_type; // M bool indication_flags_present; struct indication_flags_ indication_flags; // C - + struct fteid_ sender_f_teid; // M bool pgw_addr_present; struct fteid_ pgw_addr; // C diff --git a/srsepc/hdr/mme/mme_gtpc.h b/srsepc/hdr/mme/mme_gtpc.h new file mode 100644 index 000000000..697046494 --- /dev/null +++ b/srsepc/hdr/mme/mme_gtpc.h @@ -0,0 +1,48 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2017 Software Radio Systems Limited + * + * \section LICENSE + * + * This file is part of srsLTE. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ +#ifndef MME_GTPC_H +#define MME_GTPC_H + +namespace srsepc +{ + +class mme_gtpc +{ +public: + mme_gtpc(); + ~mme_gtpc(); + + static mme_gtpc* get_instance(void); + static void cleanup(void); + + void init(); + + void send_create_session_request(uint64_t imsi, struct create_session_response *cs_resp); + +}; + +} +#endif diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index 23a01dac9..d51313c72 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -42,6 +42,7 @@ #include "mme/s1ap_common.h" #include "mme/s1ap_mngmt_proc.h" #include "mme/s1ap_nas_transport.h" +#include "mme/mme_gtpc.h" #include "hss/hss.h" namespace srsepc{ @@ -53,31 +54,29 @@ class s1ap public: s1ap(); virtual ~s1ap(); - int enb_listen(); + int enb_listen(); int init(s1ap_args_t s1ap_args, srslte::log_filter *s1ap_log); void stop(); 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_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT *ue_rel, 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); - void print_enb_ctx_info(const enb_ctx_t &enb_ctx); private: @@ -95,9 +94,12 @@ private: 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; + + //FIXME the GTP-C should be moved to the MME class, the the packaging of GTP-C messages is done. + mme_gtpc *m_gtpc; }; diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc new file mode 100644 index 000000000..0e0109cb2 --- /dev/null +++ b/srsepc/src/mme/mme_gtpc.cc @@ -0,0 +1,96 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2017 Software Radio Systems Limited + * + * \section LICENSE + * + * This file is part of srsLTE. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +#include + +namespace srsepc{ + +mme_gtpc* mme_gtpc::m_instance = NULL; +boost::mutex mme_gtpc_instance_mutex; + +mme_gtpc::mme_gtpc(): +{ +} + +mme_gtpc::~mme_gtpc() +{ +} + +mme_gtpc* +mme_gtpc::get_instance(void) +{ + boost::mutex::scoped_lock lock(mme_gtpc_instance_mutex); + if(NULL == m_instance) { + m_instance = new mme_gtpc(); + } + return(m_instance); +} + +void +mme_gtpc::cleanup(void) +{ + boost::mutex::scoped_lock lock(mme_gtpc_instance_mutex); + if(NULL != m_instance) { + delete m_instance; + m_instance = NULL; + } +} + + +void +mme_gtpc::init() +{ + m_spgw = spgw::get_instance(); +} + +void +mme_gtpc::send_create_session_request(uint64_t imsi, struct create_session_response *cs_resp) +{ + uint64_t imsi; + struct gtpc_pdu cs_req; + + //Setup GTP-C Header. FIXME: Length, sequence and other fields need to be added. + cs_req.header.piggyback = false; + cs_req.header.teid_present = true; + cs_req.header.type = GTPC_MSG_TYPE_CREATE_SESSION_REQUEST; + cs_req.header.teid = 0; //Send create session request to the butler TEID + + //Setup GTP-C Create Session Request IEs + // Control TEID allocated \\ + cs_req.create_session_request.sender_f_teid.tied = get_new_ctrl_teid(); + cs_req.create_session_request.sender_f_teid.ip = htonl(m_mme_ip); + // APN \\ + memcpy(cs_req.create_session_request.apn, "internet", sizeof("internet")); + // RAT Type \\ + cs_req.create_session_request.rat_type = GTPC_RAT_TYPE::EUTRAN; + + //Save RX Control TEID + create_rx_control_teid(create_session_request.sender_f_tied); + + spgw->handle_create_session_request(&cs_req, cs_resp); + return; +} +} //namespace srsepc diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 16ebd19e1..a334d47dc 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -44,6 +44,7 @@ s1ap::~s1ap() int s1ap::init(s1ap_args_t s1ap_args, srslte::log_filter *s1ap_log) { + m_pool = srslte::byte_buffer_pool::get_instance(); m_s1ap_args = s1ap_args; srslte::s1ap_mccmnc_to_plmn(s1ap_args.mcc, s1ap_args.mnc, &m_plmn); @@ -51,8 +52,8 @@ s1ap::init(s1ap_args_t s1ap_args, srslte::log_filter *s1ap_log) m_s1ap_log = s1ap_log; m_s1ap_nas_transport.set_log(s1ap_log); - m_hss = hss::get_instance(); - m_pool = srslte::byte_buffer_pool::get_instance(); + m_hss = hss::get_instance(); + m_gtpc = mme_gtpc::get_instance(); m_s1mme = enb_listen(); @@ -445,7 +446,7 @@ s1ap::handle_nas_authentication_response(srslte::byte_buffer_t *nas_msg, srslte: LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT auth_resp; bool ue_valid=true; - + //Get NAS authentication response LIBLTE_ERROR_ENUM err = liblte_mme_unpack_authentication_response_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &auth_resp); if(err != LIBLTE_SUCCESS){ @@ -469,7 +470,7 @@ s1ap::handle_nas_authentication_response(srslte::byte_buffer_t *nas_msg, srslte: std::cout << std::hex <<(uint16_t)ue_ctx->xres[i]; } std::cout<console("UE Authentication Rejected. IMSI: %lu\n", ue_ctx->imsi); m_s1ap_log->warning("UE Authentication Rejected. IMSI: %lu\n", ue_ctx->imsi); //Send back Athentication Reject @@ -483,7 +484,11 @@ s1ap::handle_nas_authentication_response(srslte::byte_buffer_t *nas_msg, srslte: //Send Security Mode Command m_s1ap_nas_transport.pack_security_mode_command(reply_msg, ue_ctx); - //m_gtpc->send_create_session_request(ue_ctx->imsi); + //FIXME The packging of GTP-C messages is not ready + //This means that GTP-U tunnels are created with function calls, as oposed to GTP-C. + //In future send_create_session_request will return void and the handle_create_session_response will be called from the GTP-C class itself. + struct gtpc_create_session_response *cs_resp = m_gtpc->send_create_session_request(ue_ctx->imsi); + m_gtpc->handle_create_session_response(cs_resp); } return true; } diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index 1d2169a9a..5f0a3d87f 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -83,7 +83,7 @@ spgw::init(spgw_args_t* args, srslte::log_filter *spgw_log) //Init log m_spgw_log = spgw_log; - + //Init SGi interface err = init_sgi_if(args); if (err != srslte::ERROR_NONE) @@ -112,7 +112,7 @@ spgw::stop() m_running = false; thread_cancel(); wait_thread_finish(); - + //Clean up SGi interface if(m_sgi_up) { @@ -135,7 +135,7 @@ spgw::run_thread() m_running=true; srslte::byte_buffer_t *msg; msg = m_pool->allocate(); - + struct sockaddr src_addr; socklen_t addrlen; @@ -150,7 +150,7 @@ spgw::run_thread() FD_ZERO(&set); FD_SET(m_s1u, &set); FD_SET(sgi, &set); - + m_spgw_log->info("Waiting for S1-U or SGi packets.\n"); int n = select(max_fd+1, &set, NULL, NULL, NULL); if (n == -1)