diff --git a/srsepc/hdr/mme/mme_gtpc.h b/srsepc/hdr/mme/mme_gtpc.h index 5864ca9c6..bb0e2a55b 100644 --- a/srsepc/hdr/mme/mme_gtpc.h +++ b/srsepc/hdr/mme/mme_gtpc.h @@ -31,6 +31,8 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/log.h" #include "srslte/common/log_filter.h" +#include +#include namespace srsepc { @@ -44,13 +46,13 @@ public: srslte::gtp_fteid_t mme_ctr_fteid; srslte::gtp_fteid_t sgw_ctr_fteid; } gtpc_ctx_t; + static mme_gtpc* get_instance(void); static void cleanup(void); bool init(srslte::log_filter* mme_gtpc_log); void handle_s11_pdu(srslte::gtpc_pdu* msg); - uint32_t get_new_ctrl_teid(); virtual bool send_create_session_request(uint64_t imsi); bool handle_create_session_response(srslte::gtpc_pdu* cs_resp_pdu); virtual bool send_modify_bearer_request(uint64_t imsi, uint16_t erab_to_modify, srslte::gtp_fteid_t* enb_fteid); @@ -73,6 +75,12 @@ private: uint32_t m_next_ctrl_teid; std::map m_mme_ctr_teid_to_imsi; std::map m_imsi_to_gtpc_ctx; + + int m_s11; + struct sockaddr_un m_mme_addr, m_spgw_addr; + + bool init_s11(); + uint32_t get_new_ctrl_teid(); }; inline uint32_t mme_gtpc::get_new_ctrl_teid() diff --git a/srsepc/hdr/spgw/gtpc.h b/srsepc/hdr/spgw/gtpc.h index c3ff5d686..53f064254 100644 --- a/srsepc/hdr/spgw/gtpc.h +++ b/srsepc/hdr/spgw/gtpc.h @@ -29,6 +29,8 @@ #include "srsepc/hdr/spgw/spgw.h" #include "srslte/asn1/gtpc.h" #include "srslte/interfaces/epc_interfaces.h" +#include +#include namespace srsepc { @@ -40,13 +42,16 @@ public: int init(spgw_args_t* args, spgw* spgw, gtpu_interface_gtpc* gtpu, srslte::log_filter* gtpc_log); void stop(); + srslte::error_t init_s11(spgw_args_t *args); srslte::error_t init_ue_ip(spgw_args_t* args); + int get_s11(); uint64_t get_new_ctrl_teid(); uint64_t get_new_user_teid(); in_addr_t get_new_ue_ipv4(); void handle_s11_pdu(srslte::gtpc_pdu* msg, srslte::gtpc_pdu* reply_msg); + void handle_create_session_request(const srslte::gtpc_create_session_request& cs_req, srslte::gtpc_pdu* gtpc_pdu); void handle_modify_bearer_request(const srslte::gtpc_header& mb_req_hdr, const srslte::gtpc_modify_bearer_request& mb_req, @@ -64,6 +69,9 @@ public: spgw* m_spgw; gtpu_interface_gtpc* m_gtpu; + int m_s11; + struct sockaddr_un m_spgw_addr, m_mme_addr; + uint32_t m_h_next_ue_ip; uint64_t m_next_ctrl_teid; uint64_t m_next_user_teid; @@ -77,6 +85,11 @@ public: srslte::byte_buffer_pool* m_pool; }; +inline int spgw::gtpc::get_s11() +{ + return m_s11; +} + inline uint64_t spgw::gtpc::get_new_ctrl_teid() { return m_next_ctrl_teid++; diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index 13296493f..1de0d87c6 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -73,14 +73,59 @@ bool mme_gtpc::init(srslte::log_filter* mme_gtpc_log) m_next_ctrl_teid = 1; - m_s1ap = s1ap::get_instance(); + m_s1ap = s1ap::get_instance(); m_spgw = spgw::get_instance(); + if (!init_s11()) { + m_mme_gtpc_log->error("Error Initializing MME S11 Interface\n"); + return false; + } + m_mme_gtpc_log->info("MME GTP-C Initialized\n"); m_mme_gtpc_log->console("MME GTP-C Initialized\n"); return true; } +bool mme_gtpc::init_s11() +{ + + socklen_t sock_len; + char mme_addr_name[] = "@mme_s11"; + char spgw_addr_name[] = "@spgw_s11"; + + // Logs + m_mme_gtpc_log->info("Initializing MME S11 interface.\n"); + + // Open Socket + m_s11 = socket(AF_UNIX, SOCK_DGRAM, 0); + if (m_s11 < 0) { + m_mme_gtpc_log->error("Error opening UNIX socket. Error %s\n", strerror(errno)); + return false; + } + + // Set MME Address + memset(&m_mme_addr, 0, sizeof(struct sockaddr_un)); + m_mme_addr.sun_family = AF_UNIX; + strncpy(m_mme_addr.sun_path, mme_addr_name, strlen(mme_addr_name)); + m_mme_addr.sun_path[0] = '\0'; + + // Bind socket to address + if (bind(m_s11, (const struct sockaddr*)&m_mme_addr, sizeof(m_mme_addr)) == -1) { + m_mme_gtpc_log->error("Error binding UNIX socket. Error %s\n", strerror(errno)); + return false; + } + + // Set SPGW Address for later use + memset(&m_spgw_addr, 0, sizeof(struct sockaddr_un)); + m_spgw_addr.sun_family = AF_UNIX; + strncpy(m_spgw_addr.sun_path, spgw_addr_name, strlen(spgw_addr_name)); + m_spgw_addr.sun_path[0] = '\0'; + + m_mme_gtpc_log->info("MME S11 Initialized\n"); + m_mme_gtpc_log->console("MME S11 Initialized\n"); + return true; +} + void mme_gtpc::handle_s11_pdu(srslte::gtpc_pdu *pdu) { m_mme_gtpc_log->debug("MME Received GTP-C PDU. Message type %s\n",srslte::gtpc_msg_type_to_str(pdu->header.type)); diff --git a/srsepc/src/spgw/gtpc.cc b/srsepc/src/spgw/gtpc.cc index b455674c0..c21b751d9 100644 --- a/srsepc/src/spgw/gtpc.cc +++ b/srsepc/src/spgw/gtpc.cc @@ -66,6 +66,13 @@ int spgw::gtpc::init(spgw_args_t* args, spgw* spgw, gtpu_interface_gtpc* gtpu, s m_spgw = spgw; m_gtpu = gtpu; + // Init S11 interface + err = init_s11(args); + if (err != srslte::ERROR_NONE) { + m_gtpc_log->console("Could not initialize the S11 interface.\n"); + return -1; + } + // Init IP pool err = init_ue_ip(args); if (err != srslte::ERROR_NONE) { @@ -90,6 +97,42 @@ void spgw::gtpc::stop() return; } +srslte::error_t spgw::gtpc::init_s11(spgw_args_t* args) +{ + socklen_t sock_len; + char spgw_addr_name[] = "@spgw_s11"; + char mme_addr_name[] = "@mme_s11"; + + // Logs + m_gtpc_log->info("Initializing SPGW S11 interface.\n"); + + // Open Socket + m_s11 = socket(AF_UNIX, SOCK_DGRAM, 0); + if (m_s11 < 0) { + m_gtpc_log->error("Error opening UNIX socket. Error %s\n", strerror(errno)); + return srslte::ERROR_CANT_START; + } + + // Set MME Address + memset(&m_mme_addr, 0, sizeof(struct sockaddr_un)); + m_mme_addr.sun_family = AF_UNIX; + strncpy(m_mme_addr.sun_path, mme_addr_name, strlen(mme_addr_name)); + m_mme_addr.sun_path[0] = '\0'; + + // Set SPGW Address + memset(&m_spgw_addr, 0, sizeof(struct sockaddr_un)); + m_spgw_addr.sun_family = AF_UNIX; + strncpy(m_spgw_addr.sun_path, spgw_addr_name, strlen(spgw_addr_name)); + m_spgw_addr.sun_path[0] = '\0'; + + // Bind socket to address + if (bind(m_s11, (const struct sockaddr*)&m_spgw_addr, sizeof(m_spgw_addr)) == -1) { + m_gtpc_log->error("Error binding UNIX socket. Error %s\n", strerror(errno)); + return srslte::ERROR_CANT_START; + } + return srslte::ERROR_NONE; +} + void spgw::gtpc::handle_s11_pdu(srslte::gtpc_pdu* pdu, srslte::gtpc_pdu* reply_pdu) { m_gtpc_log->console("Received GTP-C PDU. Message type: %s\n", srslte::gtpc_msg_type_to_str(pdu->header.type));