Fixed Paging and reattachment in new state machine. Moved GW to srsue
This commit is contained in:
parent
826667361e
commit
68b1782c86
|
@ -32,7 +32,7 @@
|
|||
#include "upper/common_enb.h"
|
||||
#include "upper/s1ap_metrics.h"
|
||||
#include "upper/rrc_metrics.h"
|
||||
#include "srslte/upper/gw_metrics.h"
|
||||
#include "../../../../srsue/hdr/upper/gw_metrics.h"
|
||||
#include "srslte/upper/rlc_metrics.h"
|
||||
#include "mac/mac_metrics.h"
|
||||
#include "phy/phy_metrics.h"
|
||||
|
|
|
@ -113,6 +113,13 @@ public:
|
|||
virtual void deattach_request() = 0;
|
||||
};
|
||||
|
||||
// NAS interface for UE
|
||||
class nas_interface_gw
|
||||
{
|
||||
public:
|
||||
virtual void attach_request() = 0;
|
||||
};
|
||||
|
||||
// RRC interface for MAC
|
||||
class rrc_interface_mac_common
|
||||
{
|
||||
|
@ -172,6 +179,7 @@ class pdcp_interface_gw
|
|||
{
|
||||
public:
|
||||
virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0;
|
||||
virtual bool is_drb_enabled(uint32_t lcid) = 0;
|
||||
};
|
||||
|
||||
// PDCP interface for RRC
|
||||
|
|
|
@ -50,6 +50,9 @@ public:
|
|||
uint8_t direction_);
|
||||
void stop();
|
||||
|
||||
// GW interface
|
||||
bool is_drb_enabled(uint32_t lcid);
|
||||
|
||||
// RRC interface
|
||||
void reset();
|
||||
void write_sdu(uint32_t lcid, byte_buffer_t *sdu);
|
||||
|
|
|
@ -65,6 +65,15 @@ void pdcp::reset()
|
|||
/*******************************************************************************
|
||||
RRC/GW interface
|
||||
*******************************************************************************/
|
||||
bool pdcp::is_drb_enabled(uint32_t lcid)
|
||||
{
|
||||
if(lcid >= SRSLTE_N_RADIO_BEARERS) {
|
||||
pdcp_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_RADIO_BEARERS, lcid);
|
||||
return false;
|
||||
}
|
||||
return pdcp_array[lcid].is_active();
|
||||
}
|
||||
|
||||
void pdcp::write_sdu(uint32_t lcid, byte_buffer_t *sdu)
|
||||
{
|
||||
if(valid_lcid(lcid))
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#include "srslte/upper/pdcp.h"
|
||||
#include "upper/rrc.h"
|
||||
#include "upper/nas.h"
|
||||
#include "srslte/upper/gw.h"
|
||||
#include "upper/gw.h"
|
||||
#include "upper/usim.h"
|
||||
|
||||
#include "srslte/common/buffer_pool.h"
|
||||
|
@ -82,9 +82,6 @@ public:
|
|||
|
||||
void pregenerate_signals(bool enable);
|
||||
|
||||
// Testing
|
||||
void test_con_restablishment();
|
||||
|
||||
|
||||
private:
|
||||
virtual ~ue();
|
||||
|
@ -97,7 +94,7 @@ private:
|
|||
srslte::pdcp pdcp;
|
||||
srsue::rrc rrc;
|
||||
srsue::nas nas;
|
||||
srslte::gw gw;
|
||||
srsue::gw gw;
|
||||
srsue::usim usim;
|
||||
|
||||
#ifdef LOG_STDOUT
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "srslte/upper/gw_metrics.h"
|
||||
#include "upper/gw_metrics.h"
|
||||
#include "srslte/upper/rlc_metrics.h"
|
||||
#include "mac/mac_metrics.h"
|
||||
#include "phy/phy_metrics.h"
|
||||
|
@ -48,7 +48,7 @@ typedef struct {
|
|||
phy_metrics_t phy;
|
||||
mac_metrics_t mac;
|
||||
srslte::rlc_metrics_t rlc;
|
||||
srslte::gw_metrics_t gw;
|
||||
gw_metrics_t gw;
|
||||
}ue_metrics_t;
|
||||
|
||||
// UE interface
|
||||
|
|
|
@ -33,39 +33,40 @@
|
|||
#include "srslte/common/msg_queue.h"
|
||||
#include "srslte/interfaces/ue_interfaces.h"
|
||||
#include "srslte/common/threads.h"
|
||||
#include "srslte/upper/gw_metrics.h"
|
||||
#include "gw_metrics.h"
|
||||
|
||||
#include <linux/if.h>
|
||||
|
||||
namespace srslte {
|
||||
namespace srsue {
|
||||
|
||||
class gw
|
||||
:public srsue::gw_interface_pdcp
|
||||
,public srsue::gw_interface_nas
|
||||
:public gw_interface_pdcp
|
||||
,public gw_interface_nas
|
||||
,public thread
|
||||
{
|
||||
public:
|
||||
gw();
|
||||
void init(srsue::pdcp_interface_gw *pdcp_, srsue::ue_interface *ue_, log *gw_log_, uint32_t lcid_);
|
||||
void init(pdcp_interface_gw *pdcp_, nas_interface_gw *nas_, srslte::log *gw_log_, uint32_t lcid_);
|
||||
void stop();
|
||||
|
||||
void get_metrics(gw_metrics_t &m);
|
||||
|
||||
// PDCP interface
|
||||
void write_pdu(uint32_t lcid, byte_buffer_t *pdu);
|
||||
void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu);
|
||||
|
||||
// NAS interface
|
||||
error_t setup_if_addr(uint32_t ip_addr, char *err_str);
|
||||
srslte::error_t setup_if_addr(uint32_t ip_addr, char *err_str);
|
||||
|
||||
private:
|
||||
|
||||
static const int GW_THREAD_PRIO = 7;
|
||||
|
||||
srsue::pdcp_interface_gw *pdcp;
|
||||
srsue::ue_interface *ue;
|
||||
pdcp_interface_gw *pdcp;
|
||||
nas_interface_gw *nas;
|
||||
|
||||
byte_buffer_pool *pool;
|
||||
log *gw_log;
|
||||
srslte::byte_buffer_pool *pool;
|
||||
|
||||
srslte::log *gw_log;
|
||||
bool running;
|
||||
bool run_enable;
|
||||
int32 tun_fd;
|
||||
|
@ -81,7 +82,7 @@ private:
|
|||
struct timeval metrics_time[3];
|
||||
|
||||
void run_thread();
|
||||
error_t init_if(char *err_str);
|
||||
srslte::error_t init_if(char *err_str);
|
||||
};
|
||||
|
||||
} // namespace srsue
|
|
@ -28,7 +28,7 @@
|
|||
#define UE_GW_METRICS_H
|
||||
|
||||
|
||||
namespace srslte {
|
||||
namespace srsue {
|
||||
|
||||
struct gw_metrics_t
|
||||
{
|
|
@ -63,7 +63,10 @@ typedef enum {
|
|||
} plmn_selection_state_t;
|
||||
|
||||
class nas
|
||||
: public nas_interface_rrc, public nas_interface_ue {
|
||||
: public nas_interface_rrc,
|
||||
public nas_interface_ue,
|
||||
public nas_interface_gw
|
||||
{
|
||||
public:
|
||||
nas();
|
||||
void init(usim_interface_nas *usim_,
|
||||
|
@ -106,6 +109,7 @@ private:
|
|||
|
||||
plmn_selection_state_t plmn_selection;
|
||||
LIBLTE_RRC_PLMN_IDENTITY_STRUCT current_plmn;
|
||||
LIBLTE_RRC_PLMN_IDENTITY_STRUCT selecting_plmn;
|
||||
LIBLTE_RRC_PLMN_IDENTITY_STRUCT home_plmn;
|
||||
|
||||
std::vector<LIBLTE_RRC_PLMN_IDENTITY_STRUCT > known_plmns;
|
||||
|
|
|
@ -78,8 +78,6 @@ public:
|
|||
// Timeout callback interface
|
||||
void timer_expired(uint32_t timeout_id);
|
||||
|
||||
void test_con_restablishment();
|
||||
|
||||
void liblte_rrc_log(char *str);
|
||||
|
||||
private:
|
||||
|
@ -130,7 +128,6 @@ private:
|
|||
uint32_t n310_cnt, N310;
|
||||
uint32_t n311_cnt, N311;
|
||||
uint32_t t301, t310, t311;
|
||||
uint32_t safe_reset_timer;
|
||||
int ue_category;
|
||||
|
||||
typedef struct {
|
||||
|
@ -155,6 +152,10 @@ private:
|
|||
} si_acquire_state_t;
|
||||
|
||||
si_acquire_state_t si_acquire_state;
|
||||
void run_si_acquisition_procedure();
|
||||
uint32_t sib_start_tti(uint32_t tti, uint32_t period, uint32_t x);
|
||||
uint32_t nof_sib1_trials;
|
||||
uint32_t last_win_start;
|
||||
|
||||
void select_next_cell_in_plmn();
|
||||
LIBLTE_RRC_PLMN_IDENTITY_STRUCT selected_plmn_id;
|
||||
|
@ -242,12 +243,10 @@ private:
|
|||
void parse_dl_info_transfer(uint32_t lcid, byte_buffer_t *pdu);
|
||||
|
||||
// Helpers
|
||||
void reset_ue();
|
||||
void rrc_connection_release();
|
||||
void radio_link_failure();
|
||||
static void* start_sib_thread(void *rrc_);
|
||||
void sib_search();
|
||||
uint32_t sib_start_tti(uint32_t tti, uint32_t period, uint32_t x);
|
||||
void apply_sib2_configs(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2);
|
||||
void handle_con_setup(LIBLTE_RRC_CONNECTION_SETUP_STRUCT *setup);
|
||||
void handle_con_reest(LIBLTE_RRC_CONNECTION_REESTABLISHMENT_STRUCT *setup);
|
||||
|
|
|
@ -38,14 +38,16 @@ typedef enum {
|
|||
RRC_STATE_CELL_SELECTED,
|
||||
RRC_STATE_CONNECTING,
|
||||
RRC_STATE_CONNECTED,
|
||||
RRC_STATE_LEAVE_CONNECTED,
|
||||
RRC_STATE_N_ITEMS,
|
||||
} rrc_state_t;
|
||||
static const char rrc_state_text[RRC_STATE_N_ITEMS][100] = {"IDLE",
|
||||
"PLMN SELECTION",
|
||||
"CELL SELECTION",
|
||||
"CELL SELECTING",
|
||||
"CELL SELECTED",
|
||||
"CONNECTING",
|
||||
"CONNECTED",
|
||||
"RRC CONNECTED"};
|
||||
"LEAVE CONNECTED"};
|
||||
|
||||
} // namespace srsue
|
||||
|
||||
|
|
|
@ -407,14 +407,18 @@ void phch_recv::set_earfcn(std::vector<uint32_t> earfcn) {
|
|||
}
|
||||
|
||||
bool phch_recv::stop_sync() {
|
||||
Info("SYNC: Going to IDLE\n");
|
||||
phy_state = IDLE;
|
||||
int cnt=0;
|
||||
while(!is_in_idle && cnt<100) {
|
||||
usleep(10000);
|
||||
cnt++;
|
||||
if (phy_state == IDLE && is_in_idle) {
|
||||
return true;
|
||||
} else {
|
||||
Info("SYNC: Going to IDLE\n");
|
||||
phy_state = IDLE;
|
||||
int cnt = 0;
|
||||
while (!is_in_idle && cnt < 100) {
|
||||
usleep(10000);
|
||||
cnt++;
|
||||
}
|
||||
return is_in_idle;
|
||||
}
|
||||
return is_in_idle;
|
||||
}
|
||||
|
||||
void phch_recv::cell_search_inc()
|
||||
|
@ -425,7 +429,6 @@ void phch_recv::cell_search_inc()
|
|||
cur_earfcn_index = 0;
|
||||
}
|
||||
}
|
||||
usleep(100000);
|
||||
Info("SYNC: Cell Search idx %d/%d\n", cur_earfcn_index, earfcn.size());
|
||||
if (current_earfcn != earfcn[cur_earfcn_index]) {
|
||||
current_earfcn = earfcn[cur_earfcn_index];
|
||||
|
@ -627,8 +630,6 @@ void phch_recv::run_thread() {
|
|||
rrc->cell_found(earfcn[cur_earfcn_index], cell, 10*log10(measure_rsrp/1000));
|
||||
break;
|
||||
case 0:
|
||||
log_h->error("SYNC: Getting RSRP cell measurement.\n");
|
||||
cell_search_next();
|
||||
break;
|
||||
default:
|
||||
log_h->error("SYNC: Receiving frorm radio.\n");
|
||||
|
@ -684,6 +685,7 @@ void phch_recv::run_thread() {
|
|||
rrc->in_sync();
|
||||
log_h->debug("SYNC: Sending in-sync to RRC\n");
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
log_h->error("SYNC: Sync error. Sending out-of-sync to RRC\n");
|
||||
// Notify RRC of out-of-sync frame
|
||||
|
@ -692,7 +694,7 @@ void phch_recv::run_thread() {
|
|||
worker_com->reset_ul();
|
||||
break;
|
||||
default:
|
||||
log_h->error("SYNC: Receiving frorm radio.\n");
|
||||
log_h->error("SYNC: Receiving from radio.\n");
|
||||
phy_state = IDLE;
|
||||
radio_h->reset();
|
||||
}
|
||||
|
|
|
@ -298,8 +298,8 @@ int phy::prach_tx_tti()
|
|||
|
||||
void phy::reset()
|
||||
{
|
||||
sf_recv.stop_sync();
|
||||
n_ta = 0;
|
||||
Info("Resetting PHY\n");
|
||||
n_ta = 0;
|
||||
pdcch_dl_search_reset();
|
||||
for(uint32_t i=0;i<nof_workers;i++) {
|
||||
workers[i].reset();
|
||||
|
|
|
@ -167,7 +167,7 @@ bool ue::init(all_args_t *args_)
|
|||
pdcp.init(&rlc, &rrc, &gw, &pdcp_log, 0 /* RB_ID_SRB0 */, SECURITY_DIRECTION_UPLINK);
|
||||
|
||||
nas.init(&usim, &rrc, &gw, &nas_log, 1 /* RB_ID_SRB1 */);
|
||||
gw.init(&pdcp, this, &gw_log, 3 /* RB_ID_DRB1 */);
|
||||
gw.init(&pdcp, &nas, &gw_log, 3 /* RB_ID_DRB1 */);
|
||||
|
||||
usim.init(&args->usim, &usim_log);
|
||||
|
||||
|
@ -195,10 +195,6 @@ void ue::pregenerate_signals(bool enable)
|
|||
phy.enable_pregen_signals(enable);
|
||||
}
|
||||
|
||||
void ue::test_con_restablishment() {
|
||||
rrc.test_con_restablishment();
|
||||
}
|
||||
|
||||
void ue::stop()
|
||||
{
|
||||
if(started)
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "srslte/upper/gw.h"
|
||||
#include "../../hdr/upper/gw.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
@ -38,7 +38,7 @@
|
|||
#include <sys/socket.h>
|
||||
|
||||
|
||||
namespace srslte {
|
||||
namespace srsue {
|
||||
|
||||
gw::gw()
|
||||
:if_up(false)
|
||||
|
@ -46,11 +46,11 @@ gw::gw()
|
|||
current_ip_addr = 0;
|
||||
}
|
||||
|
||||
void gw::init(srsue::pdcp_interface_gw *pdcp_, srsue::ue_interface *ue_, log *gw_log_, uint32_t lcid_)
|
||||
void gw::init(pdcp_interface_gw *pdcp_, nas_interface_gw *nas_, srslte::log *gw_log_, uint32_t lcid_)
|
||||
{
|
||||
pool = byte_buffer_pool::get_instance();
|
||||
pool = srslte::byte_buffer_pool::get_instance();
|
||||
pdcp = pdcp_;
|
||||
ue = ue_;
|
||||
nas = nas_;
|
||||
gw_log = gw_log_;
|
||||
lcid = lcid_;
|
||||
run_enable = true;
|
||||
|
@ -107,7 +107,7 @@ void gw::get_metrics(gw_metrics_t &m)
|
|||
/*******************************************************************************
|
||||
PDCP interface
|
||||
*******************************************************************************/
|
||||
void gw::write_pdu(uint32_t lcid, byte_buffer_t *pdu)
|
||||
void gw::write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu)
|
||||
{
|
||||
gw_log->info_hex(pdu->msg, pdu->N_bytes, "RX PDU");
|
||||
gw_log->info("RX PDU. Stack latency: %ld us\n", pdu->get_latency_us());
|
||||
|
@ -128,7 +128,7 @@ void gw::write_pdu(uint32_t lcid, byte_buffer_t *pdu)
|
|||
/*******************************************************************************
|
||||
NAS interface
|
||||
*******************************************************************************/
|
||||
error_t gw::setup_if_addr(uint32_t ip_addr, char *err_str)
|
||||
srslte::error_t gw::setup_if_addr(uint32_t ip_addr, char *err_str)
|
||||
{
|
||||
if (ip_addr != current_ip_addr) {
|
||||
if(!if_up)
|
||||
|
@ -136,7 +136,7 @@ error_t gw::setup_if_addr(uint32_t ip_addr, char *err_str)
|
|||
if(init_if(err_str))
|
||||
{
|
||||
gw_log->error("init_if failed\n");
|
||||
return(ERROR_CANT_START);
|
||||
return(srslte::ERROR_CANT_START);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,7 +149,7 @@ error_t gw::setup_if_addr(uint32_t ip_addr, char *err_str)
|
|||
err_str = strerror(errno);
|
||||
gw_log->debug("Failed to set socket address: %s\n", err_str);
|
||||
close(tun_fd);
|
||||
return(ERROR_CANT_START);
|
||||
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");
|
||||
|
@ -158,7 +158,7 @@ error_t gw::setup_if_addr(uint32_t ip_addr, char *err_str)
|
|||
err_str = strerror(errno);
|
||||
gw_log->debug("Failed to set socket netmask: %s\n", err_str);
|
||||
close(tun_fd);
|
||||
return(ERROR_CANT_START);
|
||||
return(srslte::ERROR_CANT_START);
|
||||
}
|
||||
|
||||
current_ip_addr = ip_addr;
|
||||
|
@ -167,59 +167,59 @@ error_t gw::setup_if_addr(uint32_t ip_addr, char *err_str)
|
|||
start(GW_THREAD_PRIO);
|
||||
}
|
||||
|
||||
return(ERROR_NONE);
|
||||
return(srslte::ERROR_NONE);
|
||||
}
|
||||
|
||||
error_t gw::init_if(char *err_str)
|
||||
srslte::error_t gw::init_if(char *err_str)
|
||||
{
|
||||
if(if_up)
|
||||
{
|
||||
return(ERROR_ALREADY_STARTED);
|
||||
}
|
||||
if(if_up)
|
||||
{
|
||||
return(srslte::ERROR_ALREADY_STARTED);
|
||||
}
|
||||
|
||||
char dev[IFNAMSIZ] = "tun_srsue";
|
||||
char dev[IFNAMSIZ] = "tun_srsue";
|
||||
|
||||
// Construct the TUN device
|
||||
tun_fd = open("/dev/net/tun", O_RDWR);
|
||||
gw_log->info("TUN file descriptor = %d\n", tun_fd);
|
||||
if(0 > tun_fd)
|
||||
{
|
||||
err_str = strerror(errno);
|
||||
gw_log->debug("Failed to open TUN device: %s\n", err_str);
|
||||
return(ERROR_CANT_START);
|
||||
}
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
|
||||
strncpy(ifr.ifr_ifrn.ifrn_name, dev, IFNAMSIZ);
|
||||
if(0 > ioctl(tun_fd, TUNSETIFF, &ifr))
|
||||
{
|
||||
err_str = strerror(errno);
|
||||
gw_log->debug("Failed to set TUN device name: %s\n", err_str);
|
||||
close(tun_fd);
|
||||
return(ERROR_CANT_START);
|
||||
}
|
||||
// Construct the TUN device
|
||||
tun_fd = open("/dev/net/tun", O_RDWR);
|
||||
gw_log->info("TUN file descriptor = %d\n", tun_fd);
|
||||
if(0 > tun_fd)
|
||||
{
|
||||
err_str = strerror(errno);
|
||||
gw_log->debug("Failed to open TUN device: %s\n", err_str);
|
||||
return(srslte::ERROR_CANT_START);
|
||||
}
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
|
||||
strncpy(ifr.ifr_ifrn.ifrn_name, dev, IFNAMSIZ);
|
||||
if(0 > ioctl(tun_fd, TUNSETIFF, &ifr))
|
||||
{
|
||||
err_str = strerror(errno);
|
||||
gw_log->debug("Failed to set TUN device name: %s\n", err_str);
|
||||
close(tun_fd);
|
||||
return(srslte::ERROR_CANT_START);
|
||||
}
|
||||
|
||||
// Bring up the interface
|
||||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if(0 > ioctl(sock, SIOCGIFFLAGS, &ifr))
|
||||
{
|
||||
err_str = strerror(errno);
|
||||
gw_log->debug("Failed to bring up socket: %s\n", err_str);
|
||||
close(tun_fd);
|
||||
return(ERROR_CANT_START);
|
||||
}
|
||||
ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
|
||||
if(0 > ioctl(sock, SIOCSIFFLAGS, &ifr))
|
||||
{
|
||||
err_str = strerror(errno);
|
||||
gw_log->debug("Failed to set socket flags: %s\n", err_str);
|
||||
close(tun_fd);
|
||||
return(ERROR_CANT_START);
|
||||
}
|
||||
// Bring up the interface
|
||||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if(0 > ioctl(sock, SIOCGIFFLAGS, &ifr))
|
||||
{
|
||||
err_str = strerror(errno);
|
||||
gw_log->debug("Failed to bring up socket: %s\n", err_str);
|
||||
close(tun_fd);
|
||||
return(srslte::ERROR_CANT_START);
|
||||
}
|
||||
ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
|
||||
if(0 > ioctl(sock, SIOCSIFFLAGS, &ifr))
|
||||
{
|
||||
err_str = strerror(errno);
|
||||
gw_log->debug("Failed to set socket flags: %s\n", err_str);
|
||||
close(tun_fd);
|
||||
return(srslte::ERROR_CANT_START);
|
||||
}
|
||||
|
||||
if_up = true;
|
||||
if_up = true;
|
||||
|
||||
return(ERROR_NONE);
|
||||
return(srslte::ERROR_NONE);
|
||||
}
|
||||
|
||||
/********************/
|
||||
|
@ -227,65 +227,81 @@ error_t gw::init_if(char *err_str)
|
|||
/********************/
|
||||
void gw::run_thread()
|
||||
{
|
||||
struct iphdr *ip_pkt;
|
||||
uint32 idx = 0;
|
||||
int32 N_bytes;
|
||||
byte_buffer_t *pdu = pool_allocate;
|
||||
struct iphdr *ip_pkt;
|
||||
uint32 idx = 0;
|
||||
int32 N_bytes;
|
||||
srslte::byte_buffer_t *pdu = pool_allocate;
|
||||
|
||||
gw_log->info("GW IP packet receiver thread run_enable\n");
|
||||
const static uint32_t ATTACH_TIMEOUT_MS = 2000;
|
||||
uint32_t attach_cnt = 0;
|
||||
|
||||
running = true;
|
||||
while(run_enable)
|
||||
{
|
||||
if (SRSLTE_MAX_BUFFER_SIZE_BYTES-SRSLTE_BUFFER_HEADER_OFFSET > idx) {
|
||||
N_bytes = read(tun_fd, &pdu->msg[idx], SRSLTE_MAX_BUFFER_SIZE_BYTES-SRSLTE_BUFFER_HEADER_OFFSET - idx);
|
||||
} else {
|
||||
gw_log->error("GW pdu buffer full - gw receive thread exiting.\n");
|
||||
gw_log->console("GW pdu buffer full - gw receive thread exiting.\n");
|
||||
break;
|
||||
}
|
||||
gw_log->debug("Read %d bytes from TUN fd=%d, idx=%d\n", N_bytes, tun_fd, idx);
|
||||
if(N_bytes > 0)
|
||||
{
|
||||
pdu->N_bytes = idx + N_bytes;
|
||||
ip_pkt = (struct iphdr*)pdu->msg;
|
||||
gw_log->info("GW IP packet receiver thread run_enable\n");
|
||||
|
||||
// Warning: Accept only IPv4 packets
|
||||
if (ip_pkt->version == 4) {
|
||||
// Check if entire packet was received
|
||||
if(ntohs(ip_pkt->tot_len) == pdu->N_bytes)
|
||||
{
|
||||
gw_log->info_hex(pdu->msg, pdu->N_bytes, "TX PDU");
|
||||
|
||||
if (!run_enable) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Send PDU directly to PDCP
|
||||
pdu->set_timestamp();
|
||||
ul_tput_bytes += pdu->N_bytes;
|
||||
pdcp->write_sdu(lcid, pdu);
|
||||
|
||||
do {
|
||||
pdu = pool_allocate;
|
||||
if (!pdu) {
|
||||
printf("Not enough buffers in pool\n");
|
||||
usleep(100000);
|
||||
}
|
||||
} while(!pdu);
|
||||
idx = 0;
|
||||
}else{
|
||||
idx += N_bytes;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
gw_log->error("Failed to read from TUN interface - gw receive thread exiting.\n");
|
||||
gw_log->console("Failed to read from TUN interface - gw receive thread exiting.\n");
|
||||
break;
|
||||
}
|
||||
running = true;
|
||||
while(run_enable)
|
||||
{
|
||||
if (SRSLTE_MAX_BUFFER_SIZE_BYTES-SRSLTE_BUFFER_HEADER_OFFSET > idx) {
|
||||
N_bytes = read(tun_fd, &pdu->msg[idx], SRSLTE_MAX_BUFFER_SIZE_BYTES-SRSLTE_BUFFER_HEADER_OFFSET - idx);
|
||||
} else {
|
||||
gw_log->error("GW pdu buffer full - gw receive thread exiting.\n");
|
||||
gw_log->console("GW pdu buffer full - gw receive thread exiting.\n");
|
||||
break;
|
||||
}
|
||||
running = false;
|
||||
gw_log->info("GW IP receiver thread exiting.\n");
|
||||
gw_log->debug("Read %d bytes from TUN fd=%d, idx=%d\n", N_bytes, tun_fd, idx);
|
||||
if(N_bytes > 0)
|
||||
{
|
||||
pdu->N_bytes = idx + N_bytes;
|
||||
ip_pkt = (struct iphdr*)pdu->msg;
|
||||
|
||||
// Warning: Accept only IPv4 packets
|
||||
if (ip_pkt->version == 4) {
|
||||
// Check if entire packet was received
|
||||
if(ntohs(ip_pkt->tot_len) == pdu->N_bytes)
|
||||
{
|
||||
gw_log->info_hex(pdu->msg, pdu->N_bytes, "TX PDU");
|
||||
|
||||
while(run_enable && !pdcp->is_drb_enabled(lcid)) {
|
||||
if (attach_cnt == 0) {
|
||||
gw_log->info("LCID=%d not active, requesting NAS attach\n", lcid);
|
||||
nas->attach_request();
|
||||
}
|
||||
attach_cnt++;
|
||||
if (attach_cnt == ATTACH_TIMEOUT_MS) {
|
||||
attach_cnt = 0;
|
||||
}
|
||||
usleep(1000);
|
||||
}
|
||||
attach_cnt = 0;
|
||||
|
||||
if (!run_enable) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Send PDU directly to PDCP
|
||||
pdu->set_timestamp();
|
||||
ul_tput_bytes += pdu->N_bytes;
|
||||
pdcp->write_sdu(lcid, pdu);
|
||||
|
||||
do {
|
||||
pdu = pool_allocate;
|
||||
if (!pdu) {
|
||||
printf("Not enough buffers in pool\n");
|
||||
usleep(100000);
|
||||
}
|
||||
} while(!pdu);
|
||||
idx = 0;
|
||||
}else{
|
||||
idx += N_bytes;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
gw_log->error("Failed to read from TUN interface - gw receive thread exiting.\n");
|
||||
gw_log->console("Failed to read from TUN interface - gw receive thread exiting.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
running = false;
|
||||
gw_log->info("GW IP receiver thread exiting.\n");
|
||||
}
|
||||
|
||||
} // namespace srsue
|
|
@ -74,7 +74,12 @@ void nas::attach_request() {
|
|||
} else if (plmn_selection == PLMN_SELECTED) {
|
||||
nas_log->info("Selecting PLMN %s\n", plmn_id_to_c_str(current_plmn).c_str());
|
||||
rrc->plmn_select(current_plmn);
|
||||
selecting_plmn = current_plmn;
|
||||
}
|
||||
} else if (state == EMM_STATE_REGISTERED) {
|
||||
nas_log->info("NAS state is registered, connecting to same PLMN\n");
|
||||
rrc->plmn_select(current_plmn);
|
||||
selecting_plmn = current_plmn;
|
||||
} else {
|
||||
nas_log->info("Attach request ignored. State = %s\n", emm_state_text[state]);
|
||||
}
|
||||
|
@ -97,6 +102,7 @@ void nas::plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_
|
|||
nas_log->info("Detected known PLMN %s\n", plmn_id_to_c_str(plmn_id).c_str());
|
||||
if (plmn_id.mcc == home_plmn.mcc && plmn_id.mnc == home_plmn.mnc) {
|
||||
rrc->plmn_select(plmn_id);
|
||||
selecting_plmn = plmn_id;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -107,6 +113,7 @@ void nas::plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_
|
|||
tracking_area_code);
|
||||
if (plmn_id.mcc == home_plmn.mcc && plmn_id.mnc == home_plmn.mnc) {
|
||||
rrc->plmn_select(plmn_id);
|
||||
selecting_plmn = plmn_id;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -317,6 +324,7 @@ void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) {
|
|||
// FIXME: Setup the default EPS bearer context
|
||||
|
||||
state = EMM_STATE_REGISTERED;
|
||||
current_plmn = selecting_plmn;
|
||||
|
||||
// Send EPS bearer context accept and attach complete
|
||||
count_ul++;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue