Merge branch 'next' into agpl_next

master
Codebot 3 years ago committed by SRS codebot
commit c00f44037c

@ -83,7 +83,7 @@ option(ENABLE_ZMQ_TEST "Enable ZMQ based E2E tests" OFF)
option(BUILD_STATIC "Attempt to statically link external deps" OFF) option(BUILD_STATIC "Attempt to statically link external deps" OFF)
option(RPATH "Enable RPATH" OFF) option(RPATH "Enable RPATH" OFF)
option(ENABLE_ASAN "Enable gcc/clang address sanitizer" OFF) option(ENABLE_ASAN "Enable gcc/clang address sanitizer" OFF)
option(ENABLE_GCOV "Enable gcc/clang address sanitizer" OFF) option(ENABLE_GCOV "Enable gcov" OFF)
option(ENABLE_MSAN "Enable clang memory sanitizer" OFF) option(ENABLE_MSAN "Enable clang memory sanitizer" OFF)
option(ENABLE_TSAN "Enable clang thread sanitizer" OFF) option(ENABLE_TSAN "Enable clang thread sanitizer" OFF)
option(ENABLE_TIDY "Enable clang tidy" OFF) option(ENABLE_TIDY "Enable clang tidy" OFF)

@ -1,6 +1,7 @@
srsRAN srsRAN
====== ======
[![Build Status](https://github.com/srsran/srsRAN/actions/workflows/ccpp.yml/badge.svg?branch=master)](https://github.com/srsran/srsRAN/actions)
[![Build Status](https://app.travis-ci.com/srsran/srsRAN.svg?branch=master)](https://app.travis-ci.com/github/srsran/srsRAN) [![Build Status](https://app.travis-ci.com/srsran/srsRAN.svg?branch=master)](https://app.travis-ci.com/github/srsran/srsRAN)
[![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/srsran/srsRAN.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/srsran/srsRAN/context:cpp) [![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/srsran/srsRAN.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/srsran/srsRAN/context:cpp)
[![Coverity](https://scan.coverity.com/projects/23045/badge.svg)](https://scan.coverity.com/projects/srsran) [![Coverity](https://scan.coverity.com/projects/23045/badge.svg)](https://scan.coverity.com/projects/srsran)

@ -120,12 +120,7 @@ int pdcp::add_bearer(uint32_t lcid, const pdcp_config_t& cfg)
if (cfg.rat == srsran::srsran_rat_t::lte) { if (cfg.rat == srsran::srsran_rat_t::lte) {
entity.reset(new pdcp_entity_lte{rlc, rrc, gw, task_sched, logger, lcid}); entity.reset(new pdcp_entity_lte{rlc, rrc, gw, task_sched, logger, lcid});
} else if (cfg.rat == srsran::srsran_rat_t::nr) { } else if (cfg.rat == srsran::srsran_rat_t::nr) {
#ifdef USE_PDCP_NR
#pragma message "Compiling with PDCP NR entity"
entity.reset(new pdcp_entity_nr{rlc, rrc, gw, task_sched, logger, lcid}); entity.reset(new pdcp_entity_nr{rlc, rrc, gw, task_sched, logger, lcid});
#else
entity.reset(new pdcp_entity_lte{rlc, rrc, gw, task_sched, logger, lcid});
#endif
} }
if (not entity->configure(cfg)) { if (not entity->configure(cfg)) {

@ -58,13 +58,17 @@ bool pdcp_entity_nr::configure(const pdcp_config_t& cnfg_)
rlc_mode = rlc->rb_is_um(lcid) ? rlc_mode_t::UM : rlc_mode_t::AM; rlc_mode = rlc->rb_is_um(lcid) ? rlc_mode_t::UM : rlc_mode_t::AM;
// Timers // t-Reordering timer
if (cfg.t_reordering != pdcp_t_reordering_t::infinity) {
reordering_timer = task_sched.get_unique_timer(); reordering_timer = task_sched.get_unique_timer();
// configure timer
if (static_cast<uint32_t>(cfg.t_reordering) > 0) { if (static_cast<uint32_t>(cfg.t_reordering) > 0) {
reordering_timer.set(static_cast<uint32_t>(cfg.t_reordering), *reordering_fnc); reordering_timer.set(static_cast<uint32_t>(cfg.t_reordering), *reordering_fnc);
} }
} else if (rlc_mode == rlc_mode_t::UM) {
logger.warning("%s possible PDCP-NR misconfiguration: using infinite re-ordering timer with RLC UM bearer.",
rb_name);
}
active = true; active = true;
logger.info("%s PDCP-NR entity configured. SN_LEN=%d, Discard timer %d, Re-ordering timer %d, RLC=%s, RAT=%s", logger.info("%s PDCP-NR entity configured. SN_LEN=%d, Discard timer %d, Re-ordering timer %d, RLC=%s, RAT=%s",
rb_name, rb_name,
@ -276,10 +280,13 @@ void pdcp_entity_nr::write_pdu(unique_byte_buffer_t pdu)
reordering_timer.stop(); reordering_timer.stop();
} }
if (cfg.t_reordering != pdcp_t_reordering_t::infinity) {
if (not reordering_timer.is_running() and rx_deliv < rx_next) { if (not reordering_timer.is_running() and rx_deliv < rx_next) {
rx_reord = rx_next; rx_reord = rx_next;
reordering_timer.run(); reordering_timer.run();
} }
}
logger.debug("Rx PDCP state - RX_NEXT=%u, RX_DELIV=%u, RX_REORD=%u", rx_next, rx_deliv, rx_reord); logger.debug("Rx PDCP state - RX_NEXT=%u, RX_DELIV=%u, RX_REORD=%u", rx_next, rx_deliv, rx_reord);
} }

@ -351,6 +351,12 @@ rlc_am_nr_read_status_pdu_12bit_sn(const uint8_t* payload, const uint32_t nof_by
ptr++; ptr++;
while (e1 != 0) { while (e1 != 0) {
// check buffer headroom
if (uint32_t(ptr - payload) >= nof_bytes) {
fprintf(stderr, "Malformed PDU, trying to read more bytes than it is available\n");
return 0;
}
// E1 flag set, read a NACK_SN // E1 flag set, read a NACK_SN
rlc_status_nack_t nack = {}; rlc_status_nack_t nack = {};
nack.nack_sn = (*ptr & 0xff) << 4; nack.nack_sn = (*ptr & 0xff) << 4;
@ -385,10 +391,6 @@ rlc_am_nr_read_status_pdu_12bit_sn(const uint8_t* payload, const uint32_t nof_by
ptr++; ptr++;
} }
status->push_nack(nack); status->push_nack(nack);
if (uint32_t(ptr - payload) > nof_bytes) {
fprintf(stderr, "Malformed PDU, trying to read more bytes than it is available\n");
return 0;
}
} }
return SRSRAN_SUCCESS; return SRSRAN_SUCCESS;
@ -430,6 +432,12 @@ rlc_am_nr_read_status_pdu_18bit_sn(const uint8_t* payload, const uint32_t nof_by
ptr++; ptr++;
while (e1 != 0) { while (e1 != 0) {
// check buffer headroom
if (uint32_t(ptr - payload) >= nof_bytes) {
fprintf(stderr, "Malformed PDU, trying to read more bytes than it is available\n");
return 0;
}
// E1 flag set, read a NACK_SN // E1 flag set, read a NACK_SN
rlc_status_nack_t nack = {}; rlc_status_nack_t nack = {};
@ -467,10 +475,6 @@ rlc_am_nr_read_status_pdu_18bit_sn(const uint8_t* payload, const uint32_t nof_by
ptr++; ptr++;
} }
status->push_nack(nack); status->push_nack(nack);
if (uint32_t(ptr - payload) > nof_bytes) {
fprintf(stderr, "Malformed PDU, trying to read more bytes than it is available\n");
return 0;
}
} }
return SRSRAN_SUCCESS; return SRSRAN_SUCCESS;

@ -53,7 +53,7 @@ bool compute_diff_radio_bearer_cfg(const rrc_nr_cfg_t& cfg,
asn1::rrc_nr::radio_bearer_cfg_s& diff); asn1::rrc_nr::radio_bearer_cfg_s& diff);
/// Apply radioBearerConfig updates to CellGroupConfig /// Apply radioBearerConfig updates to CellGroupConfig
void fill_cellgroup_with_radio_bearer_cfg(const rrc_nr_cfg_t& cfg, int fill_cellgroup_with_radio_bearer_cfg(const rrc_nr_cfg_t& cfg,
uint32_t rnti, uint32_t rnti,
const enb_bearer_manager& bearer_mapper, const enb_bearer_manager& bearer_mapper,
const asn1::rrc_nr::radio_bearer_cfg_s& bearers, const asn1::rrc_nr::radio_bearer_cfg_s& bearers,

@ -196,6 +196,7 @@ private:
sched_nr_interface::ue_cfg_t uecfg{}; sched_nr_interface::ue_cfg_t uecfg{};
const uint32_t drb1_lcid = 4; const uint32_t drb1_lcid = 4;
uint32_t drb1_five_qi = 0; /// selected by 5GC
// Security helper // Security helper
srsgnb::nr_security_context sec_ctx; srsgnb::nr_security_context sec_ctx;

@ -260,6 +260,11 @@ bool ngap::ue::send_ue_context_release_request(asn1::ngap::cause_c cause)
return false; return false;
} }
if (not ctxt.amf_ue_ngap_id.has_value()) {
logger.warning("Can't send release request. User 0x%x has no AMF UE Id.", ctxt.rnti);
return false;
}
if (was_ue_context_release_requested()) { if (was_ue_context_release_requested()) {
// let timeout auto-remove user. // let timeout auto-remove user.
return false; return false;

@ -1340,7 +1340,7 @@ bool compute_diff_radio_bearer_cfg(const rrc_nr_cfg_t& cfg,
diff.drb_to_add_mod_list.size() > 0; diff.drb_to_add_mod_list.size() > 0;
} }
void fill_cellgroup_with_radio_bearer_cfg(const rrc_nr_cfg_t& cfg, int fill_cellgroup_with_radio_bearer_cfg(const rrc_nr_cfg_t& cfg,
const uint32_t rnti, const uint32_t rnti,
const enb_bearer_manager& bearer_mapper, const enb_bearer_manager& bearer_mapper,
const asn1::rrc_nr::radio_bearer_cfg_s& bearers, const asn1::rrc_nr::radio_bearer_cfg_s& bearers,
@ -1359,13 +1359,19 @@ void fill_cellgroup_with_radio_bearer_cfg(const rrc_nr_cfg_t&
out.rlc_bearer_to_add_mod_list.push_back({}); out.rlc_bearer_to_add_mod_list.push_back({});
uint32_t lcid = drb.drb_id + (int)srsran::nr_srb::count - 1; uint32_t lcid = drb.drb_id + (int)srsran::nr_srb::count - 1;
enb_bearer_manager::radio_bearer_t rb = bearer_mapper.get_lcid_bearer(rnti, lcid); enb_bearer_manager::radio_bearer_t rb = bearer_mapper.get_lcid_bearer(rnti, lcid);
if (rb.is_valid() and cfg.five_qi_cfg.find(rb.five_qi) != cfg.five_qi_cfg.end()) {
fill_drb(cfg, rb, (srsran::nr_drb)drb.drb_id, out.rlc_bearer_to_add_mod_list.back()); fill_drb(cfg, rb, (srsran::nr_drb)drb.drb_id, out.rlc_bearer_to_add_mod_list.back());
} else {
return SRSRAN_ERROR;
}
} }
// Release DRBs // Release DRBs
for (uint8_t drb_id : bearers.drb_to_release_list) { for (uint8_t drb_id : bearers.drb_to_release_list) {
out.rlc_bearer_to_release_list.push_back(drb_id); out.rlc_bearer_to_release_list.push_back(drb_id);
} }
return SRSRAN_SUCCESS;
} }
} // namespace srsenb } // namespace srsenb

@ -909,8 +909,13 @@ void rrc_nr::ue::handle_rrc_reestablishment_request(const asn1::rrc_nr::rrc_rees
// compute config and create SRB1 for new user // compute config and create SRB1 for new user
asn1::rrc_nr::radio_bearer_cfg_s dummy_radio_bearer_cfg; // just to compute difference, it's never sent to UE asn1::rrc_nr::radio_bearer_cfg_s dummy_radio_bearer_cfg; // just to compute difference, it's never sent to UE
compute_diff_radio_bearer_cfg(parent->cfg, radio_bearer_cfg, next_radio_bearer_cfg, dummy_radio_bearer_cfg); compute_diff_radio_bearer_cfg(parent->cfg, radio_bearer_cfg, next_radio_bearer_cfg, dummy_radio_bearer_cfg);
fill_cellgroup_with_radio_bearer_cfg( if (fill_cellgroup_with_radio_bearer_cfg(
parent->cfg, old_rnti, *parent->bearer_mapper, dummy_radio_bearer_cfg, next_cell_group_cfg); parent->cfg, old_rnti, *parent->bearer_mapper, dummy_radio_bearer_cfg, next_cell_group_cfg) !=
SRSRAN_SUCCESS) {
logger.error("Couldn't fill cellGroupCfg during RRC Reestablishment");
send_rrc_reject(max_wait_time_secs);
return;
}
// send RRC Reestablishment message and restore bearer configuration // send RRC Reestablishment message and restore bearer configuration
send_connection_reest(old_ue->sec_ctx.get_ncc()); send_connection_reest(old_ue->sec_ctx.get_ncc());
@ -929,6 +934,7 @@ void rrc_nr::ue::handle_rrc_reestablishment_request(const asn1::rrc_nr::rrc_rees
// Reestablish E-RABs of old rnti later, during ConnectionReconfiguration // Reestablish E-RABs of old rnti later, during ConnectionReconfiguration
// bearer_list.reestablish_bearers(std::move(old_ue->bearer_list)); // bearer_list.reestablish_bearers(std::move(old_ue->bearer_list));
drb1_five_qi = old_ue->drb1_five_qi;
// remove old RNTI // remove old RNTI
old_ue->deactivate_bearers(); old_ue->deactivate_bearers();
@ -948,12 +954,14 @@ void rrc_nr::ue::send_connection_reest(uint8_t ncc)
// set NCC // set NCC
reest.next_hop_chaining_count = ncc; reest.next_hop_chaining_count = ncc;
// add PDCP bearers
update_pdcp_bearers(next_radio_bearer_cfg, next_cell_group_cfg);
// add RLC bearers // add RLC bearers
update_rlc_bearers(next_cell_group_cfg); update_rlc_bearers(next_cell_group_cfg);
// add PDCP bearers
// this is done after updating the RLC bearers,
// so the PDCP can query the RLC mode
update_pdcp_bearers(next_radio_bearer_cfg, next_cell_group_cfg);
// add MAC bearers // add MAC bearers
update_mac(next_cell_group_cfg, false); update_mac(next_cell_group_cfg, false);
@ -1003,8 +1011,14 @@ void rrc_nr::ue::send_rrc_setup()
// - Setup masterCellGroup // - Setup masterCellGroup
// - Derive master cell group config bearers // - Derive master cell group config bearers
fill_cellgroup_with_radio_bearer_cfg( if (fill_cellgroup_with_radio_bearer_cfg(
parent->cfg, rnti, *parent->bearer_mapper, setup_ies.radio_bearer_cfg, next_cell_group_cfg); parent->cfg, rnti, *parent->bearer_mapper, setup_ies.radio_bearer_cfg, next_cell_group_cfg) !=
SRSRAN_SUCCESS) {
logger.error("Couldn't fill cellGroupCfg during RRC Setup");
send_rrc_reject(max_wait_time_secs);
return;
}
// - Pack masterCellGroup into container // - Pack masterCellGroup into container
srsran::unique_byte_buffer_t pdu = parent->pack_into_pdu(next_cell_group_cfg, __FUNCTION__); srsran::unique_byte_buffer_t pdu = parent->pack_into_pdu(next_cell_group_cfg, __FUNCTION__);
if (pdu == nullptr) { if (pdu == nullptr) {
@ -1019,12 +1033,14 @@ void rrc_nr::ue::send_rrc_setup()
logger.debug("Containerized MasterCellGroup: %s", js.to_string().c_str()); logger.debug("Containerized MasterCellGroup: %s", js.to_string().c_str());
} }
// add PDCP bearers
update_pdcp_bearers(setup_ies.radio_bearer_cfg, next_cell_group_cfg);
// add RLC bearers // add RLC bearers
update_rlc_bearers(next_cell_group_cfg); update_rlc_bearers(next_cell_group_cfg);
// add PDCP bearers
// this is done after updating the RLC bearers,
// so the PDCP can query the RLC mode
update_pdcp_bearers(next_radio_bearer_cfg, next_cell_group_cfg);
// add MAC bearers // add MAC bearers
update_mac(next_cell_group_cfg, false); update_mac(next_cell_group_cfg, false);
@ -1146,8 +1162,12 @@ void rrc_nr::ue::send_rrc_reconfiguration()
// Fill masterCellGroup // Fill masterCellGroup
cell_group_cfg_s master_cell_group; cell_group_cfg_s master_cell_group;
master_cell_group.cell_group_id = 0; master_cell_group.cell_group_id = 0;
fill_cellgroup_with_radio_bearer_cfg( if (fill_cellgroup_with_radio_bearer_cfg(
parent->cfg, rnti, *parent->bearer_mapper, ies.radio_bearer_cfg, master_cell_group); parent->cfg, rnti, *parent->bearer_mapper, ies.radio_bearer_cfg, master_cell_group) != SRSRAN_SUCCESS) {
logger.error("Couldn't fill cellGroupCfg during RRC Reconfiguration");
parent->ngap->user_release_request(rnti, asn1::ngap::cause_radio_network_opts::radio_res_not_available);
return;
}
// Pack masterCellGroup into container // Pack masterCellGroup into container
srsran::unique_byte_buffer_t pdu = parent->pack_into_pdu(master_cell_group, __FUNCTION__); srsran::unique_byte_buffer_t pdu = parent->pack_into_pdu(master_cell_group, __FUNCTION__);
@ -1171,6 +1191,8 @@ void rrc_nr::ue::send_rrc_reconfiguration()
update_rlc_bearers(master_cell_group); update_rlc_bearers(master_cell_group);
// add PDCP bearers // add PDCP bearers
// this is done after updating the RLC bearers,
// so the PDCP can query the RLC mode
update_pdcp_bearers(ies.radio_bearer_cfg, master_cell_group); update_pdcp_bearers(ies.radio_bearer_cfg, master_cell_group);
} }
@ -1258,6 +1280,7 @@ void rrc_nr::ue::handle_rrc_reestablishment_complete(const asn1::rrc_nr::rrc_ree
for (const auto& drb : next_radio_bearer_cfg.drb_to_add_mod_list) { for (const auto& drb : next_radio_bearer_cfg.drb_to_add_mod_list) {
uint16_t lcid = drb1_lcid; uint16_t lcid = drb1_lcid;
parent->bearer_mapper->add_eps_bearer(rnti, lcid - 3, srsran::srsran_rat_t::nr, lcid); parent->bearer_mapper->add_eps_bearer(rnti, lcid - 3, srsran::srsran_rat_t::nr, lcid);
parent->bearer_mapper->set_five_qi(rnti, lcid - 3, drb1_five_qi);
logger.info("Established EPS bearer for LCID %u and RNTI 0x%x", lcid, rnti); logger.info("Established EPS bearer for LCID %u and RNTI 0x%x", lcid, rnti);
} }
@ -1310,6 +1333,11 @@ void rrc_nr::ue::establish_eps_bearer(uint32_t pdu_session_id,
uint32_t lcid, uint32_t lcid,
uint32_t five_qi) uint32_t five_qi)
{ {
if (parent->cfg.five_qi_cfg.find(five_qi) == parent->cfg.five_qi_cfg.end()) {
parent->logger.error("No bearer config for 5QI %d present. Aborting DRB addition.", five_qi);
return;
}
// Enqueue NAS PDU // Enqueue NAS PDU
srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer(); srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer();
if (pdu == nullptr) { if (pdu == nullptr) {
@ -1345,6 +1373,9 @@ void rrc_nr::ue::establish_eps_bearer(uint32_t pdu_session_id,
rnti, lcid - 3, srsran::srsran_rat_t::nr, lcid); // TODO: configurable bearer id <-> lcid mapping rnti, lcid - 3, srsran::srsran_rat_t::nr, lcid); // TODO: configurable bearer id <-> lcid mapping
parent->bearer_mapper->set_five_qi(rnti, lcid - 3, five_qi); parent->bearer_mapper->set_five_qi(rnti, lcid - 3, five_qi);
// store 5QI for possible reestablishment of DRB
drb1_five_qi = five_qi;
logger.info("Established EPS bearer for LCID %u and RNTI 0x%x", lcid, rnti); logger.info("Established EPS bearer for LCID %u and RNTI 0x%x", lcid, rnti);
} }

@ -115,7 +115,7 @@ int test_rrc_setup()
rrc_nr rrc_obj(&task_sched); rrc_nr rrc_obj(&task_sched);
// set cfg // set cfg
rrc_nr_cfg_t rrc_cfg_nr; rrc_nr_cfg_t rrc_cfg_nr = {};
rrc_cfg_nr.cell_list.emplace_back(); rrc_cfg_nr.cell_list.emplace_back();
generate_default_nr_cell(rrc_cfg_nr.cell_list[0]); generate_default_nr_cell(rrc_cfg_nr.cell_list[0]);
rrc_cfg_nr.cell_list[0].phy_cell.carrier.pci = 500; rrc_cfg_nr.cell_list[0].phy_cell.carrier.pci = 500;

@ -333,13 +333,13 @@ srsran::proc_outcome_t rrc_nr::connection_setup_proc::init(const asn1::rrc_nr::r
// Stop T300 // Stop T300
rrc_handle.t300.stop(); rrc_handle.t300.stop();
// Apply the Radio Bearer configuration // Apply the Cell Group configuration
if (!rrc_handle.apply_radio_bearer_cfg(radio_bearer_cfg_)) { if (!rrc_handle.update_cell_group_cfg(cell_group_)) {
return proc_outcome_t::error; return proc_outcome_t::error;
} }
// Apply the Cell Group configuration // Apply the Radio Bearer configuration
if (!rrc_handle.update_cell_group_cfg(cell_group_)) { if (!rrc_handle.apply_radio_bearer_cfg(radio_bearer_cfg_)) {
return proc_outcome_t::error; return proc_outcome_t::error;
} }

Loading…
Cancel
Save