Commit 792fa7db authored by Ben Wojtowicz's avatar Ben Wojtowicz

Version 0.20.0: Increased the maximum messages size, fixed extended power...

Version 0.20.0: Increased the maximum messages size, fixed extended power headroom MAC CE, added classmark3 support, added tracking area update request support, fixed the fill bits in packing mobile ID IE for IMEISV and the length in unpacking UE security capabilities IE (thanks to Przemek Bereski for finding this), allowing NULL to be passed for key_256 in service reject message packing (thanks to Przemek Bereski and Peter Nguyen for finding this), added PDCCH size defines, added an error return to DCI 1C unpack, clearing punctered turbo decode bits before decoding, added AMD PDU segment support, padded all RRC enums to powers of 2, added support for several RRC IEs and messages (with the help of Przemek Bereski) in the LTE library, restructured the radio classes to ease the addition of new radio types, set the processor affinity to allow the PHY/Radio to run on a particular core, fixed memcpy lengths in MAC, fixed bugs in print_all_users (thanks to Sultan Qasim Khan for finding this) and when receiving a service request message for a non-existent user (thanks to Peter Nguyen for finding this), fixed a long standing PHY bug that was including UL PDCCH allocations in a check of DL PRB usage, added error logging for received AMD PDU segments, increased the DL datarate for default data QoS, using C-RNTI when no IMSI/IMEI are available for printing an attached user, Przemek Bereski added UE capability enquiry and UE capability information support and bladeRF support.
parent 43575fde
Ben Wojtowicz, bwojtowi@gmail.com
Andrew Murphy, andrew.murphy@rd.bbc.co.uk
Ziming He, ziminghe83@gmail.com
Przemek Bereski, przemobe@users.sourceforge.net
......@@ -23,7 +23,7 @@
########################################################################
cmake_minimum_required(VERSION 2.6)
project(openLTE CXX C)
set(openLTE_version 0.19.4)
set(openLTE_version 0.20.0)
enable_testing()
#select the release build type by default to get optimization flags
......@@ -92,6 +92,7 @@ set(GR_REQUIRED_COMPONENTS RUNTIME BLOCKS FILTER PMT)
find_package(Gnuradio "3.7.0")
find_package(GnuradioOsmosdr)
find_package(Uhd)
find_package(LibbladeRF)
find_package(FFTW3F)
find_package(Polarssl)
......@@ -107,6 +108,10 @@ if(NOT UHD_FOUND)
message(FATAL_ERROR "UHD required to compile openLTE (http://code.ettus.com/redmine/ettus/projects/uhd/wiki)")
endif()
if(NOT LIBBLADERF_FOUND)
message(FATAL_ERROR "LibbladeRF required to compile openLTE")
endif()
if(NOT FFTW3F_FOUND)
message(FATAL_ERROR "FFTW3 required to compile openLTE")
endif()
......
......@@ -226,3 +226,24 @@ v00.19.03 Added support for PUCCH decode in liblte, added support for H-ARQ
PUCCH in LTE_fdd_enodeb, and fixed a bug related to improper cleanup
of the inactivity timer in LTE_fdd_enodeb
v00.19.04 Fixed the calculation of n_prime_p in generate_dmrs_pucch.
v00.20.00 Increased the maximum messages size, fixed extended power headroom MAC
CE, added classmark3 support, added tracking area update request support,
fixed the fill bits in packing mobile ID IE for IMEISV and the length in
unpacking UE security capabilities IE (thanks to Przemek Bereski for
finding this), allowing NULL to be passed for key_256 in service reject
message packing (thanks to Przemek Bereski and Peter Nguyen for finding
this), added PDCCH size defines, added an error return to DCI 1C unpack,
clearing punctered turbo decode bits before decoding, added AMD PDU
segment support, padded all RRC enums to powers of 2, added support for
several RRC IEs and messages (with the help of Przemek Bereski) in the
LTE library, restructured the radio classes to ease the addition of new
radio types, set the processor affinity to allow the PHY/Radio to run
on a particular core, fixed memcpy lengths in MAC, fixed bugs in
print_all_users (thanks to Sultan Qasim Khan for finding this) and when
receiving a service request message for a non-existent user (thanks to
Peter Nguyen for finding this), fixed a long standing PHY bug that was
including UL PDCCH allocations in a check of DL PRB usage, added error
logging for received AMD PDU segments, increased the DL datarate for
default data QoS, using C-RNTI when no IMSI/IMEI are available for
printing an attached user, Przemek Bereski added UE capability enquiry
and UE capability information support and bladeRF support.
......@@ -24,7 +24,7 @@ add_executable(LTE_fdd_enodeb
src/LTE_fdd_enb_mme.cc
src/LTE_fdd_enb_gw.cc
)
target_link_libraries(LTE_fdd_enodeb lte fftw3f tools pthread rt ${POLARSSL_LIBRARIES} ${UHD_LIBRARIES} ${Boost_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES} ${GNURADIO_PMT_LIBRARIES})
target_link_libraries(LTE_fdd_enodeb lte fftw3f tools pthread rt ${POLARSSL_LIBRARIES} ${UHD_LIBRARIES} ${LIBBLADERF_LIBRARIES} ${Boost_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES} ${GNURADIO_PMT_LIBRARIES})
install(TARGETS LTE_fdd_enodeb DESTINATION bin)
install(CODE "execute_process(COMMAND chmod +x \"${CMAKE_SOURCE_DIR}/enodeb_nat_script.sh\")")
install(CODE "execute_process(COMMAND \"${CMAKE_SOURCE_DIR}/enodeb_nat_script.sh\")")
/*******************************************************************************
Copyright 2013-2015 Ben Wojtowicz
Copyright 2013-2016 Ben Wojtowicz
Copyright 2016 Przemek Bereski (bladeRF support)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
......@@ -33,6 +34,9 @@
07/25/2015 Ben Wojtowicz Added parameters to abstract PHY sample rate
from radio sample rate.
12/06/2015 Ben Wojtowicz Changed boost::mutex to sem_t.
07/03/2016 Ben Wojtowicz Massive restructuring to support the addition
of bladeRF as a radio choice.
07/03/2016 Przemek Bereski Addition of bladeRF as a radio choice.
*******************************************************************************/
......@@ -47,6 +51,7 @@
#include "liblte_phy.h"
#include <gnuradio/gr_complex.h>
#include <uhd/usrp/multi_usrp.hpp>
#include <libbladeRF.h>
/*******************************************************************************
DEFINES
......@@ -62,8 +67,15 @@
TYPEDEFS
*******************************************************************************/
typedef enum{
LTE_FDD_ENB_RADIO_TYPE_NO_RF = 0,
LTE_FDD_ENB_RADIO_TYPE_USRP_B2X0,
LTE_FDD_ENB_RADIO_TYPE_BLADERF,
}LTE_FDD_ENB_RADIO_TYPE_ENUM;
typedef struct{
std::string name;
std::string name;
LTE_FDD_ENB_RADIO_TYPE_ENUM type;
}LTE_FDD_ENB_RADIO_STRUCT;
typedef struct{
......@@ -85,10 +97,107 @@ typedef struct{
uint16 current_tti;
}LTE_FDD_ENB_RADIO_RX_BUF_STRUCT;
class LTE_fdd_enb_phy;
typedef struct{
LTE_fdd_enb_interface *interface;
LTE_fdd_enb_phy *phy;
LTE_FDD_ENB_RADIO_TX_BUF_STRUCT tx_radio_buf[2];
LTE_FDD_ENB_RADIO_RX_BUF_STRUCT rx_radio_buf[2];
uint32 N_subfrs_dropped;
uint32 samp_rate;
uint32 buf_idx;
uint32 recv_idx;
uint32 samp_idx;
uint32 num_samps;
uint32 N_samps_per_subfr;
uint32 fs;
uint16 rx_current_tti;
uint8 N_ant;
bool init_needed;
bool rx_synced;
}LTE_FDD_ENB_RADIO_PARAMS_STRUCT;
/*******************************************************************************
CLASS DECLARATIONS
*******************************************************************************/
class LTE_fdd_enb_radio_no_rf
{
public:
// Constructor/Destructor
LTE_fdd_enb_radio_no_rf();
~LTE_fdd_enb_radio_no_rf();
// Radio functions
LTE_FDD_ENB_ERROR_ENUM setup(void);
void teardown(void);
void send(void);
void receive(LTE_FDD_ENB_RADIO_PARAMS_STRUCT *radio_params);
private:
// Parameters
struct timespec sleep_time;
};
class LTE_fdd_enb_radio_usrp_b2x0
{
public:
// Constructor/Destructor
LTE_fdd_enb_radio_usrp_b2x0();
~LTE_fdd_enb_radio_usrp_b2x0();
// Radio functions
LTE_FDD_ENB_ERROR_ENUM setup(uint32 idx, double bw, int16 dl_earfcn, int16 ul_earfcn, std::string *clock_src, uint32 samp_rate, uint32 tx_gain, uint32 rx_gain);
void teardown(void);
void send(LTE_FDD_ENB_RADIO_TX_BUF_STRUCT *buf, LTE_FDD_ENB_RADIO_PARAMS_STRUCT *radio_params);
void receive(LTE_FDD_ENB_RADIO_PARAMS_STRUCT *radio_params);
private:
// Parameters
uhd::usrp::multi_usrp::sptr usrp;
uhd::tx_streamer::sptr tx_stream;
uhd::rx_streamer::sptr rx_stream;
uhd::rx_metadata_t metadata;
uhd::time_spec_t next_tx_ts;
uhd::time_spec_t next_rx_ts;
uhd::time_spec_t next_rx_subfr_ts;
uhd::time_spec_t check_ts;
gr_complex tx_buf[LIBLTE_PHY_N_SAMPS_PER_SUBFR_30_72MHZ];
gr_complex rx_buf[LIBLTE_PHY_N_SAMPS_PER_SUBFR_30_72MHZ];
int64 next_rx_ts_ticks;
int64 metadata_ts_ticks;
uint32 N_tx_samps;
uint32 N_rx_samps;
uint32 recv_size;
uint16 next_tx_current_tti;
};
class LTE_fdd_enb_radio_bladerf
{
public:
// Constructor/Destructor
LTE_fdd_enb_radio_bladerf();
~LTE_fdd_enb_radio_bladerf();
// Radio functions
LTE_FDD_ENB_ERROR_ENUM setup(uint32 idx, double bandwidth, int16 dl_earfcn, int16 ul_earfcn, uint8 N_ant, uint32 samp_rate, uint32 N_samps_per_subfr);
void teardown(void);
void send(LTE_FDD_ENB_RADIO_TX_BUF_STRUCT *buf, LTE_FDD_ENB_RADIO_PARAMS_STRUCT *radio_params);
void receive(LTE_FDD_ENB_RADIO_PARAMS_STRUCT *radio_params);
private:
// Parameters
struct bladerf *bladerf;
bladerf_metadata metadata_tx;
bladerf_metadata metadata_rx;
uint64 next_tx_ts;
uint64 rx_ts;
uint16 next_tx_current_tti;
int16 tx_buf[LIBLTE_PHY_N_SAMPS_PER_SUBFR_30_72MHZ*2];
int16 rx_buf[LIBLTE_PHY_N_SAMPS_PER_SUBFR_30_72MHZ*2];
bool first_tx_sample;
};
class LTE_fdd_enb_radio
{
public:
......@@ -106,6 +215,7 @@ public:
LTE_FDD_ENB_RADIO_STRUCT get_selected_radio(void);
uint32 get_selected_radio_idx(void);
LTE_FDD_ENB_ERROR_ENUM set_selected_radio_idx(uint32 idx);
LTE_FDD_ENB_RADIO_TYPE_ENUM get_selected_radio_type(void);
uint32 get_tx_gain(void);
LTE_FDD_ENB_ERROR_ENUM set_tx_gain(uint32 gain);
uint32 get_rx_gain(void);
......@@ -114,8 +224,8 @@ public:
LTE_FDD_ENB_ERROR_ENUM set_clock_source(std::string source);
uint32 get_phy_sample_rate(void);
uint32 get_radio_sample_rate(void);
void set_earfcns(int64 dl_earfcn, int64 ul_earfcn);
void send(LTE_FDD_ENB_RADIO_TX_BUF_STRUCT *buf);
pthread_t get_radio_thread(void);
private:
// Singleton
......@@ -127,28 +237,21 @@ private:
sem_t start_sem;
bool started;
// Radios
uhd::usrp::multi_usrp::sptr usrp;
uhd::tx_streamer::sptr tx_stream;
uhd::rx_streamer::sptr rx_stream;
// Generic radios
static void* radio_thread_func(void *inputs);
pthread_t radio_thread;
std::string clock_source;
LTE_FDD_ENB_RADIO_PARAMS_STRUCT radio_params;
LTE_FDD_ENB_AVAILABLE_RADIOS_STRUCT available_radios;
LTE_FDD_ENB_RADIO_TYPE_ENUM selected_radio_type;
uint32 selected_radio_idx;
uint32 tx_gain;
uint32 rx_gain;
// Radio thread
static void* radio_thread_func(void *inputs);
pthread_t radio_thread;
gr_complex tx_buf[LIBLTE_PHY_N_SAMPS_PER_SUBFR_30_72MHZ];
gr_complex rx_buf[LIBLTE_PHY_N_SAMPS_PER_SUBFR_30_72MHZ];
uhd::time_spec_t next_tx_ts;
std::string clock_source;
int64 N_ant;
uint32 N_tx_samps;
uint32 N_rx_samps;
uint32 N_samps_per_subfr;
uint32 fs;
uint32 tx_gain;
uint32 rx_gain;
uint16 next_tx_current_tti;
// Specific radios
LTE_fdd_enb_radio_no_rf no_rf;
LTE_fdd_enb_radio_usrp_b2x0 usrp_b2x0;
LTE_fdd_enb_radio_bladerf bladerf;
};
#endif /* __LTE_FDD_ENB_RADIO_H__ */
/*******************************************************************************
Copyright 2013-2016 Ben Wojtowicz
Copyright 2016 Przemek Bereski (send_ue_capability_enquiry)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
......@@ -41,6 +42,7 @@
02/13/2016 Ben Wojtowicz Removed boost message queue include and
add support for connection reestablishment
and connection reestablishment reject.
07/03/2016 Przemek Bereski Added send_ue_capability_enquiry.
*******************************************************************************/
......@@ -130,6 +132,7 @@ private:
void send_rrc_con_release(LTE_fdd_enb_user *user, LTE_fdd_enb_rb *rb);
void send_rrc_con_setup(LTE_fdd_enb_user *user, LTE_fdd_enb_rb *rb);
void send_security_mode_command(LTE_fdd_enb_user *user, LTE_fdd_enb_rb *rb);
void send_ue_capability_enquiry(LTE_fdd_enb_user *user, LTE_fdd_enb_rb *rb);
// Parameters
sem_t sys_info_sem;
......
......@@ -46,6 +46,8 @@
Gudkov).
02/13/2016 Ben Wojtowicz Actually properly constructing MNC (again,
thanks to Mikhail Gudkov).
07/03/2016 Ben Wojtowicz Removed the ability to switch EARFCNs while
the radio is running.
*******************************************************************************/
......@@ -194,7 +196,6 @@ LTE_FDD_ENB_ERROR_ENUM LTE_fdd_enb_cnfg_db::set_param(LTE_FDD_ENB_PARAM_ENUM par
set_param(LTE_FDD_ENB_PARAM_UL_EARFCN, (int64)liblte_interface_get_corresponding_ul_earfcn(value));
set_param(LTE_FDD_ENB_PARAM_DL_CENTER_FREQ, (int64)liblte_interface_dl_earfcn_to_frequency(value));
set_param(LTE_FDD_ENB_PARAM_UL_CENTER_FREQ, (int64)liblte_interface_ul_earfcn_to_frequency(liblte_interface_get_corresponding_ul_earfcn(value)));
radio->set_earfcns(value, (int64)liblte_interface_get_corresponding_ul_earfcn(value));
}else if(LTE_FDD_ENB_PARAM_USE_CNFG_FILE == param){
if(value)
{
......
......@@ -34,6 +34,7 @@
02/13/2016 Ben Wojtowicz Using memcpy instead of a typed cast for
parsing the IP packet header (thanks to
Damian Jarek for finding this).
07/03/2016 Ben Wojtowicz Setting processor affinity.
*******************************************************************************/
......@@ -291,9 +292,15 @@ void* LTE_fdd_enb_gw::receive_thread(void *inputs)
LTE_FDD_ENB_PDCP_DATA_SDU_READY_MSG_STRUCT pdcp_data_sdu;
LIBLTE_BYTE_MSG_STRUCT msg;
struct iphdr ip_pkt;
cpu_set_t af_mask;
uint32 idx = 0;
int32 N_bytes;
// Set affinity to not the last core (last core is for PHY/Radio)
pthread_getaffinity_np(gw->rx_thread, sizeof(af_mask), &af_mask);
CPU_CLR(sysconf(_SC_NPROCESSORS_ONLN)-1, &af_mask);
pthread_setaffinity_np(gw->rx_thread, sizeof(af_mask), &af_mask);
while(gw->is_started())
{
N_bytes = read(gw->tun_fd, &msg.msg[idx], LIBLTE_MAX_MSG_SIZE);
......
#line 2 "LTE_fdd_enb_hss.cc" // Make __FILE__ omit the path
/*******************************************************************************
Copyright 2014-2015 Ben Wojtowicz
Copyright 2014-2016 Ben Wojtowicz
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
......@@ -36,6 +36,8 @@
in del_user.
12/06/2015 Ben Wojtowicz Changed boost::mutex to pthread_mutex_t and
sem_t.
07/03/2016 Ben Wojtowicz Fixed a bug in print_all_users. Thanks to
Sultan Qasim Khan for finding this.
*******************************************************************************/
......@@ -257,6 +259,7 @@ std::string LTE_fdd_enb_hss::print_all_users(void)
for(iter=user_list.begin(); iter!=user_list.end(); iter++)
{
output += "\n";
tmp_ss.seekp(0);
tmp_ss << std::setw(15) << std::setfill('0') << (*iter)->id.imsi;
output += "imsi=" + tmp_ss.str();
tmp_ss.seekp(0);
......
......@@ -60,6 +60,7 @@
this).
02/13/2016 Ben Wojtowicz Added a user inactivity timer.
03/12/2016 Ben Wojtowicz Added PUCCH and H-ARQ support.
07/03/2016 Ben Wojtowicz Fixed memcpy lengths.
*******************************************************************************/
......@@ -525,6 +526,7 @@ void LTE_fdd_enb_mac::handle_pusch_decode(LTE_FDD_ENB_PUSCH_DECODE_MSG_STRUCT *p
// Unpack MAC PDU
liblte_mac_unpack_mac_pdu(&pusch_decode->msg,
false, // Simultaneous PUCCH/PUSCH
&mac_pdu);
for(i=0; i<mac_pdu.N_subheaders; i++)
......@@ -613,12 +615,12 @@ void LTE_fdd_enb_mac::handle_sdu_ready(LTE_FDD_ENB_MAC_SDU_READY_MSG_STRUCT *sdu
mac_pdu.subheader[0].lcid = LIBLTE_MAC_DLSCH_UE_CONTENTION_RESOLUTION_ID_LCID;
mac_pdu.subheader[0].payload.ue_con_res_id.id = sdu_ready->rb->get_con_res_id();
mac_pdu.subheader[1].lcid = sdu_ready->rb->get_rb_id();
memcpy(&mac_pdu.subheader[1].payload.sdu, sdu, sizeof(LIBLTE_BIT_MSG_STRUCT));
memcpy(&mac_pdu.subheader[1].payload.sdu, sdu, sizeof(LIBLTE_BYTE_MSG_STRUCT));
sdu_ready->rb->set_send_con_res_id(false);
}else{
mac_pdu.N_subheaders = 1;
mac_pdu.subheader[0].lcid = sdu_ready->rb->get_rb_id();
memcpy(&mac_pdu.subheader[0].payload.sdu, sdu, sizeof(LIBLTE_BIT_MSG_STRUCT));
memcpy(&mac_pdu.subheader[0].payload.sdu, sdu, sizeof(LIBLTE_BYTE_MSG_STRUCT));
}
// Determine the current_tti
......
......@@ -51,6 +51,9 @@
the packet filter evaluation precedence in
activate dedicated EPS bearer context (thanks
to Pedro Batista for reporting this).
07/03/2016 Ben Wojtowicz Fixed a bug when receiving a service request
message for a non-existent user. Thanks to
Peter Nguyen for finding this.
*******************************************************************************/
......@@ -1041,15 +1044,24 @@ void LTE_fdd_enb_mme::parse_service_request(LIBLTE_BYTE_MSG_STRUCT *msg,
// Resolve sequence number mismatch
auth_vec->nas_count_ul = service_req.ksi_and_seq_num.seq_num;
hss_auth_vec = hss->regenerate_enb_security_data(user->get_id(), auth_vec->nas_count_ul);
for(i=0; i<32; i++)
if(NULL != hss_auth_vec)
{
auth_vec->k_rrc_enc[i] = hss_auth_vec->k_rrc_enc[i];
auth_vec->k_rrc_int[i] = hss_auth_vec->k_rrc_int[i];
for(i=0; i<32; i++)
{
auth_vec->k_rrc_enc[i] = hss_auth_vec->k_rrc_enc[i];
auth_vec->k_rrc_int[i] = hss_auth_vec->k_rrc_int[i];
}
}
}
// Set the state
rb->set_mme_state(LTE_FDD_ENB_MME_STATE_RRC_SECURITY);
if(NULL != hss_auth_vec)
{
rb->set_mme_state(LTE_FDD_ENB_MME_STATE_RRC_SECURITY);
}else{
send_service_reject(user, rb, LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED);
rb->set_mme_state(LTE_FDD_ENB_MME_STATE_RELEASE);
}
}
}
void LTE_fdd_enb_mme::parse_activate_default_eps_bearer_context_accept(LIBLTE_BYTE_MSG_STRUCT *msg,
......
......@@ -39,6 +39,7 @@
to sem_t and properly initializing priority.
02/13/2016 Ben Wojtowicz Moved the buffer empty log from ERROR to
WARNING.
07/03/2016 Ben Wojtowicz Setting processor affinity.
*******************************************************************************/
......@@ -184,6 +185,7 @@ void* LTE_fdd_enb_msgq::receive_thread(void *inputs)
LTE_fdd_enb_msgq *msgq = (LTE_fdd_enb_msgq *)inputs;
LTE_FDD_ENB_MESSAGE_STRUCT msg;
struct sched_param priority;
cpu_set_t af_mask;
bool not_done = true;
// Set priority
......@@ -194,6 +196,11 @@ void* LTE_fdd_enb_msgq::receive_thread(void *inputs)
pthread_setschedparam(msgq->rx_thread, SCHED_FIFO, &priority);
}
// Set affinity to not the last core (last core is for PHY/Radio)
pthread_getaffinity_np(msgq->rx_thread, sizeof(af_mask), &af_mask);
CPU_CLR(sysconf(_SC_NPROCESSORS_ONLN)-1, &af_mask);
pthread_setaffinity_np(msgq->rx_thread, sizeof(af_mask), &af_mask);
while(not_done)
{
// Wait for a message
......
......@@ -48,6 +48,8 @@
12/06/2015 Ben Wojtowicz Changed boost::mutex to pthread_mutex_t and
sem_t.
03/12/2016 Ben Wojtowicz Added PUCCH support.
07/03/2016 Ben Wojtowicz Not including UL PDCCH allocations in a check
of how many DL PRBs are being used.
*******************************************************************************/
......@@ -572,8 +574,8 @@ void LTE_fdd_enb_phy::process_dl(LTE_FDD_ENB_RADIO_TX_BUF_STRUCT *tx_buf)
&pdcch.alloc[pdcch.N_alloc].tbs,
&pdcch.alloc[pdcch.N_alloc].mcs,
&pdcch.alloc[pdcch.N_alloc].N_prb);
pdcch.alloc[pdcch.N_alloc].rv_idx = (uint32)ceilf(1.5 * ((sfn / 2) % 4)) % 4; //36.321 section 5.3.1
pdcch.N_alloc++;
pdcch.alloc[pdcch.N_alloc].rv_idx = (uint32)ceilf(1.5 * ((sfn / 2) % 4)) % 4; //36.321 section 5.3.1
pdcch.alloc[pdcch.N_alloc++].dl_alloc = true;
}
if((0 * sys_info.si_win_len)%10 <= dl_subframe.num &&
(1 * sys_info.si_win_len)%10 > dl_subframe.num &&
......@@ -602,7 +604,7 @@ void LTE_fdd_enb_phy::process_dl(LTE_FDD_ENB_RADIO_TX_BUF_STRUCT *tx_buf)
&pdcch.alloc[pdcch.N_alloc].mcs,
&pdcch.alloc[pdcch.N_alloc].N_prb))
{
pdcch.N_alloc++;
pdcch.alloc[pdcch.N_alloc++].dl_alloc = true;
}
}
for(i=1; i<sys_info.sib1.N_sched_info; i++)
......@@ -631,7 +633,7 @@ void LTE_fdd_enb_phy::process_dl(LTE_FDD_ENB_RADIO_TX_BUF_STRUCT *tx_buf)
&pdcch.alloc[pdcch.N_alloc].tbs,
&pdcch.alloc[pdcch.N_alloc].mcs,
&pdcch.alloc[pdcch.N_alloc].N_prb);
pdcch.N_alloc++;
pdcch.alloc[pdcch.N_alloc++].dl_alloc = true;
}
}
......@@ -642,12 +644,12 @@ void LTE_fdd_enb_phy::process_dl(LTE_FDD_ENB_RADIO_TX_BUF_STRUCT *tx_buf)
for(i=0; i<dl_schedule[subfn].dl_allocations.N_alloc; i++)
{
memcpy(&pdcch.alloc[pdcch.N_alloc], &dl_schedule[subfn].dl_allocations.alloc[i], sizeof(LIBLTE_PHY_ALLOCATION_STRUCT));
pdcch.N_alloc++;
pdcch.alloc[pdcch.N_alloc++].dl_alloc = true;
}
for(i=0; i<dl_schedule[subfn].ul_allocations.N_alloc; i++)
{
memcpy(&pdcch.alloc[pdcch.N_alloc], &dl_schedule[subfn].ul_allocations.alloc[i], sizeof(LIBLTE_PHY_ALLOCATION_STRUCT));
pdcch.N_alloc++;
pdcch.alloc[pdcch.N_alloc++].dl_alloc = false;
}
}else{
late_subfr = true;
......@@ -666,8 +668,11 @@ void LTE_fdd_enb_phy::process_dl(LTE_FDD_ENB_RADIO_TX_BUF_STRUCT *tx_buf)
{
for(j=0; j<pdcch.alloc[i].N_prb; j++)
{
pdcch.alloc[i].prb[0][j] = last_prb;
pdcch.alloc[i].prb[1][j] = last_prb++;
if(pdcch.alloc[i].dl_alloc)
{
pdcch.alloc[i].prb[0][j] = last_prb;
pdcch.alloc[i].prb[1][j] = last_prb++;
}
}
}
if(last_prb > phy_struct->N_rb_dl)
......
This diff is collapsed.
#line 2 "LTE_fdd_enb_rlc.cc" // Make __FILE__ omit the path
/*******************************************************************************
Copyright 2013-2015 Ben Wojtowicz
Copyright 2013-2016 Ben Wojtowicz
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
......@@ -43,6 +43,7 @@
07/25/2015 Ben Wojtowicz Using the new user QoS structure.
12/06/2015 Ben Wojtowicz Changed boost::mutex to pthread_mutex_t and
sem_t.
07/03/2016 Ben Wojtowicz Added error log for AMD PDU segments.
*******************************************************************************/
......@@ -463,83 +464,93 @@ void LTE_fdd_enb_rlc::handle_am_pdu(LIBLTE_BYTE_MSG_STRUCT *pdu,
{
handle_status_pdu(pdu, user, rb);
}else{
if(vrr <= amd.hdr.sn &&
amd.hdr.sn < vrmr)
if(LIBLTE_RLC_RF_FIELD_AMD_PDU_SEGMENT == amd.hdr.rf)
{
interface->send_debug_msg(LTE_FDD_ENB_DEBUG_TYPE_INFO,
interface->send_debug_msg(LTE_FDD_ENB_DEBUG_TYPE_ERROR,
LTE_FDD_ENB_DEBUG_LEVEL_RLC,
__FILE__,
__LINE__,
&amd.data[0],
"Received AMD PDU for RNTI=%u, RB=%s, VR(R)=%u, SN=%u, VR(MR)=%u, VR(H)=%u, RF=%s, P=%s, FI=%s",
user->get_c_rnti(),
LTE_fdd_enb_rb_text[rb->get_rb_id()],
vrr,
amd.hdr.sn,
vrmr,
vrh,
liblte_rlc_rf_field_text[amd.hdr.rf],
liblte_rlc_p_field_text[amd.hdr.p],
liblte_rlc_fi_field_text[amd.hdr.fi]);
// Place RLC data PDU in reception buffer
rb->rlc_add_to_am_reception_buffer(&amd);
// Update VR(H)
if(amd.hdr.sn >= vrh)
"Not handling AMD PDU segments");
}else{
if(vrr <= amd.hdr.sn &&
amd.hdr.sn < vrmr)
{
rb->set_rlc_vrh(amd.hdr.sn + 1);
}
// Update VR(MS)
// FIXME
interface->send_debug_msg(LTE_FDD_ENB_DEBUG_TYPE_INFO,
LTE_FDD_ENB_DEBUG_LEVEL_RLC,
__FILE__,
__LINE__,
&amd.data[0],
"Received AMD PDU for RNTI=%u, RB=%s, VR(R)=%u, SN=%u, VR(MR)=%u, VR(H)=%u, RF=%s, P=%s, FI=%s",
user->get_c_rnti(),
LTE_fdd_enb_rb_text[rb->get_rb_id()],
vrr,
amd.hdr.sn,
vrmr,
vrh,
liblte_rlc_rf_field_text[amd.hdr.rf],
liblte_rlc_p_field_text[amd.hdr.p],
liblte_rlc_fi_field_text[amd.hdr.fi]);
// Place RLC data PDU in reception buffer
rb->rlc_add_to_am_reception_buffer(&amd);
// Update VR(H)
if(amd.hdr.sn >= vrh)
{
rb->set_rlc_vrh(amd.hdr.sn + 1);
}
// Update VR(R)/VR(MR) and reassemble
if(amd.hdr.sn == vrr)
{
rb->update_rlc_vrr();
// FIXME: Handle AMD PDU Segments
// Update VR(MS)
// FIXME
if(LTE_FDD_ENB_ERROR_NONE == rb->rlc_am_reassemble(&pdcp_pdu))
// Update VR(R)/VR(MR) and reassemble
if(amd.hdr.sn == vrr)
{
// Queue the SDU for PDCP
rb->queue_pdcp_pdu(&pdcp_pdu);
// Signal PDCP
pdcp_pdu_ready.user = user;
pdcp_pdu_ready.rb = rb;
msgq_to_pdcp->send(LTE_FDD_ENB_MESSAGE_TYPE_PDCP_PDU_READY,
LTE_FDD_ENB_DEST_LAYER_PDCP,
(LTE_FDD_ENB_MESSAGE_UNION *)&pdcp_pdu_ready,
sizeof(LTE_FDD_ENB_PDCP_PDU_READY_MSG_STRUCT));
rb->update_rlc_vrr();
// FIXME: Handle AMD PDU Segments
if(LTE_FDD_ENB_ERROR_NONE == rb->rlc_am_reassemble(&pdcp_pdu))
{
// Queue the SDU for PDCP
rb->queue_pdcp_pdu(&pdcp_pdu);
// Signal PDCP
pdcp_pdu_ready.user = user;
pdcp_pdu_ready.rb = rb;
msgq_to_pdcp->send(LTE_FDD_ENB_MESSAGE_TYPE_PDCP_PDU_READY,
LTE_FDD_ENB_DEST_LAYER_PDCP,
(LTE_FDD_ENB_MESSAGE_UNION *)&pdcp_pdu_ready,
sizeof(LTE_FDD_ENB_PDCP_PDU_READY_MSG_STRUCT));
}
}
}
if(amd.hdr.p)
{
// Send a STATUS PDU to ACK/NACK SNs
rb->rlc_get_am_reception_buffer_status(&status);
send_status_pdu(&status, user, rb);
}
}else{
interface->send_debug_msg(LTE_FDD_ENB_DEBUG_TYPE_INFO,
LTE_FDD_ENB_DEBUG_LEVEL_RLC,
__FILE__,
__LINE__,
&amd.data[0],
"Received AMD PDU for RNTI=%u, RB=%s, that is outside of the receiving window (%u <= %u < %u), P=%s",
user->get_c_rnti(),
LTE_fdd_enb_rb_text[rb->get_rb_id()],
vrr,
amd.hdr.sn,
vrmr,
liblte_rlc_p_field_text[amd.hdr.p]);
if(amd.hdr.p)
{
// Send a STATUS PDU to ACK/NACK SNs
rb->rlc_get_am_reception_buffer_status(&status);
send_status_pdu(&status, user, rb);
if(amd.hdr.p)
{
// Send a STATUS PDU to ACK/NACK SNs
rb->rlc_get_am_reception_buffer_status(&status);
send_status_pdu(&status, user, rb);
}
}else{
interface->send_debug_msg(LTE_FDD_ENB_DEBUG_TYPE_INFO,
LTE_FDD_ENB_DEBUG_LEVEL_RLC,
__FILE__,
__LINE__,
&amd.data[0],
"Received AMD PDU for RNTI=%u, RB=%s, that is outside of the receiving window (%u <= %u < %u), P=%s",
user->get_c_rnti(),
LTE_fdd_enb_rb_text[rb->get_rb_id()],
vrr,
amd.hdr.sn,
vrmr,
liblte_rlc_p_field_text[amd.hdr.p]);
if(amd.hdr.p)
{
// Send a STATUS PDU to ACK/NACK SNs
rb->rlc_get_am_reception_buffer_status(&status);
send_status_pdu(&status, user, rb);
}
}
}
}
......
<
......@@ -2,6 +2,8 @@
/*******************************************************************************
Copyright 2013-2016 Ben Wojtowicz
Copyright 2016 Przemek Bereski (UE capability information and UE capability
enquiry support)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
......@@ -49,6 +51,8 @@
sem_t.