Merge branch 'next' into agpl_next

This commit is contained in:
Codebot 2022-04-29 07:28:41 +00:00 committed by SRS codebot
commit 9211ad7d51
49 changed files with 247 additions and 155 deletions

View File

@ -14,19 +14,6 @@ jobs:
sudo apt update
sudo apt install -y build-essential cmake libfftw3-dev libmbedtls-dev libpcsclite-dev libboost-program-options-dev libconfig++-dev libsctp-dev colordiff ninja-build valgrind
mkdir build && cd build && cmake -DRF_FOUND=True -GNinja .. && ninja && ctest
x86_ubuntu16_build:
name: Build and test on x86 Ubuntu 16.04
strategy:
matrix:
compiler: [gcc, clang]
runs-on: ubuntu-16.04
steps:
- uses: actions/checkout@v1
- name: Build srsRAN on x86 Ubuntu 16.04
run: |
sudo apt update
sudo apt install -y build-essential cmake libfftw3-dev libmbedtls-dev libpcsclite-dev libboost-program-options-dev libconfig++-dev libsctp-dev colordiff ninja-build valgrind
mkdir build && cd build && cmake -DRF_FOUND=True -GNinja .. && ninja && ctest
aarch64_ubuntu18_build:
runs-on: ubuntu-18.04

View File

@ -1,6 +1,15 @@
Change Log for Releases
=======================
## 22.04
* Added baseline 5G-SA support to srsUE and srsENB
* Added dynamic loading of RF libraries
* Added RRC Redirect to srsUE
* Added support for A5 measurement events to srsENB
* Added Crest Factor Reduction (CFR) for srsENB downlink and srsUE uplink (4G only)
* Raise C++ standard to C++14
* Other bug-fixes and improved stability and performance in all parts
## 21.10
* Add initial 5G NSA support to srsENB (tested with OnePlus 5G Nord)
* Improved interoperability of srsUE in NSA mode

View File

@ -1,5 +1,5 @@
Files: *
Copyright: 2013-2021, Software Radio Systems Limited.
Copyright: 2013-2022, Software Radio Systems Limited.
License:

View File

@ -10,8 +10,8 @@ srsRAN is a 4G/5G software radio suite developed by [SRS](http://www.srs.io).
See the [srsRAN project pages](https://www.srsran.com) for information, guides and project news.
The srsRAN suite includes:
* srsUE - a full-stack SDR 4G/5G-NSA UE application (5G-SA coming soon)
* srsENB - a full-stack SDR 4G/5G-NSA eNodeB application (5G-SA coming soon)
* srsUE - a full-stack SDR 4G/5G UE application
* srsENB - a full-stack SDR 4G/5G e(g)NodeB application
* srsEPC - a light-weight 4G core network implementation with MME, HSS and S/P-GW
For application features, build instructions and user guides see the [srsRAN documentation](https://docs.srsran.com).

View File

@ -18,8 +18,8 @@
# and at http://www.gnu.org/licenses/.
#
SET(SRSRAN_VERSION_MAJOR 21)
SET(SRSRAN_VERSION_MINOR 10)
SET(SRSRAN_VERSION_MAJOR 22)
SET(SRSRAN_VERSION_MINOR 04)
SET(SRSRAN_VERSION_PATCH 0)
SET(SRSRAN_VERSION_STRING "${SRSRAN_VERSION_MAJOR}.${SRSRAN_VERSION_MINOR}.${SRSRAN_VERSION_PATCH}")
SET(SRSRAN_SOVERSION 0)

View File

@ -3649,6 +3649,8 @@ typedef struct {
// Functions
LIBLTE_ERROR_ENUM liblte_mme_pack_deactivate_eps_bearer_context_request_msg(
LIBLTE_MME_DEACTIVATE_EPS_BEARER_CONTEXT_REQUEST_MSG_STRUCT* deact_eps_bearer_context_req,
uint8 sec_hdr_type,
uint32 count,
LIBLTE_BYTE_MSG_STRUCT* msg);
LIBLTE_ERROR_ENUM liblte_mme_unpack_deactivate_eps_bearer_context_request_msg(
LIBLTE_BYTE_MSG_STRUCT* msg,

View File

@ -708,7 +708,6 @@ public:
class dnn_t
{
public:
uint32_t length;
std::vector<uint8_t> dnn_value;
SRSASN_CODE pack(asn1::bit_ref& bref);

View File

@ -407,7 +407,7 @@ inline uint16_t enum_to_number(const pmch_info_t::mch_sched_period_t& mch_period
struct mcch_msg_t {
uint32_t nof_common_sf_alloc = 0;
mbsfn_sf_cfg_t common_sf_alloc[8];
mbsfn_sf_cfg_t common_sf_alloc[8] = {};
enum class common_sf_alloc_period_t { rf4, rf8, rf16, rf32, rf64, rf128, rf256, nulltype } common_sf_alloc_period;
uint32_t nof_pmch_info;
pmch_info_t pmch_info_list[15];

View File

@ -140,9 +140,9 @@ private:
/// internal buffer, useful for storing very short SDUs.
class sdu_buffer
{
static const uint8_t mac_ce_payload_len = 8 + 1; // Long BSR has max. 9 octets (see sizeof_ce() too)
std::array<uint8_t, mac_ce_payload_len> ce_write_buffer; // Buffer for CE payload
uint8_t* sdu = nullptr;
static const uint8_t mac_ce_payload_len = 8 + 1; // Long BSR has max. 9 octets (see sizeof_ce() too)
std::array<uint8_t, mac_ce_payload_len> ce_write_buffer = {}; // Buffer for CE payload
uint8_t* sdu = nullptr;
public:
sdu_buffer() = default;

View File

@ -171,7 +171,7 @@ public:
}
// Create receiver ring buffers
rx_ring_buffers.resize(args_.nof_carriers * args_.nof_antennas);
rx_ring_buffers.resize(args_.nof_carriers * (size_t)args_.nof_antennas);
for (auto& rb : rx_ring_buffers) {
if (srsran_ringbuffer_init(&rb, (int)sizeof(cf_t) * TEMP_BUFFER_SZ) != SRSRAN_SUCCESS) {
perror("init softbuffer");
@ -179,7 +179,7 @@ public:
}
// Create transmitter ring buffers
tx_ring_buffers.resize(args_.nof_carriers * args_.nof_antennas);
tx_ring_buffers.resize(args_.nof_carriers * (size_t)args_.nof_antennas);
for (auto& rb : tx_ring_buffers) {
if (srsran_ringbuffer_init(&rb, (int)sizeof(cf_t) * TEMP_BUFFER_SZ) != SRSRAN_SUCCESS) {
perror("init softbuffer");

View File

@ -143,13 +143,13 @@ public:
virtual void get_buffer_state(uint32_t& tx_queue, uint32_t& prio_tx_queue) = 0;
virtual void reestablish() = 0;
virtual void empty_queue() = 0;
virtual bool sdu_queue_is_full() = 0;
virtual bool has_data() = 0;
virtual void stop() = 0;
void set_bsr_callback(bsr_callback_t callback);
int write_sdu(unique_byte_buffer_t sdu);
bool sdu_queue_is_full();
virtual void discard_sdu(uint32_t pdcp_sn);
virtual uint32_t read_pdu(uint8_t* payload, uint32_t nof_bytes) = 0;

View File

@ -68,7 +68,6 @@ public:
void stop();
uint32_t read_pdu(uint8_t* payload, uint32_t nof_bytes);
bool sdu_queue_is_full();
bool has_data();
uint32_t get_buffer_state();

View File

@ -37,7 +37,7 @@ struct rlc_sn_info_t {
struct rlc_amd_rx_pdu {
rlc_amd_pdu_header_t header;
unique_byte_buffer_t buf;
uint32_t rlc_sn;
uint32_t rlc_sn = 0;
rlc_amd_rx_pdu() = default;
explicit rlc_amd_rx_pdu(uint32_t rlc_sn_) : rlc_sn(rlc_sn_) {}

View File

@ -105,7 +105,6 @@ public:
uint32_t read_pdu(uint8_t* payload, uint32_t nof_bytes) final;
void handle_control_pdu(uint8_t* payload, uint32_t nof_bytes) final;
bool sdu_queue_is_full() final;
void reestablish() final;
void stop() final;

View File

@ -38,7 +38,7 @@ struct sys_metrics_t {
float process_cpu_usage = 0.f;
float system_mem = 0.f;
uint32_t cpu_count = 0;
std::array<float, metrics_max_supported_cpu> cpu_load;
std::array<float, metrics_max_supported_cpu> cpu_load = {};
};
} // namespace srsran

View File

@ -9018,12 +9018,27 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_deactivate_eps_bearer_context_accept_msg(
*********************************************************************/
LIBLTE_ERROR_ENUM liblte_mme_pack_deactivate_eps_bearer_context_request_msg(
LIBLTE_MME_DEACTIVATE_EPS_BEARER_CONTEXT_REQUEST_MSG_STRUCT* deact_eps_bearer_context_req,
uint8 sec_hdr_type,
uint32 count,
LIBLTE_BYTE_MSG_STRUCT* msg)
{
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
uint8* msg_ptr = msg->msg;
if (deact_eps_bearer_context_req != NULL && msg != NULL) {
if (LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS != sec_hdr_type) {
// Protocol Discriminator and Security Header Type
*msg_ptr = (sec_hdr_type << 4) | (LIBLTE_MME_PD_EPS_MOBILITY_MANAGEMENT);
msg_ptr++;
// MAC will be filled in later
msg_ptr += 4;
// Sequence Number
*msg_ptr = count & 0xFF;
msg_ptr++;
}
// Protocol Discriminator and EPS Bearer ID
*msg_ptr = (deact_eps_bearer_context_req->eps_bearer_id << 4) | (LIBLTE_MME_PD_EPS_SESSION_MANAGEMENT);
msg_ptr++;

View File

@ -1156,7 +1156,7 @@ bool make_phy_pusch_scaling(const uci_on_pusch_s& uci_on_pusch, float* in_scalin
bool make_phy_zp_csi_rs_resource(const asn1::rrc_nr::zp_csi_rs_res_s& zp_csi_rs_res,
srsran_csi_rs_zp_resource_t* out_zp_csi_rs_resource)
{
srsran_csi_rs_zp_resource_t zp_csi_rs_resource;
srsran_csi_rs_zp_resource_t zp_csi_rs_resource = {};
zp_csi_rs_resource.id = zp_csi_rs_res.zp_csi_rs_res_id;
switch (zp_csi_rs_res.res_map.freq_domain_alloc.type()) {
case csi_rs_res_map_s::freq_domain_alloc_c_::types_opts::options::row1:
@ -1321,7 +1321,7 @@ bool make_phy_zp_csi_rs_resource(const asn1::rrc_nr::zp_csi_rs_res_s& zp_csi_rs_
bool make_phy_nzp_csi_rs_resource(const asn1::rrc_nr::nzp_csi_rs_res_s& asn1_nzp_csi_rs_res,
srsran_csi_rs_nzp_resource_t* out_csi_rs_nzp_resource)
{
srsran_csi_rs_nzp_resource_t csi_rs_nzp_resource;
srsran_csi_rs_nzp_resource_t csi_rs_nzp_resource = {};
csi_rs_nzp_resource.id = asn1_nzp_csi_rs_res.nzp_csi_rs_res_id;
switch (asn1_nzp_csi_rs_res.res_map.freq_domain_alloc.type()) {
case csi_rs_res_map_s::freq_domain_alloc_c_::types_opts::options::row1:

View File

@ -334,7 +334,7 @@ mac_sch_subpdu_nr::lbsr_t mac_sch_subpdu_nr::get_lbsr() const
mac_sch_subpdu_nr::ue_con_res_id_t mac_sch_subpdu_nr::get_ue_con_res_id_ce()
{
mac_sch_subpdu_nr::ue_con_res_id_t id;
mac_sch_subpdu_nr::ue_con_res_id_t id = {};
if (!parent->is_ulsch() && lcid == CON_RES_ID) {
const uint8_t* ptr = sdu.ptr();
memcpy(id.data(), ptr, id.size());

View File

@ -437,7 +437,7 @@ int srsran_dmrs_pdcch_get_measure(const srsran_dmrs_pdcch_estimator_t* q,
// For each CORESET symbol
for (uint32_t l = 0; l < q->coreset.duration; l++) {
// Temporal least square estimates
cf_t tmp[DMRS_PDCCH_MAX_NOF_PILOTS_CANDIDATE];
cf_t tmp[DMRS_PDCCH_MAX_NOF_PILOTS_CANDIDATE] = {};
uint32_t nof_pilots = 0;
// For each RB in the CORESET

View File

@ -35,6 +35,7 @@ static int test_row1()
}
m.nof_ports = 1;
m.first_symbol_idx = 0;
m.first_symbol_idx2 = 0;
m.cdm = srsran_csi_rs_cdm_nocdm;
m.density = srsran_csi_rs_resource_mapping_density_three;
m.freq_band.start_rb = carrier.start;
@ -78,6 +79,7 @@ static int test_row2()
}
m.nof_ports = 1;
m.first_symbol_idx = 0;
m.first_symbol_idx2 = 0;
m.cdm = srsran_csi_rs_cdm_nocdm;
m.density = density;
m.freq_band.start_rb = carrier.start;

View File

@ -143,7 +143,8 @@ int main(int argc, char** argv)
srsran_chest_dl_res_t chest_dl_res;
srsran_pmch_t pmch;
srsran_pmch_cfg_t pmch_cfg;
srsran_ofdm_t ifft_mbsfn[SRSRAN_MAX_PORTS], fft_mbsfn[SRSRAN_MAX_PORTS];
srsran_ofdm_t ifft_mbsfn[SRSRAN_MAX_PORTS] = {};
srsran_ofdm_t fft_mbsfn[SRSRAN_MAX_PORTS] = {};
parse_args(argc, argv);
/* Initialise to zeros */

View File

@ -182,17 +182,17 @@ void parse_args(int argc, char** argv)
int main(int argc, char** argv)
{
srsran_random_t random_h = srsran_random_init(0);
srsran_chest_ul_res_t chest_res;
srsran_pusch_t pusch_tx;
srsran_pusch_t pusch_rx;
srsran_chest_ul_res_t chest_res = {};
srsran_pusch_t pusch_tx = {};
srsran_pusch_t pusch_rx = {};
uint8_t* data = NULL;
uint8_t* data_rx = NULL;
cf_t* sf_symbols = NULL;
int ret = -1;
struct timeval t[3];
srsran_pusch_cfg_t cfg;
srsran_softbuffer_tx_t softbuffer_tx;
srsran_softbuffer_rx_t softbuffer_rx;
srsran_pusch_cfg_t cfg = {};
srsran_softbuffer_tx_t softbuffer_tx = {};
srsran_softbuffer_rx_t softbuffer_rx = {};
srsran_crc_t crc_tb;
ZERO_OBJECT(uci_data_tx);

View File

@ -90,7 +90,7 @@ static int _rf_file_tx_baseband(rf_file_tx_t* q, cf_t* buffer, uint32_t nsamples
size_t ret = fwrite(buf, (size_t)sample_sz, (size_t)nsamples, q->file);
if (ret < (size_t)nsamples) {
rf_file_error(q->id,
"[file] Error: transmitter expected %d bytes and sent %d. %s.\n",
"[file] Error: transmitter expected %d bytes and sent %zd. %s.\n",
NSAMPLES2NBYTES(nsamples),
ret,
strerror(errno));

View File

@ -400,7 +400,7 @@ void srsran_nbiot_ue_dl_decode_sib1(srsran_nbiot_ue_dl_t* q, uint32_t current_sf
// activate SIB1 grant and configure NPDSCH
INFO(
"%d.x: Activated SIB1 decoding in sfn=%d\n", current_sfn, srsran_nbiot_ue_dl_get_next_sib1_start(q, current_sfn));
srsran_ra_nbiot_dl_grant_t grant;
srsran_ra_nbiot_dl_grant_t grant = {};
srsran_nbiot_ue_dl_get_sib1_grant(q, current_sfn, &grant);
srsran_nbiot_ue_dl_set_grant(q, &grant);
}
@ -419,7 +419,7 @@ void srsran_nbiot_ue_dl_decode_sib(srsran_nbiot_ue_dl_t* q,
if (type == SRSRAN_NBIOT_SI_TYPE_SIB2) {
assert(params.n == 1);
// calculate SIB2 params
srsran_ra_nbiot_dl_grant_t grant;
srsran_ra_nbiot_dl_grant_t grant = {};
srsran_nbiot_ue_dl_get_sib_grant(q, hfn, sfn, params, &grant);
srsran_nbiot_ue_dl_set_grant(q, &grant);
INFO("%d.x: Activated SIB2 reception in hfn=%d, sfn=%d",

View File

@ -505,7 +505,7 @@ bool radio::open_dev(const uint32_t &device_idx, FILE** rx_files, FILE** tx_file
{
srsran_rf_t* rf_device = &rf_devices[device_idx];
srsran::console("Opening %d channels in RF device abstraction\n");
srsran::console("Opening channels idx %d in RF device abstraction\n", device_idx);
if (srsran_rf_open_file(rf_device, rx_files, tx_files, nof_channels, base_srate)) {
logger.error("Error opening RF device abstraction");

View File

@ -281,6 +281,11 @@ void rlc_am::rlc_am_base_tx::discard_sdu(uint32_t discard_sn)
RlcInfo("%s PDU with PDCP_SN=%d", discarded ? "Discarding" : "Couldn't discard", discard_sn);
}
bool rlc_am::rlc_am_base_tx::sdu_queue_is_full()
{
return tx_sdu_queue.is_full();
}
void rlc_am::rlc_am_base_tx::set_bsr_callback(bsr_callback_t callback)
{
bsr_callback = callback;

View File

@ -277,11 +277,6 @@ void rlc_am_lte_tx::get_buffer_state_nolock(uint32_t& n_bytes_newtx, uint32_t& n
}
}
bool rlc_am_lte_tx::sdu_queue_is_full()
{
return tx_sdu_queue.is_full();
}
uint32_t rlc_am_lte_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes)
{
std::lock_guard<std::mutex> lock(mutex);

View File

@ -185,6 +185,10 @@ uint32_t rlc_am_nr_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes)
*/
uint32_t rlc_am_nr_tx::build_new_pdu(uint8_t* payload, uint32_t nof_bytes)
{
if (nof_bytes <= min_hdr_size) {
RlcInfo("Not enough bytes for payload plus header. nof_bytes=%d", nof_bytes);
return 0;
}
// Read new SDU from TX queue
unique_byte_buffer_t tx_sdu;
RlcDebug("Reading from RLC SDU queue. Queue size %d", tx_sdu_queue.size());
@ -449,12 +453,12 @@ uint32_t rlc_am_nr_tx::build_retx_pdu(uint8_t* payload, uint32_t nof_bytes)
// Sanity check - drop any retx SNs not present in tx_window
while (not tx_window->has_sn(retx.sn)) {
RlcWarning("SN=%d not in tx window. Ignoring retx.", retx.sn);
RlcInfo("SN=%d not in tx window, probably already ACKed. Skip and remove from retx queue", retx.sn);
retx_queue->pop();
if (!retx_queue->empty()) {
retx = retx_queue->front();
} else {
RlcWarning("empty retx queue, cannot provide retx PDU");
RlcInfo("empty retx queue, cannot provide any retx PDU");
return 0;
}
}
@ -833,9 +837,9 @@ void rlc_am_nr_tx::handle_control_pdu(uint8_t* payload, uint32_t nof_bytes)
std::set<uint32_t> retx_sn_set; // Set of PDU SNs added for retransmission (no duplicates)
for (uint32_t nack_idx = 0; nack_idx < status.nacks.size(); nack_idx++) {
if (status.nacks[nack_idx].has_nack_range) {
RlcError("Handling NACK ranges is not yet implemented. Ignoring NACK across %d SDU(s) starting from SN=%d",
status.nacks[nack_idx].nack_range,
status.nacks[nack_idx].nack_sn);
RlcWarning("Handling NACK ranges is not yet implemented. Ignoring NACK across %d SDU(s) starting from SN=%d",
status.nacks[nack_idx].nack_range,
status.nacks[nack_idx].nack_sn);
continue;
}
if (tx_mod_base_nr(st.tx_next_ack) <= tx_mod_base_nr(status.nacks[nack_idx].nack_sn) &&
@ -1159,11 +1163,6 @@ void rlc_am_nr_tx::reestablish()
stop();
}
bool rlc_am_nr_tx::sdu_queue_is_full()
{
return false;
}
void rlc_am_nr_tx::empty_queue()
{
std::lock_guard<std::mutex> lock(mutex);
@ -1234,6 +1233,11 @@ void rlc_am_nr_tx::timer_expired(uint32_t timeout_id)
retx.current_so = 0;
retx.segment_length = (*tx_window)[st.tx_next_ack].segment_list.begin()->payload_len;
}
RlcDebug("Retransmission because of t-PollRetransmit. RETX SN=%d, is_segment=%s, so_start=%d, segment_length=%d",
retx.sn,
retx.is_segment ? "true" : "false",
retx.so_start,
retx.segment_length);
}
return;
}
@ -1356,12 +1360,44 @@ void rlc_am_nr_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_bytes)
return;
}
// Trigger polling if poll bit is set.
// We do this before discarding duplicate SDUs/SDU segments
// Because t-PollRetransmit may transmit a PDU that was already
// received.
if (header.p) {
RlcInfo("status packet requested through polling bit");
do_status = true;
}
// Section 5.2.3.2.2, discard duplicate PDUs
if (rx_window->has_sn(header.sn) && (*rx_window)[header.sn].fully_received) {
RlcInfo("discarding duplicate SN=%d", header.sn);
return;
}
// Section 5.2.3.2.2, discard segments with overlapping bytes
if (rx_window->has_sn(header.sn) && header.si != rlc_nr_si_field_t::full_sdu) {
for (const auto& segm : (*rx_window)[header.sn].segments) {
uint32_t segm_last_byte = segm.header.so + segm.buf->N_bytes - 1;
uint32_t pdu_last_byte = header.so + nof_bytes - hdr_len - 1;
if ((header.so >= segm.header.so && header.so <= segm_last_byte) ||
(pdu_last_byte >= segm.header.so && pdu_last_byte <= segm_last_byte)) {
RlcInfo("Got SDU segment with duplicate bytes. Discarding.");
RlcInfo("Discarded SDU segment. SN=%d, SO=%d, last_byte=%d, payload=%d",
header.sn,
header.so,
header.so + (nof_bytes - hdr_len),
(nof_bytes - hdr_len));
RlcInfo("Overlaping with SDU segment with SN=%d, SO=%d, last_byte=%d, payload=%d",
header.sn,
segm.header.so,
segm_last_byte,
segm.buf->N_bytes);
return;
}
}
}
// Write to rx window either full SDU or SDU segment
if (header.si == rlc_nr_si_field_t::full_sdu) {
int err = handle_full_data_sdu(header, payload, nof_bytes);
@ -1375,12 +1411,6 @@ void rlc_am_nr_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_bytes)
}
}
// Check poll bit
if (header.p) {
RlcInfo("status packet requested through polling bit");
do_status = true;
}
debug_state();
// 5.2.3.2.3 Actions when an AMD PDU is placed in the reception buffer
@ -1632,11 +1662,30 @@ uint32_t rlc_am_nr_rx::get_status_pdu(rlc_am_nr_status_pdu_t* status, uint32_t m
nack.so_start = last_so;
nack.so_end = segm->header.so - 1; // set to last missing byte
status->push_nack(nack);
RlcDebug("First/middle segment missing. NACK_SN=%d. SO_start=%d, SO_end=%d",
nack.nack_sn,
nack.so_start,
nack.so_end);
srsran_assert(nack.so_start <= nack.so_end, "Error: SO_start > SO_end. NACK_SN=%d", nack.nack_sn);
if (nack.so_start > nack.so_end) {
// Print segment list
for (auto segm_it = (*rx_window)[i].segments.begin(); segm_it != (*rx_window)[i].segments.end();
segm_it++) {
RlcError("Segment: segm.header.so=%d, segm.buf.N_bytes=%d", segm_it->header.so, segm_it->buf->N_bytes);
}
RlcError("Error: SO_start=%d > SO_end=%d. NACK_SN=%d. SO_start=%d, SO_end=%d, seg.so=%d",
nack.so_start,
nack.so_end,
nack.nack_sn,
nack.so_start,
nack.so_end,
segm->header.so);
srsran_assert(nack.so_start <= nack.so_end,
"Error: SO_start=%d > SO_end=%d. NACK_SN=%d",
nack.so_start,
nack.so_end,
nack.nack_sn);
} else {
RlcDebug("First/middle segment missing. NACK_SN=%d. SO_start=%d, SO_end=%d",
nack.nack_sn,
nack.so_start,
nack.so_end);
}
}
if (segm->header.si == rlc_nr_si_field_t::last_segment) {
last_segment_rx = true;

View File

@ -124,7 +124,7 @@ bool rlc_um_lte::rlc_um_lte_tx::configure(const rlc_config_t& cnfg_, std::string
uint32_t rlc_um_lte::rlc_um_lte_tx::build_data_pdu(unique_byte_buffer_t pdu, uint8_t* payload, uint32_t nof_bytes)
{
std::lock_guard<std::mutex> lock(mutex);
rlc_umd_pdu_header_t header;
rlc_umd_pdu_header_t header = {};
header.fi = RLC_FI_FIELD_START_AND_END_ALIGNED;
header.sn = vt_us;
header.N_li = 0;

View File

@ -404,7 +404,7 @@ int test_seq_of()
cbit_ref borig2(&buf[0], sizeof(buf));
uint32_t fixed_list_size = 33;
std::array<uint32_t, 33> fixed_list;
std::array<uint32_t, 33> fixed_list = {};
for (uint32_t i = 0; i < fixed_list_size; ++i) {
fixed_list[i] = i;
}

View File

@ -48,7 +48,8 @@ add_lte_test(rlc_tm_stress_test rlc_stress_test --mode=TM --loglevel 1 --random_
add_nr_test(rlc_um6_nr_stress_test rlc_stress_test --rat NR --mode=UM6 --loglevel 1)
add_nr_test(rlc_um12_nr_stress_test rlc_stress_test --rat NR --mode=UM12 --loglevel 1)
#add_nr_test(rlc_am12_nr_stress_test rlc_stress_test --rat NR --mode=AM12 --loglevel 1)
add_nr_test(rlc_am12_nr_stress_test rlc_stress_test --rat NR --mode=AM12 --loglevel 1)
add_nr_test(rlc_am12_nr_stress_test rlc_stress_test --rat NR --mode=AM18 --loglevel 1)
add_executable(rlc_um_data_test rlc_um_data_test.cc)
target_link_libraries(rlc_um_data_test srsran_rlc srsran_phy srsran_common)

View File

@ -311,6 +311,10 @@ void stress_test(stress_test_args_t args)
seed = rd();
}
if (args.seed != 0) {
seed = args.seed;
}
srsran::timer_handler timers(8);
srsran::rlc rlc1(log1.id().c_str());

View File

@ -1498,7 +1498,7 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_
args_->stack.mac.nof_prealloc_ues,
SRSENB_MAX_UES);
// Check for a forced DL EARFCN or frequency (only valid for a single cell config (Xico's favorite feature))
// Check for a forced DL EARFCN or frequency (only valid for a single cell config
if (rrc_cfg_->cell_list.size() > 0) {
if (rrc_cfg_->cell_list.size() == 1) {
auto& cfg = rrc_cfg_->cell_list.at(0);
@ -1807,6 +1807,24 @@ int set_derived_args_nr(all_args_t* args_, rrc_nr_cfg_t* rrc_nr_cfg_, phy_cfg_t*
args_->nr_stack.mac.pcap.enable = args_->stack.mac_pcap.enable;
args_->nr_stack.log = args_->stack.log;
// Sanity check for unsupported/untested configuration
for (auto& cfg : rrc_nr_cfg_->cell_list) {
if (cfg.phy_cell.carrier.nof_prb != 52) {
ERROR("Only 10 MHz bandwidth supported.");
return SRSRAN_ERROR;
}
if (rrc_nr_cfg_->is_standalone) {
if (cfg.phy_cell.carrier.dl_center_frequency_hz != 1842.5e6) {
ERROR("Only DL-ARFCN 368500 supported.");
return SRSRAN_ERROR;
}
if (cfg.duplex_mode == SRSRAN_DUPLEX_MODE_TDD) {
ERROR("Only FDD duplex supported in SA mode.");
return SRSRAN_ERROR;
}
}
}
return SRSRAN_SUCCESS;
}

View File

@ -468,10 +468,6 @@ bool mac::is_valid_rnti_unprotected(uint16_t rnti)
logger.info("RACH ignored as eNB is being shutdown");
return false;
}
if (ue_db.full()) {
logger.warning("Maximum number of connected UEs %zd connected to the eNB. Ignoring PRACH", SRSENB_MAX_UES);
return false;
}
if (not ue_db.has_space(rnti)) {
logger.info("Failed to allocate rnti=0x%x. Attempting a different rnti.", rnti);
return false;
@ -491,6 +487,10 @@ uint16_t mac::allocate_ue(uint32_t enb_cc_idx)
// Pre-check if rnti is valid
{
srsran::rwlock_read_guard read_lock(rwlock);
if (ue_db.full()) {
logger.warning("Maximum number of connected UEs %zd connected to the eNB. Ignoring PRACH", SRSENB_MAX_UES);
return SRSRAN_INVALID_RNTI;
}
if (not is_valid_rnti_unprotected(rnti)) {
continue;
}
@ -785,17 +785,20 @@ int mac::get_dl_sched(uint32_t tti_tx_dl, dl_sched_list_t& dl_sched_res_list)
// Copy PDCCH order grants
for (uint32_t i = 0; i < sched_result.po.size(); i++) {
// Copy dci info
dl_sched_res->pdsch[n].dci = sched_result.po[i].dci;
if (pcap) {
pcap->write_dl_pch(dl_sched_res->pdsch[n].data[0], sched_result.po[i].tbs, true, tti_tx_dl, enb_cc_idx);
uint16_t rnti = sched_result.po[i].dci.rnti;
if (ue_db.contains(rnti)) {
// Copy dci info
dl_sched_res->pdsch[n].dci = sched_result.po[i].dci;
if (pcap) {
pcap->write_dl_pch(dl_sched_res->pdsch[n].data[0], sched_result.po[i].tbs, true, tti_tx_dl, enb_cc_idx);
}
if (pcap_net) {
pcap_net->write_dl_pch(dl_sched_res->pdsch[n].data[0], sched_result.po[i].tbs, true, tti_tx_dl, enb_cc_idx);
}
n++;
} else {
logger.warning("Invalid PDCCH order scheduling result. User 0x%x does not exist", rnti);
}
if (pcap_net) {
pcap_net->write_dl_pch(dl_sched_res->pdsch[n].data[0], sched_result.po[i].tbs, true, tti_tx_dl, enb_cc_idx);
}
n++;
}
dl_sched_res->nof_grants = n;

View File

@ -137,7 +137,7 @@ void sched_tester::before_sched()
for (auto& it : ue_db) {
uint16_t rnti = it.first;
srsenb::sched_ue* user = it.second.get();
tester_user_results d;
tester_user_results d = {};
tti_data.ue_data.insert(std::make_pair(rnti, d));
// NOTE: ACK might have just cleared the harq for tti_info.tti_params.tti_tx_ul

View File

@ -53,7 +53,7 @@ int test_erab_setup(srsran::log_sink_spy& spy, bool qci_exists)
rrc.init(cfg, &phy, &mac, &rlc, &pdcp, &s1ap, &gtpu);
uint16_t rnti = 0x46;
sched_interface::ue_cfg_t ue_cfg;
sched_interface::ue_cfg_t ue_cfg = {};
ue_cfg.supported_cc_list.resize(1);
ue_cfg.supported_cc_list[0].active = true;
ue_cfg.supported_cc_list[0].enb_cc_idx = 0;

View File

@ -10,6 +10,8 @@
# tac: 16-bit Tracking Area Code.
# mcc: Mobile Country Code
# mnc: Mobile Network Code
# full_net_name Display Name of the Network
# short_net_name Short Display Name of the Network
# apn: Set Access Point Name (APN)
# mme_bind_addr: IP bind addr to listen for eNB S1-MME connnections
# dns_addr: DNS server address for the UEs

View File

@ -393,7 +393,7 @@ int main(int argc, char* argv[])
cout << endl << "--- Software Radio Systems EPC ---" << endl << endl;
srsran_debug_handle_crash(argc, argv);
all_args_t args;
all_args_t args = {};
parse_args(&args, argc, argv);
// Setup logging.

View File

@ -1082,7 +1082,7 @@ int fill_mib_from_enb_cfg(const rrc_cell_cfg_nr_t& cell_cfg, asn1::rrc_nr::mib_s
default:
srsran_terminate("Invalid carrier SCS=%d Hz", SRSRAN_SUBC_SPACING_NR(cell_cfg.phy_cell.carrier.scs));
}
mib.ssb_subcarrier_offset = 6; // FIXME: currently hard-coded
mib.ssb_subcarrier_offset = 6; // TODO: currently hard-coded
mib.dmrs_type_a_position.value = mib_s::dmrs_type_a_position_opts::pos2;
mib.pdcch_cfg_sib1.search_space_zero = 0;
mib.pdcch_cfg_sib1.ctrl_res_set_zero = cell_cfg.coreset0_idx;

View File

@ -1092,7 +1092,7 @@ int rrc_nr::ue::update_as_security(uint32_t lcid, bool enable_integrity = true,
return SRSRAN_ERROR;
}
// FIXME: Currently we are using the PDCP-LTE, so we need to convert from nr_as_security_cfg to as_security_config.
// TODO: Currently we are using the PDCP-LTE, so we need to convert from nr_as_security_cfg to as_security_config.
// When we start using PDCP-NR we can avoid this step.
srsran::nr_as_security_config_t tmp_cnfg = sec_ctx.get_as_sec_cfg();
srsran::as_security_config_t pdcp_cnfg = {};

View File

@ -58,7 +58,7 @@ void test_sib_generation()
enb_bearer_manager bearer_mapper;
// set cfg
rrc_nr_cfg_t rrc_cfg_nr;
rrc_nr_cfg_t rrc_cfg_nr = {};
rrc_cfg_nr.cell_list.emplace_back();
generate_default_nr_cell(rrc_cfg_nr.cell_list[0]);
rrc_cfg_nr.cell_list[0].phy_cell.carrier.pci = 500;
@ -162,7 +162,7 @@ void test_rrc_sa_connection()
rlc_cfg.um_bi_dir().dl_um_rlc.t_reassembly = t_reassembly_e::ms50;
// set cfg
rrc_nr_cfg_t rrc_cfg_nr;
rrc_nr_cfg_t rrc_cfg_nr = {};
rrc_cfg_nr.cell_list.emplace_back();
generate_default_nr_cell(rrc_cfg_nr.cell_list[0]);
rrc_cfg_nr.cell_list[0].phy_cell.carrier.pci = 500;

View File

@ -42,11 +42,11 @@ struct info_metrics_t {
struct sync_metrics_t {
typedef std::array<sync_metrics_t, SRSRAN_MAX_CARRIERS> array_t;
float ta_us;
float distance_km;
float speed_kmph;
float cfo;
float sfo;
float ta_us = 0.0;
float distance_km = 0.0;
float speed_kmph = 0.0;
float cfo = 0.0;
float sfo = 0.0;
void set(const sync_metrics_t& other)
{
@ -75,14 +75,14 @@ private:
struct ch_metrics_t {
typedef std::array<ch_metrics_t, SRSRAN_MAX_CARRIERS> array_t;
float n;
float sinr;
float rsrp;
float rsrq;
float rssi;
float ri;
float pathloss;
float sync_err;
float n = 0.0;
float sinr = 0.0;
float rsrp = 0.0;
float rsrq = 0.0;
float rssi = 0.0;
float ri = 0.0;
float pathloss = 0.0;
float sync_err = 0.0;
void set(const ch_metrics_t& other)
{
@ -120,9 +120,9 @@ private:
struct dl_metrics_t {
typedef std::array<dl_metrics_t, SRSRAN_MAX_CARRIERS> array_t;
float fec_iters;
float mcs;
float evm;
float fec_iters = 0.0;
float mcs = 0.0;
float evm = 0.0;
void set(const dl_metrics_t& other)
{

View File

@ -284,6 +284,9 @@ bool cc_worker::work_dl_regular()
// Set RNTI
ue_dl_cfg.cfg.pdsch.rnti = dci_dl.rnti;
} else {
ue_dl_cfg.cfg.pdsch.rnti = dci_dl.rnti;
ue_dl_cfg.cfg.pdsch.grant.tb[0].tbs = 0;
}
// Generate MAC grant
mac_interface_phy_lte::mac_grant_dl_t mac_grant = {};

View File

@ -442,6 +442,9 @@ void mac::new_grant_dl(uint32_t cc_idx,
action->tb[0].rv = grant.tb[0].rv;
srsran_softbuffer_rx_reset_cb(&pch_softbuffer, 1);
}
} else if (grant.is_pdcch_order) {
// if the grant is a PDCCH order then there is no associated PDSCH
action->tb[0].enabled = false;
} else if (!(grant.rnti == SRSRAN_SIRNTI && cc_idx != 0)) {
// If PDCCH for C-RNTI and RA procedure in Contention Resolution, notify it
if (grant.rnti == uernti.get_crnti() && ra_procedure.is_contention_resolution()) {

View File

@ -32,13 +32,11 @@
namespace srsue {
const char* state_str[] = {"RA: INIT: ",
"RA: PDCCH: ",
"RA: Rx: ",
const char* state_str[] = {"RA: IDLE: ",
"RA: PDCCH: ",
"RA: Rx: ",
"RA: Backoff: ",
"RA: ConRes: ",
"RA: WaitComplt: ",
"RA: Complt: "};
"RA: ConRes: "};
#define rError(fmt, ...) logger.error("%s" fmt, state_str[state], ##__VA_ARGS__)
#define rInfo(fmt, ...) logger.info("%s" fmt, state_str[state], ##__VA_ARGS__)

View File

@ -66,6 +66,7 @@ int test_add_neighbours()
TESTASSERT(list.get_neighbour_cell_handle(0, 0) == nullptr);
phy_meas_t pmeas;
pmeas.rat = srsran::srsran_rat_t::lte;
pmeas.cfo_hz = 4;
pmeas.rsrp = -20;
pmeas.pci = 1;

View File

@ -166,7 +166,7 @@ int rrc_nr_cap_request_test()
dummy_eutra dummy_eutra;
dummy_sim dummy_sim;
dummy_stack dummy_stack;
rrc_nr_args_t rrc_nr_args;
rrc_nr_args_t rrc_nr_args = {};
rrc_nr_args.supported_bands_eutra.push_back(7);
rrc_nr_args.supported_bands_nr.push_back(78);
@ -208,7 +208,7 @@ int rrc_nsa_reconfig_tdd_test()
dummy_eutra dummy_eutra;
dummy_sim dummy_sim;
dummy_stack dummy_stack;
rrc_nr_args_t rrc_nr_args;
rrc_nr_args_t rrc_nr_args = {};
TESTASSERT(rrc_nr.init(&dummy_phy,
&dummy_mac,
&dummy_rlc,
@ -311,7 +311,7 @@ int rrc_nsa_reconfig_fdd_test()
dummy_eutra dummy_eutra;
dummy_sim dummy_sim;
dummy_stack dummy_stack;
rrc_nr_args_t rrc_nr_args;
rrc_nr_args_t rrc_nr_args = {};
TESTASSERT(rrc_nr.init(&dummy_phy,
&dummy_mac,
&dummy_rlc,
@ -415,7 +415,7 @@ int rrc_nr_setup_request_test()
dummy_eutra dummy_eutra;
dummy_sim dummy_sim;
dummy_stack dummy_stack;
rrc_nr_args_t rrc_nr_args;
rrc_nr_args_t rrc_nr_args = {};
rrc_nr_args.supported_bands_nr.push_back(78);
@ -459,7 +459,7 @@ int rrc_nr_sib1_decoding_test()
dummy_eutra dummy_eutra;
dummy_sim dummy_sim;
dummy_stack dummy_stack;
rrc_nr_args_t rrc_nr_args;
rrc_nr_args_t rrc_nr_args = {};
TESTASSERT(rrc_nr.init(&dummy_phy,
&dummy_mac,
&dummy_rlc,
@ -508,7 +508,7 @@ int rrc_nr_setup_test()
dummy_eutra dummy_eutra;
dummy_sim dummy_sim;
dummy_stack dummy_stack;
rrc_nr_args_t rrc_nr_args;
rrc_nr_args_t rrc_nr_args = {};
TESTASSERT(rrc_nr.init(&dummy_phy,
&dummy_mac,
&dummy_rlc,
@ -563,7 +563,7 @@ int rrc_nr_reconfig_test()
dummy_eutra dummy_eutra;
dummy_sim dummy_sim;
dummy_stack dummy_stack;
rrc_nr_args_t rrc_nr_args;
rrc_nr_args_t rrc_nr_args = {};
TESTASSERT(rrc_nr.init(&dummy_phy,
&dummy_mac,
&dummy_rlc,

View File

@ -32,12 +32,7 @@ using namespace srsran;
namespace srsue {
pcsc_usim::pcsc_usim(srslog::basic_logger& logger) : usim_base(logger), sc(logger)
{
bzero(ck, CK_LEN);
bzero(ik, IK_LEN);
bzero(auts, IK_LEN);
}
pcsc_usim::pcsc_usim(srslog::basic_logger& logger) : usim_base(logger), sc(logger) {}
pcsc_usim::~pcsc_usim()
{

View File

@ -6,18 +6,19 @@
# RF configuration
#
# freq_offset: Uplink and Downlink optional frequency offset (in Hz)
# tx_gain: Transmit gain (dB).
# tx_gain: Transmit gain (dB).
# rx_gain: Optional receive gain (dB). If disabled, AGC if enabled
# srate: Optional fixed sampling rate (Hz), corresponding to cell bandwidth. Must be set for 5G-SA.
#
# nof_antennas: Number of antennas per carrier (all carriers have the same number of antennas)
# device_name: Device driver family. Supported options: "auto" (uses first found), "UHD" or "bladeRF"
# device_args: Arguments for the device driver. Options are "auto" or any string.
# device_name: Device driver family. Supported options: "auto" (uses first found), "UHD" or "bladeRF"
# device_args: Arguments for the device driver. Options are "auto" or any string.
# Default for UHD: "recv_frame_size=9232,send_frame_size=9232"
# Default for bladeRF: ""
# device_args_2: Arguments for the RF device driver 2.
# device_args_3: Arguments for the RF device driver 3.
# time_adv_nsamples: Transmission time advance (in number of samples) to compensate for RF delay
# from antenna to timestamp insertion.
# from antenna to timestamp insertion.
# Default "auto". B210 USRP: 100 samples, bladeRF: 27.
# continuous_tx: Transmit samples continuously to the radio or on bursts (auto/yes/no).
# Default is auto (yes for UHD, no for rest)
@ -26,6 +27,7 @@
freq_offset = 0
tx_gain = 80
#rx_gain = 40
#srate = 11.52e6
#nof_antennas = 1
@ -45,10 +47,10 @@ tx_gain = 80
#####################################################################
# EUTRA RAT configuration
#
#
# dl_earfcn: Downlink EARFCN list.
#
# Optional parameters:
# Optional parameters:
# dl_freq: Override DL frequency corresponding to dl_earfcn
# ul_freq: Override UL frequency corresponding to dl_earfcn
# nof_carriers: Number of carriers
@ -59,8 +61,8 @@ dl_earfcn = 3350
#####################################################################
# NR RAT configuration
#
# Optional parameters:
#
# Optional parameters:
# bands: List of support NR bands seperated by a comma (default 78)
# nof_carriers: Number of NR carriers (must be at least 1 for NR support)
#####################################################################
@ -71,19 +73,19 @@ dl_earfcn = 3350
#####################################################################
# Packet capture configuration
#
# Packet capture is supported at the MAC, MAC_NR, and NAS layer.
# MAC-layer packets are captured to file a the compact format decoded
# by the Wireshark. For decoding, use the UDP dissector and the UDP
# heuristic dissection. Edit the preferences (Edit > Preferences >
# Protocols > DLT_USER) for DLT_USER to add an entry for DLT=149 with
# Packet capture is supported at the MAC, MAC_NR, and NAS layer.
# MAC-layer packets are captured to file a the compact format decoded
# by the Wireshark. For decoding, use the UDP dissector and the UDP
# heuristic dissection. Edit the preferences (Edit > Preferences >
# Protocols > DLT_USER) for DLT_USER to add an entry for DLT=149 with
# Protocol=udp. Further, enable the heuristic dissection in UDP under:
# Analyze > Enabled Protocols > MAC-LTE > mac_lte_udp and MAC-NR > mac_nr_udp
# For more information see: https://wiki.wireshark.org/MAC-LTE
# Using the same filename for mac_filename and mac_nr_filename writes both
# MAC-LTE and MAC-NR to the same file allowing a better analysis.
# MAC-LTE and MAC-NR to the same file allowing a better analysis.
# NAS-layer packets are dissected with DLT=148, and Protocol = nas-eps.
#
# enable: Enable packet captures of layers (mac/mac_nr/nas/none) multiple option list
# enable: Enable packet captures of layers (mac/mac_nr/nas/none) multiple option list
# mac_filename: File path to use for MAC packet capture
# mac_nr_filename: File path to use for MAC NR packet capture
# nas_filename: File path to use for NAS packet capture
@ -136,12 +138,12 @@ file_max_size = -1
#####################################################################
[usim]
mode = soft
algo = xor
#opc = 63BFA50EE6523365FF14C1F45F88737D
algo = milenage
opc = 63BFA50EE6523365FF14C1F45F88737D
k = 00112233445566778899aabbccddeeff
imsi = 001010123456789
imsi = 001010123456780
imei = 353490069873319
#reader =
#reader =
#pin = 1234
#####################################################################
@ -303,18 +305,18 @@ enable = false
#
# rx_gain_offset: RX Gain offset to add to rx_gain to calibrate RSRP readings
# prach_gain: PRACH gain (dB). If defined, forces a gain for the tranmsission of PRACH only.,
# Default is to use tx_gain in [rf] section.
# cqi_max: Upper bound on the maximum CQI to be reported. Default 15.
# Default is to use tx_gain in [rf] section.
# cqi_max: Upper bound on the maximum CQI to be reported. Default 15.
# cqi_fixed: Fixes the reported CQI to a constant value. Default disabled.
# snr_ema_coeff: Sets the SNR exponential moving average coefficient (Default 0.1)
# snr_estim_alg: Sets the noise estimation algorithm. (Default refs)
# Options: pss: use difference between received and known pss signal,
# Options: pss: use difference between received and known pss signal,
# refs: use difference between noise references and noiseless (after filtering)
# empty: use empty subcarriers in the boarder of pss/sss signal
# pdsch_max_its: Maximum number of turbo decoder iterations (Default 4)
# pdsch_meas_evm: Measure PDSCH EVM, increases CPU load (default false)
# nof_phy_threads: Selects the number of PHY threads (maximum 4, minimum 1, default 3)
# equalizer_mode: Selects equalizer mode. Valid modes are: "mmse", "zf" or any
# equalizer_mode: Selects equalizer mode. Valid modes are: "mmse", "zf" or any
# non-negative real number to indicate a regularized zf coefficient.
# Default is MMSE.
# correct_sync_error: Channel estimator measures and pre-compensates time synchronization error. Increases CPU usage,
@ -322,7 +324,7 @@ enable = false
# sfo_ema: EMA coefficient to average sample offsets used to compute SFO
# sfo_correct_period: Period in ms to correct sample time to adjust for SFO
# sss_algorithm: Selects the SSS estimation algorithm. Can choose between
# {full, partial, diff}.
# {full, partial, diff}.
# estimator_fil_auto: The channel estimator smooths the channel estimate with an adaptative filter.
# estimator_fil_stddev: Sets the channel estimator smooth gaussian filter standard deviation.
# estimator_fil_order: Sets the channel estimator smooth gaussian filter order (even values perform better).