Added initial ability to parse the S1 setup request.

This commit is contained in:
Pedro Alvarez 2017-10-12 21:53:48 +01:00
parent ca212db4c9
commit 41aafbc9c8
6 changed files with 150 additions and 44 deletions

View File

@ -36,6 +36,7 @@
#include <cstddef>
#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;

View File

@ -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;

View File

@ -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}

View File

@ -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 <iostream>
#include <errno.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/sctp.h>
#include <boost/program_options.hpp>
#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 <<endl;
cout << "Flags:" << msg_flags <<endl;
rd_sz = sctp_recvmsg(s1mme, (void*) readbuf, sizeof(readbuf),(struct sockaddr*) &enb_addr, &fromlen, &sri, &msg_flags);
if (rd_sz == -1 && errno != EAGAIN){
cout<< "Error reading from SCTP socket"<<endl;
printf("Error: %s\n", strerror(errno));
return -1;
}
else if (rd_sz == -1 && errno == EAGAIN){
cout << "Timeout reached" << endl;
}
else{
cout<< "Received SCTP msg." << endl;
cout << "\tSize: " << rd_sz <<endl;
cout << "\tMsg: " << readbuf << endl;
}
}
mme->main_loop();
mme->stop();
mme->cleanup();
cout << "--- exiting ---" << endl;

View File

@ -25,6 +25,10 @@
*/
#include <iostream> //TODO Remove
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/sctp.h>
#include <boost/thread/mutex.hpp>
#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

View File

@ -33,6 +33,7 @@
#include <netinet/sctp.h>
#include <unistd.h>
#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" <<std::endl;
m_log_h->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" <<std::endl;
m_log_h->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" <<std::endl;
m_log_h->debug("Received Unsucceseful Outcome PDU\n");
return true;//handle_unsuccessfuloutcome(&rx_pdu.choice.unsuccessfulOutcome);
break;
default:
std::cout << "Unhandled PDU type" <<std::endl;
m_log_h->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" <<std::endl;
//liblte_s1ap_unpack_enbname(&tmp, &msg->eNBname);
std::cout << tmp <<std::endl;
//free(tmp);
//std::cout << msg->Global_ENB_ID.eNB_ID.choice.macroENB_ID.buffer<<std::endl;
//s1ap_log->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