mirror of https://github.com/PentHertz/srsLTE.git
Added a TUN interface for the SGi and a socket to receive packets from the S1-U. Select is able choose the fd that needs to be read from.
This commit is contained in:
parent
796fba6f55
commit
606520d244
|
@ -22,5 +22,5 @@ mnc = 01
|
||||||
mme_bind_addr = 127.0.0.0/24
|
mme_bind_addr = 127.0.0.0/24
|
||||||
|
|
||||||
[spgw]
|
[spgw]
|
||||||
s1u_bind_addr=127.0.0.1
|
gtpu_bind_addr=127.0.0.1
|
||||||
|
sgi_if_addr=172.0.0.1
|
||||||
|
|
|
@ -46,6 +46,7 @@ const uint16_t GTPU_RX_PORT = 2152;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
std::string gtpu_bind_addr;
|
std::string gtpu_bind_addr;
|
||||||
|
std::string sgi_if_addr;
|
||||||
} spgw_args_t;
|
} spgw_args_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,8 @@ parse_args(all_args_t *args, int argc, char* argv[]) {
|
||||||
string mcc;
|
string mcc;
|
||||||
string mnc;
|
string mnc;
|
||||||
string mme_bind_addr;
|
string mme_bind_addr;
|
||||||
|
string spgw_bind_addr;
|
||||||
|
string sgi_if_addr;
|
||||||
|
|
||||||
// Command line only options
|
// Command line only options
|
||||||
bpo::options_description general("General options");
|
bpo::options_description general("General options");
|
||||||
|
@ -90,6 +92,8 @@ parse_args(all_args_t *args, int argc, char* argv[]) {
|
||||||
("mme.mcc", bpo::value<string>(&mcc)->default_value("001"), "Mobile Country Code")
|
("mme.mcc", bpo::value<string>(&mcc)->default_value("001"), "Mobile Country Code")
|
||||||
("mme.mnc", bpo::value<string>(&mnc)->default_value("01"), "Mobile Network Code")
|
("mme.mnc", bpo::value<string>(&mnc)->default_value("01"), "Mobile Network Code")
|
||||||
("mme.mme_bind_addr", bpo::value<string>(&mme_bind_addr)->default_value("127.0.0.1"),"IP address of MME for S1 connnection")
|
("mme.mme_bind_addr", bpo::value<string>(&mme_bind_addr)->default_value("127.0.0.1"),"IP address of MME for S1 connnection")
|
||||||
|
("spgw.gtpu_bind_addr", bpo::value<string>(&spgw_bind_addr)->default_value("127.0.0.1"),"IP address of SP-GW for the S1-U connection")
|
||||||
|
("spgw.sgi_if_addr", bpo::value<string>(&sgi_if_addr)->default_value("176.16.0.1"),"IP address of TUN interface for the SGi connection")
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
@ -162,6 +166,8 @@ parse_args(all_args_t *args, int argc, char* argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
args->mme_args.s1ap_args.mme_bind_addr = mme_bind_addr;
|
args->mme_args.s1ap_args.mme_bind_addr = mme_bind_addr;
|
||||||
|
args->spgw_args.gtpu_bind_addr = spgw_bind_addr;
|
||||||
|
args->spgw_args.sgi_if_addr = sgi_if_addr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
#include <boost/thread/mutex.hpp>
|
#include <boost/thread/mutex.hpp>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
@ -39,6 +40,8 @@ namespace srsepc{
|
||||||
spgw* spgw::m_instance = NULL;
|
spgw* spgw::m_instance = NULL;
|
||||||
boost::mutex spgw_instance_mutex;
|
boost::mutex spgw_instance_mutex;
|
||||||
|
|
||||||
|
const uint16_t SPGW_BUFFER_SIZE = 2500;
|
||||||
|
|
||||||
spgw::spgw():
|
spgw::spgw():
|
||||||
m_running(false),
|
m_running(false),
|
||||||
m_sgi_up(false),
|
m_sgi_up(false),
|
||||||
|
@ -130,10 +133,53 @@ spgw::run_thread()
|
||||||
{
|
{
|
||||||
//Mark the thread as running
|
//Mark the thread as running
|
||||||
m_running=true;
|
m_running=true;
|
||||||
|
srslte::byte_buffer_t *msg;
|
||||||
|
msg = m_pool->allocate();
|
||||||
|
|
||||||
|
struct sockaddr src_addr;
|
||||||
|
socklen_t addrlen;
|
||||||
|
|
||||||
|
int sgi = m_sgi_if;
|
||||||
|
|
||||||
|
fd_set set;
|
||||||
|
//struct timeval to;
|
||||||
|
int max_fd = std::max(m_s1u,sgi);
|
||||||
while (m_running)
|
while (m_running)
|
||||||
{
|
{
|
||||||
sleep(1);
|
msg->reset();
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
m_spgw_log->error("Error from select\n");
|
||||||
}
|
}
|
||||||
|
else if (n)
|
||||||
|
{
|
||||||
|
m_spgw_log->info("Data is available now.\n");
|
||||||
|
if (FD_ISSET(m_s1u, &set))
|
||||||
|
{
|
||||||
|
msg->N_bytes = recvfrom(m_s1u, msg->msg, SRSLTE_MAX_BUFFER_SIZE_BYTES, 0, &src_addr, &addrlen );
|
||||||
|
m_spgw_log->console("Received PDU from S1-U. Bytes %d\n", msg->N_bytes);
|
||||||
|
m_spgw_log->debug("Received PDU from S1-U. Bytes %d\n", msg->N_bytes);
|
||||||
|
}
|
||||||
|
if (FD_ISSET(m_sgi_if, &set))
|
||||||
|
{
|
||||||
|
m_spgw_log->console("Received PDU from SGi\n");
|
||||||
|
msg->N_bytes = read(sgi, msg->msg, SRSLTE_MAX_BUFFER_SIZE_BYTES);
|
||||||
|
m_spgw_log->console("Received PDU from SGi. Bytes %d\n", msg->N_bytes);
|
||||||
|
m_spgw_log->debug("Received PDU from SGi. Bytes %d\n", msg->N_bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_spgw_log->debug("No data from select.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_pool->deallocate(msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,6 +216,7 @@ spgw::init_sgi_if(spgw_args_t *args)
|
||||||
|
|
||||||
// Bring up the interface
|
// Bring up the interface
|
||||||
m_sgi_sock = socket(AF_INET, SOCK_DGRAM, 0);
|
m_sgi_sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
if(ioctl(m_sgi_sock, SIOCGIFFLAGS, &ifr) < 0)
|
if(ioctl(m_sgi_sock, SIOCGIFFLAGS, &ifr) < 0)
|
||||||
{
|
{
|
||||||
m_spgw_log->error("Failed to bring up socket: %s\n", strerror(errno));
|
m_spgw_log->error("Failed to bring up socket: %s\n", strerror(errno));
|
||||||
|
@ -184,6 +231,28 @@ spgw::init_sgi_if(spgw_args_t *args)
|
||||||
return(srslte::ERROR_CANT_START);
|
return(srslte::ERROR_CANT_START);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Set IP of the interface
|
||||||
|
struct sockaddr_in *addr = (struct sockaddr_in*)&ifr.ifr_addr;
|
||||||
|
addr->sin_family = AF_INET;
|
||||||
|
addr->sin_addr.s_addr = inet_addr(args->sgi_if_addr.c_str());
|
||||||
|
addr->sin_port = 0;
|
||||||
|
|
||||||
|
if (ioctl(m_sgi_sock, SIOCSIFADDR, &ifr) < 0) {
|
||||||
|
m_spgw_log->error("Failed to set TUN interface IP. Address: %s, Error: %s\n", args->sgi_if_addr.c_str(), strerror(errno));
|
||||||
|
close(m_sgi_if);
|
||||||
|
close(m_sgi_sock);
|
||||||
|
return srslte::ERROR_CANT_START;
|
||||||
|
}
|
||||||
|
|
||||||
|
ifr.ifr_netmask.sa_family = AF_INET;
|
||||||
|
((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr = inet_addr("255.255.255.0");
|
||||||
|
if (ioctl(m_sgi_sock, SIOCSIFNETMASK, &ifr) < 0) {
|
||||||
|
m_spgw_log->error("Failed to set TUN interface Netmask. Error: %s\n", strerror(errno));
|
||||||
|
close(m_sgi_if);
|
||||||
|
close(m_sgi_sock);
|
||||||
|
return srslte::ERROR_CANT_START;
|
||||||
|
}
|
||||||
|
|
||||||
m_sgi_up = true;
|
m_sgi_up = true;
|
||||||
return(srslte::ERROR_NONE);
|
return(srslte::ERROR_NONE);
|
||||||
}
|
}
|
||||||
|
@ -210,6 +279,7 @@ spgw::init_s1u(spgw_args_t *args)
|
||||||
m_spgw_log->error("Failed to bind socket: %s\n", strerror(errno));
|
m_spgw_log->error("Failed to bind socket: %s\n", strerror(errno));
|
||||||
return srslte::ERROR_CANT_START;
|
return srslte::ERROR_CANT_START;
|
||||||
}
|
}
|
||||||
|
m_spgw_log->info("S1-U socket = %d\n", m_s1u);
|
||||||
return srslte::ERROR_NONE;
|
return srslte::ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue