From 41aafbc9c8fc5e3f04d8e4775ef3aeb4977b17d0 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 12 Oct 2017 21:53:48 +0100 Subject: [PATCH] Added initial ability to parse the S1 setup request. --- srsepc/hdr/mme/mme.h | 5 +++ srsepc/hdr/mme/s1ap.h | 7 +++ srsepc/src/CMakeLists.txt | 1 + srsepc/src/main.cc | 45 +------------------ srsepc/src/mme/mme.cc | 44 ++++++++++++++++++- srsepc/src/mme/s1ap.cc | 92 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 150 insertions(+), 44 deletions(-) diff --git a/srsepc/hdr/mme/mme.h b/srsepc/hdr/mme/mme.h index 3749eef2f..40ede136b 100644 --- a/srsepc/hdr/mme/mme.h +++ b/srsepc/hdr/mme/mme.h @@ -36,6 +36,7 @@ #include #include "srslte/common/logger_file.h" #include "srslte/common/log_filter.h" +#include "srslte/common/buffer_pool.h" #include "s1ap.h" @@ -67,6 +68,8 @@ public: void stop(); int get_s1_mme(); + + void main_loop(); private: @@ -75,6 +78,8 @@ private: static mme *m_instance; s1ap m_s1ap; + srslte::byte_buffer_pool *m_pool; + /*Logs*/ srslte::logger_stdout m_logger_stdout; srslte::logger_file m_logger_file; diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index 8388083ff..46c495f6f 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -23,6 +23,7 @@ * and at http://www.gnu.org/licenses/. * */ +#include "srslte/asn1/liblte_s1ap.h" #include "srslte/common/log.h" namespace srsepc{ @@ -50,6 +51,12 @@ public: int get_s1_mme(); + bool handle_s1ap_rx_pdu(srslte::byte_buffer_t *pdu); + + bool handle_initiatingmessage(LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *msg); + + bool handle_s1setuprequest(LIBLTE_S1AP_MESSAGE_S1SETUPREQUEST_STRUCT *msg); + private: uint8_t m_mme_code; uint16_t m_mme_group; diff --git a/srsepc/src/CMakeLists.txt b/srsepc/src/CMakeLists.txt index 11985c134..fec7cd557 100644 --- a/srsepc/src/CMakeLists.txt +++ b/srsepc/src/CMakeLists.txt @@ -14,6 +14,7 @@ endif (RPATH) add_executable(srsepc main.cc ) target_link_libraries(srsepc srsepc_mme + srslte_upper srslte_common ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index 42759749f..3d4bb6949 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -2,8 +2,6 @@ * * \section COPYRIGHT * - * Copyright 2013-2017 Software Radio Systems Limited - * * \section LICENSE * * This file is part of srsLTE. @@ -26,10 +24,6 @@ #include #include #include -#include -#include -#include -#include #include #include "srslte/common/bcd_helpers.h" #include "mme/mme.h" @@ -145,21 +139,7 @@ main (int argc,char * argv[] ) all_args_t args; parse_args(&args, argc, argv); - //TODO these should be passed from config files - //args.s1ap_args.mme_code = 0x01; - //args.s1ap_args.mme_group = 0x0001; - //args.s1ap_args.tac = 0x0001; - //args.s1ap_args.mcc = 0x01; - //args.s1ap_args.mnc = 0x01; - //args.s1ap_args.mme_bindx_addr="127.0.0.0/24"; - args.log_args.filename = std::string("/tmp/epc.log"); - struct sockaddr_in enb_addr; - char readbuf[1000]; - struct sctp_sndrcvinfo sri; - socklen_t fromlen; - int rd_sz; - int msg_flags=0; mme *mme = mme::get_instance(); if (mme->init(&args)) { @@ -167,29 +147,8 @@ main (int argc,char * argv[] ) exit(1); } - //Initalize S1-MME scoket - int s1mme = mme->get_s1_mme(); - cout << "Socket: " << s1mme; - while(running) - { - cout << "Waiting for SCTP Msg on: " << s1mme << endl; - //cout << "Sri:" << sri <main_loop(); + mme->stop(); mme->cleanup(); cout << "--- exiting ---" << endl; diff --git a/srsepc/src/mme/mme.cc b/srsepc/src/mme/mme.cc index 291077868..d6f8b4359 100644 --- a/srsepc/src/mme/mme.cc +++ b/srsepc/src/mme/mme.cc @@ -25,6 +25,10 @@ */ #include //TODO Remove +#include +#include +#include +#include #include #include "mme/mme.h" @@ -35,7 +39,8 @@ boost::mutex mme_instance_mutex; mme::mme() { - return; + m_pool = srslte::byte_buffer_pool::get_instance(); + return; } mme::~mme() @@ -97,4 +102,41 @@ mme::get_s1_mme() return m_s1ap.get_s1_mme(); } +void +mme::main_loop() +{ + srslte::byte_buffer_t *pdu = m_pool->allocate(); + uint32_t sz = SRSLTE_MAX_BUFFER_SIZE_BYTES - SRSLTE_BUFFER_HEADER_OFFSET; + + struct sockaddr_in enb_addr; + struct sctp_sndrcvinfo sri; + socklen_t fromlen = sizeof(enb_addr); + bzero(&enb_addr, sizeof(enb_addr)); + int rd_sz; + int msg_flags=0; + + //Get S1-MME socket + int s1mme = m_s1ap.get_s1_mme(); + while(true) + { + std::cout << "Waiting for SCTP Msg " << std::endl; + pdu->reset(); + rd_sz = sctp_recvmsg(s1mme, pdu->msg, sz,(struct sockaddr*) &enb_addr, &fromlen, &sri, &msg_flags); + if (rd_sz == -1 && errno != EAGAIN){ + std::cout<< "Error reading from SCTP socket" << std::endl; + printf("Error: %s\n", strerror(errno)); + } + else if (rd_sz == -1 && errno == EAGAIN){ + std::cout << "Timeout reached" << std::endl; + } + else{ + pdu->N_bytes = rd_sz; + std::cout<< "Received SCTP msg." << std::endl; + std::cout << "\tSize: " << pdu->N_bytes << std::endl; + std::cout << "\tMsg: " << pdu->msg << std::endl; + m_s1ap.handle_s1ap_rx_pdu(pdu); + } + } +} + } //namespace srsepc diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index bbf36180e..495f1ca02 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -33,6 +33,7 @@ #include #include +#include "srslte/common/common.h" #include "mme/s1ap.h" namespace srsepc{ @@ -60,6 +61,7 @@ s1ap::init(s1ap_args_t s1ap_args, srslte::log *s1ap_log) m_log_h = s1ap_log; m_s1mme = enb_listen(); + return 0; } @@ -131,5 +133,95 @@ s1ap::enb_listen() return sock_fd; } +bool +s1ap::handle_s1ap_rx_pdu(srslte::byte_buffer_t *pdu) //TODO As it is, this function is exactly the same as srsenb::handle_s1ap_rx_pdu. Refactoring is needed. +{ + LIBLTE_S1AP_S1AP_PDU_STRUCT rx_pdu; + + if(liblte_s1ap_unpack_s1ap_pdu((LIBLTE_BYTE_MSG_STRUCT*)pdu, &rx_pdu) != LIBLTE_SUCCESS) { + std::cout << "Failed to Unpack PDU" << std::endl; + m_log_h->error("Failed to unpack received PDU\n"); + return false; + } + + switch(rx_pdu.choice_type) { + case LIBLTE_S1AP_S1AP_PDU_CHOICE_INITIATINGMESSAGE: + std::cout << "Received initiating PDU" <debug("Received initiating PDU\n"); + return handle_initiatingmessage(&rx_pdu.choice.initiatingMessage); + break; + case LIBLTE_S1AP_S1AP_PDU_CHOICE_SUCCESSFULOUTCOME: + std::cout << "Received Successful PDU" <debug("Received Succeseful Outcome PDU\n"); + return true;//handle_successfuloutcome(&rx_pdu.choice.successfulOutcome); + break; + case LIBLTE_S1AP_S1AP_PDU_CHOICE_UNSUCCESSFULOUTCOME: + std::cout << "Received Unsuccesfull PDU" <debug("Received Unsucceseful Outcome PDU\n"); + return true;//handle_unsuccessfuloutcome(&rx_pdu.choice.unsuccessfulOutcome); + break; + default: + std::cout << "Unhandled PDU type" <error("Unhandled PDU type %d\n", rx_pdu.choice_type); + return false; + } + + return true; + +} + +bool +s1ap::handle_initiatingmessage(LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *msg) +{ + switch(msg->choice_type) { + case LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_S1SETUPREQUEST: + std::cout << "Received S1 Setup Request." << std::endl; + return handle_s1setuprequest(&msg->choice.S1SetupRequest); + default: + std::cout << "Unhandled intiating message" << std::cout; + //s1ap_log->error("Unhandled intiating message: %s\n", liblte_s1ap_initiatingmessage_choice_text[msg->choice_type]); + } + return true; +} + +bool +s1ap::handle_s1setuprequest(LIBLTE_S1AP_MESSAGE_S1SETUPREQUEST_STRUCT *msg) +{ + + uint8_t tmp[150]; + bzero(tmp,sizeof(tmp)); + memcpy(tmp,&msg->eNBname.buffer,msg->eNBname.n_octets); + std::cout <<"Wazuup" <eNBname); + std::cout << tmp <Global_ENB_ID.eNB_ID.choice.macroENB_ID.buffer<info("Received DownlinkNASTransport\n"); + /* + if(msg->ext) { + s1ap_log->warning("Not handling S1AP message extension\n"); + } + if(enbid_to_rnti_map.end() == enbid_to_rnti_map.find(msg->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID)) { + s1ap_log->warning("eNB_UE_S1AP_ID not found - discarding message\n"); + return false; + } + uint16_t rnti = enbid_to_rnti_map[msg->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID]; + ue_ctxt_map[rnti].MME_UE_S1AP_ID = msg->MME_UE_S1AP_ID.MME_UE_S1AP_ID; + + if(msg->HandoverRestrictionList_present) { + s1ap_log->warning("Not handling HandoverRestrictionList\n"); + } + if(msg->SubscriberProfileIDforRFP_present) { + s1ap_log->warning("Not handling SubscriberProfileIDforRFP\n"); + } + + srslte::byte_buffer_t *pdu = pool_allocate; + memcpy(pdu->msg, msg->NAS_PDU.buffer, msg->NAS_PDU.n_octets); + pdu->N_bytes = msg->NAS_PDU.n_octets; + rrc->write_dl_info(rnti, pdu); + */ + return true; +} + }//namespace srsepc