nr,gnb,rrc: add extra fields to RRC setup and RRC setup complete messages.

This commit is contained in:
Francisco 2021-11-14 17:50:18 +00:00 committed by Francisco Paisana
parent 5a3e99fb58
commit 4aa5fe41df
8 changed files with 406 additions and 99 deletions

View File

@ -18,8 +18,14 @@
namespace srsenb {
using rlc_bearer_list_t = asn1::rrc_nr::cell_group_cfg_s::rlc_bearer_to_add_mod_list_l_;
// NSA helpers
int fill_sp_cell_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, asn1::rrc_nr::sp_cell_cfg_s& sp_cell);
// SA helpers
int fill_master_cell_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, asn1::rrc_nr::cell_group_cfg_s& out);
int fill_mib_from_enb_cfg(const rrc_nr_cfg_t& cfg, asn1::rrc_nr::mib_s& mib);
int fill_sib1_from_enb_cfg(const rrc_nr_cfg_t& cfg, asn1::rrc_nr::sib1_s& sib1);

View File

@ -138,11 +138,12 @@ private:
// vars
struct cell_ctxt_t {
asn1::rrc_nr::mib_s mib;
asn1::rrc_nr::sib1_s sib1;
asn1::rrc_nr::sys_info_ies_s::sib_type_and_info_l_ sibs;
srsran::unique_byte_buffer_t mib_buffer = nullptr;
std::vector<srsran::unique_byte_buffer_t> sib_buffer;
asn1::rrc_nr::mib_s mib;
asn1::rrc_nr::sib1_s sib1;
asn1::rrc_nr::sys_info_ies_s::sib_type_and_info_l_ sibs;
srsran::unique_byte_buffer_t mib_buffer = nullptr;
std::vector<srsran::unique_byte_buffer_t> sib_buffer;
std::unique_ptr<const asn1::rrc_nr::cell_group_cfg_s> master_cell_group;
};
std::unique_ptr<cell_ctxt_t> cell_ctxt;
rnti_map_t<std::unique_ptr<ue> > users;

View File

@ -66,9 +66,6 @@ public:
void handle_ul_information_transfer(const asn1::rrc_nr::ul_info_transfer_s& msg);
private:
rrc_nr* parent = nullptr;
uint16_t rnti = SRSRAN_INVALID_RNTI;
void send_dl_ccch(const asn1::rrc_nr::dl_ccch_msg_s& dl_ccch_msg);
void send_dl_dcch(srsran::nr_srb srb, const asn1::rrc_nr::dl_dcch_msg_s& dl_dcch_msg);
@ -93,7 +90,6 @@ private:
int pack_sp_cell_cfg_ded(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack);
int pack_sp_cell_cfg_ded_init_dl_bwp(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack);
int pack_sp_cell_cfg_ded_init_dl_bwp_pdsch_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack);
int pack_sp_cell_cfg_ded_init_dl_bwp_radio_link_monitoring(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack);
int pack_sp_cell_cfg_ded_ul_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack);
@ -123,6 +119,8 @@ private:
int add_drb();
bool init_pucch();
// logging helpers
template <class M>
void log_rrc_message(srsran::nr_srb srb,
@ -133,6 +131,11 @@ private:
template <class M>
void log_rrc_container(const direction_t dir, srsran::const_byte_span pdu, const M& msg, const char* msg_type);
// args
rrc_nr* parent = nullptr;
srslog::basic_logger& logger;
uint16_t rnti = SRSRAN_INVALID_RNTI;
// state
rrc_nr_state_t state = rrc_nr_state_t::RRC_IDLE;
uint8_t transaction_id = 0;
@ -147,6 +150,12 @@ private:
const uint32_t drb1_lcid = 4;
// SA specific variables
struct ctxt_t {
uint64_t setup_ue_id = -1;
asn1::rrc_nr::establishment_cause_opts connection_cause;
} ctxt;
// NSA specific variables
bool endc = false;
uint16_t eutra_rnti = SRSRAN_INVALID_RNTI;

View File

@ -228,7 +228,8 @@ int fill_pdcch_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, pdcch_cfg_
{
auto& cell_cfg = cfg.cell_list.at(cc);
for (uint32_t cs_idx = 0; cs_idx < SRSRAN_UE_DL_NR_MAX_NOF_CORESET; cs_idx++) {
// Note: Skip CORESET#0
for (uint32_t cs_idx = 1; cs_idx < SRSRAN_UE_DL_NR_MAX_NOF_CORESET; cs_idx++) {
if (cell_cfg.phy_cell.pdcch.coreset_present[cs_idx]) {
auto& coreset_cfg = cell_cfg.phy_cell.pdcch.coreset[cs_idx];
@ -263,7 +264,8 @@ int fill_pdcch_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, pdcch_cfg_
}
}
for (uint32_t ss_idx = 0; ss_idx < SRSRAN_UE_DL_NR_MAX_NOF_SEARCH_SPACE; ss_idx++) {
// Note: Skip SearchSpace#0
for (uint32_t ss_idx = 1; ss_idx < SRSRAN_UE_DL_NR_MAX_NOF_SEARCH_SPACE; ss_idx++) {
if (cell_cfg.phy_cell.pdcch.search_space_present[ss_idx]) {
// search spaces
auto& search_space_cfg = cell_cfg.phy_cell.pdcch.search_space[ss_idx];
@ -309,17 +311,204 @@ int fill_pdcch_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, pdcch_cfg_
return SRSRAN_SUCCESS;
}
void fill_pdsch_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, pdsch_cfg_s& out)
{
out.dmrs_dl_for_pdsch_map_type_a_present = true;
out.dmrs_dl_for_pdsch_map_type_a.set_setup();
out.dmrs_dl_for_pdsch_map_type_a.setup().dmrs_add_position_present = true;
out.dmrs_dl_for_pdsch_map_type_a.setup().dmrs_add_position = dmrs_dl_cfg_s::dmrs_add_position_opts::pos1;
out.tci_states_to_add_mod_list_present = true;
out.tci_states_to_add_mod_list.resize(1);
out.tci_states_to_add_mod_list[0].tci_state_id = 0;
out.tci_states_to_add_mod_list[0].qcl_type1.ref_sig.set_ssb();
out.tci_states_to_add_mod_list[0].qcl_type1.ref_sig.ssb() = 0;
out.tci_states_to_add_mod_list[0].qcl_type1.qcl_type = asn1::rrc_nr::qcl_info_s::qcl_type_opts::type_d;
out.res_alloc = pdsch_cfg_s::res_alloc_opts::res_alloc_type1;
out.rbg_size = pdsch_cfg_s::rbg_size_opts::cfg1;
out.prb_bundling_type.set_static_bundling();
out.prb_bundling_type.static_bundling().bundle_size_present = true;
out.prb_bundling_type.static_bundling().bundle_size =
pdsch_cfg_s::prb_bundling_type_c_::static_bundling_s_::bundle_size_opts::wideband;
// ZP-CSI
out.zp_csi_rs_res_to_add_mod_list_present = false; // TEMP
out.zp_csi_rs_res_to_add_mod_list.resize(1);
out.zp_csi_rs_res_to_add_mod_list[0].zp_csi_rs_res_id = 0;
out.zp_csi_rs_res_to_add_mod_list[0].res_map.freq_domain_alloc.set_row4();
out.zp_csi_rs_res_to_add_mod_list[0].res_map.freq_domain_alloc.row4().from_number(0b100);
out.zp_csi_rs_res_to_add_mod_list[0].res_map.nrof_ports = asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p4;
out.zp_csi_rs_res_to_add_mod_list[0].res_map.first_ofdm_symbol_in_time_domain = 8;
out.zp_csi_rs_res_to_add_mod_list[0].res_map.cdm_type = asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::fd_cdm2;
out.zp_csi_rs_res_to_add_mod_list[0].res_map.density.set_one();
out.zp_csi_rs_res_to_add_mod_list[0].res_map.freq_band.start_rb = 0;
out.zp_csi_rs_res_to_add_mod_list[0].res_map.freq_band.nrof_rbs = cfg.cell_list[cc].phy_cell.carrier.nof_prb;
out.zp_csi_rs_res_to_add_mod_list[0].periodicity_and_offset_present = true;
out.zp_csi_rs_res_to_add_mod_list[0].periodicity_and_offset.set_slots80() = 1;
out.p_zp_csi_rs_res_set_present = false; // TEMP
out.p_zp_csi_rs_res_set.set_setup();
out.p_zp_csi_rs_res_set.setup().zp_csi_rs_res_set_id = 0;
out.p_zp_csi_rs_res_set.setup().zp_csi_rs_res_id_list.resize(1);
out.p_zp_csi_rs_res_set.setup().zp_csi_rs_res_id_list[0] = 0;
}
/// Fill InitDlBwp with gNB config
int fill_init_dl_bwp_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, bwp_dl_ded_s& init_dl_bwp)
{
init_dl_bwp.pdcch_cfg_present = true;
HANDLE_ERROR(fill_pdcch_cfg_from_enb_cfg(cfg, cc, init_dl_bwp.pdcch_cfg.set_setup()));
init_dl_bwp.pdsch_cfg_present = true;
fill_pdsch_cfg_from_enb_cfg(cfg, cc, init_dl_bwp.pdsch_cfg.set_setup());
// TODO: ADD missing fields
return SRSRAN_SUCCESS;
}
void fill_pucch_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, pucch_cfg_s& out)
{
// Make 2 PUCCH resource sets
out.res_set_to_add_mod_list_present = true;
out.res_set_to_add_mod_list.resize(2);
// Make PUCCH resource set for 1-2 bit
for (uint32_t set_id = 0; set_id < out.res_set_to_add_mod_list.size(); ++set_id) {
auto& res_set = out.res_set_to_add_mod_list[set_id];
res_set.pucch_res_set_id = set_id;
res_set.res_list.resize(8);
for (uint32_t i = 0; i < res_set.res_list.size(); ++i) {
if (cfg.is_standalone) {
res_set.res_list[i] = i + set_id * 8;
} else {
res_set.res_list[i] = set_id;
}
}
}
// Make 3 possible resources
out.res_to_add_mod_list_present = true;
out.res_to_add_mod_list.resize(18);
uint32_t j = 0, j2 = 0;
for (uint32_t i = 0; i < out.res_to_add_mod_list.size(); ++i) {
out.res_to_add_mod_list[i].pucch_res_id = i;
out.res_to_add_mod_list[i].intra_slot_freq_hop_present = true;
out.res_to_add_mod_list[i].second_hop_prb_present = true;
if (i < 8 or i == 16) {
out.res_to_add_mod_list[i].start_prb = 51;
out.res_to_add_mod_list[i].second_hop_prb = 0;
out.res_to_add_mod_list[i].format.set_format1().init_cyclic_shift = (4 * (j % 3));
out.res_to_add_mod_list[i].format.format1().nrof_symbols = 14;
out.res_to_add_mod_list[i].format.format1().start_symbol_idx = 0;
out.res_to_add_mod_list[i].format.format1().time_domain_occ = j / 3;
j++;
} else if (i < 15) {
out.res_to_add_mod_list[i].start_prb = 1;
out.res_to_add_mod_list[i].second_hop_prb = 50;
out.res_to_add_mod_list[i].format.set_format2().nrof_prbs = 1;
out.res_to_add_mod_list[i].format.format2().nrof_symbols = 2;
out.res_to_add_mod_list[i].format.format2().start_symbol_idx = 2 * (j2 % 7);
j2++;
} else {
out.res_to_add_mod_list[i].start_prb = 50;
out.res_to_add_mod_list[i].second_hop_prb = 1;
out.res_to_add_mod_list[i].format.set_format2().nrof_prbs = 1;
out.res_to_add_mod_list[i].format.format2().nrof_symbols = 2;
out.res_to_add_mod_list[i].format.format2().start_symbol_idx = 2 * (j2 % 7);
j2++;
}
}
out.format1_present = true;
out.format1.set_setup();
out.format2_present = true;
out.format2.set_setup();
out.format2.setup().max_code_rate_present = true;
out.format2.setup().max_code_rate = pucch_max_code_rate_opts::zero_dot25;
// SR resources
out.sched_request_res_to_add_mod_list_present = true;
out.sched_request_res_to_add_mod_list.resize(1);
auto& sr_res1 = out.sched_request_res_to_add_mod_list[0];
sr_res1.sched_request_res_id = 1;
sr_res1.sched_request_id = 0;
sr_res1.periodicity_and_offset_present = true;
sr_res1.periodicity_and_offset.set_sl40() = 0;
sr_res1.res_present = true;
sr_res1.res = 16;
// DL data
out.dl_data_to_ul_ack_present = true;
if (cfg.cell_list[cc].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) {
out.dl_data_to_ul_ack.resize(1);
out.dl_data_to_ul_ack[0] = 4;
} else {
out.dl_data_to_ul_ack.resize(6);
out.dl_data_to_ul_ack[0] = 6;
out.dl_data_to_ul_ack[1] = 5;
out.dl_data_to_ul_ack[2] = 4;
out.dl_data_to_ul_ack[3] = 4;
out.dl_data_to_ul_ack[4] = 4;
out.dl_data_to_ul_ack[5] = 4;
}
}
void fill_pusch_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, pusch_cfg_s& out)
{
out.dmrs_ul_for_pusch_map_type_a_present = true;
out.dmrs_ul_for_pusch_map_type_a.set_setup();
out.dmrs_ul_for_pusch_map_type_a.setup().dmrs_add_position_present = true;
out.dmrs_ul_for_pusch_map_type_a.setup().dmrs_add_position = dmrs_ul_cfg_s::dmrs_add_position_opts::pos1;
// PUSH power control skipped
out.res_alloc = pusch_cfg_s::res_alloc_opts::res_alloc_type1;
// UCI
out.uci_on_pusch_present = true;
out.uci_on_pusch.set_setup();
out.uci_on_pusch.setup().beta_offsets_present = true;
out.uci_on_pusch.setup().beta_offsets.set_semi_static();
auto& beta_offset_semi_static = out.uci_on_pusch.setup().beta_offsets.semi_static();
beta_offset_semi_static.beta_offset_ack_idx1_present = true;
beta_offset_semi_static.beta_offset_ack_idx1 = 9;
beta_offset_semi_static.beta_offset_ack_idx2_present = true;
beta_offset_semi_static.beta_offset_ack_idx2 = 9;
beta_offset_semi_static.beta_offset_ack_idx3_present = true;
beta_offset_semi_static.beta_offset_ack_idx3 = 9;
beta_offset_semi_static.beta_offset_csi_part1_idx1_present = true;
beta_offset_semi_static.beta_offset_csi_part1_idx1 = 6;
beta_offset_semi_static.beta_offset_csi_part1_idx2_present = true;
beta_offset_semi_static.beta_offset_csi_part1_idx2 = 6;
beta_offset_semi_static.beta_offset_csi_part2_idx1_present = true;
beta_offset_semi_static.beta_offset_csi_part2_idx1 = 6;
beta_offset_semi_static.beta_offset_csi_part2_idx2_present = true;
beta_offset_semi_static.beta_offset_csi_part2_idx2 = 6;
out.uci_on_pusch.setup().scaling = uci_on_pusch_s::scaling_opts::f1;
}
void fill_init_ul_bwp_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, bwp_ul_ded_s& out)
{
if (cfg.is_standalone) {
out.pucch_cfg_present = true;
fill_pucch_cfg_from_enb_cfg(cfg, cc, out.pucch_cfg.set_setup());
out.pusch_cfg_present = true;
fill_pusch_cfg_from_enb_cfg(cfg, cc, out.pusch_cfg.set_setup());
}
}
/// Fill InitUlBwp with gNB config
void fill_ul_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, ul_cfg_s& out)
{
out.init_ul_bwp_present = true;
fill_init_ul_bwp_from_enb_cfg(cfg, cc, out.init_ul_bwp);
}
/// Fill ServingCellConfig with gNB config
int fill_serv_cell_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, serving_cell_cfg_s& serv_cell)
{
@ -329,6 +518,16 @@ int fill_serv_cell_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, serving_ce
serv_cell.init_dl_bwp_present = true;
fill_init_dl_bwp_from_enb_cfg(cfg, cc, serv_cell.init_dl_bwp);
serv_cell.first_active_dl_bwp_id_present = true;
if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) {
serv_cell.first_active_dl_bwp_id = 0;
} else {
serv_cell.first_active_dl_bwp_id = 1;
}
serv_cell.ul_cfg_present = true;
fill_ul_cfg_from_enb_cfg(cfg, cc, serv_cell.ul_cfg);
// TODO: remaining fields
return SRSRAN_SUCCESS;
@ -584,6 +783,95 @@ int fill_sp_cell_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, sp_cell_
return SRSRAN_SUCCESS;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void fill_srb1(const rrc_nr_cfg_t& cfg, rlc_bearer_cfg_s& srb1)
{
srb1.lc_ch_id = 1;
srb1.served_radio_bearer_present = true;
srb1.served_radio_bearer.set_srb_id() = 1;
srb1.rlc_cfg_present = true;
ul_am_rlc_s& am_ul = srb1.rlc_cfg.set_am().ul_am_rlc;
am_ul.sn_field_len_present = true;
am_ul.sn_field_len.value = asn1::rrc_nr::sn_field_len_am_opts::size12;
am_ul.t_poll_retx.value = asn1::rrc_nr::t_poll_retx_opts::ms45;
am_ul.poll_pdu.value = asn1::rrc_nr::poll_pdu_opts::infinity;
am_ul.poll_byte.value = asn1::rrc_nr::poll_byte_opts::infinity;
am_ul.max_retx_thres.value = asn1::rrc_nr::ul_am_rlc_s::max_retx_thres_opts::t8;
dl_am_rlc_s& am_dl = srb1.rlc_cfg.am().dl_am_rlc;
am_dl.sn_field_len_present = true;
am_dl.sn_field_len.value = asn1::rrc_nr::sn_field_len_am_opts::size12;
am_dl.t_reassembly.value = t_reassembly_opts::ms35;
am_dl.t_status_prohibit.value = asn1::rrc_nr::t_status_prohibit_opts::ms0;
// mac-LogicalChannelConfig -- Cond LCH-Setup
srb1.mac_lc_ch_cfg_present = true;
srb1.mac_lc_ch_cfg.ul_specific_params_present = true;
srb1.mac_lc_ch_cfg.ul_specific_params.prio = 1;
srb1.mac_lc_ch_cfg.ul_specific_params.prioritised_bit_rate.value =
lc_ch_cfg_s::ul_specific_params_s_::prioritised_bit_rate_opts::infinity;
srb1.mac_lc_ch_cfg.ul_specific_params.bucket_size_dur.value =
lc_ch_cfg_s::ul_specific_params_s_::bucket_size_dur_opts::ms5;
srb1.mac_lc_ch_cfg.ul_specific_params.lc_ch_group_present = true;
srb1.mac_lc_ch_cfg.ul_specific_params.lc_ch_group = 0;
srb1.mac_lc_ch_cfg.ul_specific_params.sched_request_id_present = true;
srb1.mac_lc_ch_cfg.ul_specific_params.sched_request_id = 0;
srb1.mac_lc_ch_cfg.ul_specific_params.lc_ch_sr_mask = false;
srb1.mac_lc_ch_cfg.ul_specific_params.lc_ch_sr_delay_timer_applied = false;
}
/// Fill MasterCellConfig with gNB config
int fill_master_cell_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, asn1::rrc_nr::cell_group_cfg_s& out)
{
out.cell_group_id = 0;
out.rlc_bearer_to_add_mod_list_present = true;
out.rlc_bearer_to_add_mod_list.resize(1);
fill_srb1(cfg, out.rlc_bearer_to_add_mod_list[0]);
// mac-CellGroupConfig -- Need M
out.mac_cell_group_cfg_present = true;
out.mac_cell_group_cfg.sched_request_cfg_present = true;
out.mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list_present = true;
out.mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list.resize(1);
out.mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list[0].sched_request_id = 0;
out.mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list[0].sr_trans_max.value =
sched_request_to_add_mod_s::sr_trans_max_opts::n64;
out.mac_cell_group_cfg.bsr_cfg_present = true;
out.mac_cell_group_cfg.bsr_cfg.periodic_bsr_timer.value = bsr_cfg_s::periodic_bsr_timer_opts::sf20;
out.mac_cell_group_cfg.bsr_cfg.retx_bsr_timer.value = bsr_cfg_s::retx_bsr_timer_opts::sf320;
out.mac_cell_group_cfg.tag_cfg_present = true;
out.mac_cell_group_cfg.tag_cfg.tag_to_add_mod_list_present = true;
out.mac_cell_group_cfg.tag_cfg.tag_to_add_mod_list.resize(1);
out.mac_cell_group_cfg.tag_cfg.tag_to_add_mod_list[0].tag_id = 0;
out.mac_cell_group_cfg.tag_cfg.tag_to_add_mod_list[0].time_align_timer.value = time_align_timer_opts::infinity;
out.mac_cell_group_cfg.phr_cfg_present = true;
phr_cfg_s& phr = out.mac_cell_group_cfg.phr_cfg.set_setup();
phr.phr_periodic_timer.value = asn1::rrc_nr::phr_cfg_s::phr_periodic_timer_opts::sf500;
phr.phr_prohibit_timer.value = asn1::rrc_nr::phr_cfg_s::phr_prohibit_timer_opts::sf200;
phr.phr_tx_pwr_factor_change.value = asn1::rrc_nr::phr_cfg_s::phr_tx_pwr_factor_change_opts::db3;
phr.multiple_phr = false;
phr.dummy = false;
phr.phr_type2_other_cell = false;
phr.phr_mode_other_cg.value = asn1::rrc_nr::phr_cfg_s::phr_mode_other_cg_opts::real;
out.mac_cell_group_cfg.skip_ul_tx_dynamic = false;
// physicalCellGroupConfig -- Need M
out.phys_cell_group_cfg_present = true;
out.phys_cell_group_cfg.p_nr_fr1_present = true;
out.phys_cell_group_cfg.p_nr_fr1 = 10;
out.phys_cell_group_cfg.pdsch_harq_ack_codebook.value =
phys_cell_group_cfg_s::pdsch_harq_ack_codebook_opts::dynamic_value;
// spCellConfig -- Need M
out.sp_cell_cfg_present = true;
fill_sp_cell_cfg_from_enb_cfg(cfg, cc, out.sp_cell_cfg);
out.sp_cell_cfg.recfg_with_sync_present = false;
return SRSRAN_SUCCESS;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fill_mib_from_enb_cfg(const rrc_nr_cfg_t& cfg, asn1::rrc_nr::mib_s& mib)
{
uint32_t scs =

View File

@ -49,7 +49,15 @@ int rrc_nr::init(const rrc_nr_cfg_t& cfg_,
rrc_eutra = rrc_eutra_;
cfg = cfg_;
// Generate cell config structs
cell_ctxt.reset(new cell_ctxt_t{});
if (cfg.is_standalone) {
std::unique_ptr<cell_group_cfg_s> master_cell_group{new cell_group_cfg_s{}};
int ret = fill_master_cell_cfg_from_enb_cfg(cfg, 0, *master_cell_group);
srsran_assert(ret == SRSRAN_SUCCESS, "Failed to configure MasterCellGroup");
cell_ctxt->master_cell_group = std::move(master_cell_group);
}
// derived
slot_dur_ms = 1;

View File

@ -26,7 +26,7 @@ Every function in UE class is called from a mutex environment thus does not
need extra protection.
*******************************************************************************/
rrc_nr::ue::ue(rrc_nr* parent_, uint16_t rnti_, const sched_nr_ue_cfg_t& uecfg_, bool start_msg3_timer) :
parent(parent_), rnti(rnti_), uecfg(uecfg_)
parent(parent_), logger(parent_->logger), rnti(rnti_), uecfg(uecfg_)
{
// Derive UE cfg from rrc_cfg_nr_t
uecfg.phy_cfg.pdcch = parent->cfg.cell_list[0].phy_cell.pdcch;
@ -56,12 +56,12 @@ void rrc_nr::ue::set_activity_timeout(activity_timeout_type_t type)
deadline_ms = 10000;
break;
default:
parent->logger.error("Unknown timeout type %d", type);
logger.error("Unknown timeout type %d", type);
return;
}
activity_timer.set(deadline_ms, [this, type](uint32_t tid) { activity_timer_expired(type); });
parent->logger.debug("Setting timer for %s for rnti=0x%x to %dms", to_string(type).c_str(), rnti, deadline_ms);
logger.debug("Setting timer for %s for rnti=0x%x to %dms", to_string(type).c_str(), rnti, deadline_ms);
set_activity();
}
@ -70,7 +70,7 @@ void rrc_nr::ue::set_activity(bool enabled)
{
if (not enabled) {
if (activity_timer.is_running()) {
parent->logger.debug("Inactivity timer interrupted for rnti=0x%x", rnti);
logger.debug("Inactivity timer interrupted for rnti=0x%x", rnti);
}
activity_timer.stop();
return;
@ -78,12 +78,12 @@ void rrc_nr::ue::set_activity(bool enabled)
// re-start activity timer with current timeout value
activity_timer.run();
parent->logger.debug("Activity registered for rnti=0x%x (timeout_value=%dms)", rnti, activity_timer.duration());
logger.debug("Activity registered for rnti=0x%x (timeout_value=%dms)", rnti, activity_timer.duration());
}
void rrc_nr::ue::activity_timer_expired(const activity_timeout_type_t type)
{
parent->logger.info("Activity timer for rnti=0x%x expired after %d ms", rnti, activity_timer.time_elapsed());
logger.info("Activity timer for rnti=0x%x expired after %d ms", rnti, activity_timer.time_elapsed());
switch (type) {
case MSG5_RX_TIMEOUT:
@ -101,7 +101,7 @@ void rrc_nr::ue::activity_timer_expired(const activity_timeout_type_t type)
default:
// Unhandled activity timeout, just remove UE and log an error
parent->rem_user(rnti);
parent->logger.error(
logger.error(
"Unhandled reason for activity timer expiration. rnti=0x%x, cause %d", rnti, static_cast<unsigned>(type));
}
}
@ -117,7 +117,7 @@ void rrc_nr::ue::send_dl_ccch(const dl_ccch_msg_s& dl_ccch_msg)
// Allocate a new PDU buffer, pack the message and send to PDCP
srsran::unique_byte_buffer_t pdu = parent->pack_into_pdu(dl_ccch_msg);
if (pdu == nullptr) {
parent->logger.error("Failed to send DL-CCCH");
logger.error("Failed to send DL-CCCH");
return;
}
fmt::memory_buffer fmtbuf;
@ -131,7 +131,7 @@ void rrc_nr::ue::send_dl_dcch(srsran::nr_srb srb, const asn1::rrc_nr::dl_dcch_ms
// Allocate a new PDU buffer, pack the message and send to PDCP
srsran::unique_byte_buffer_t pdu = parent->pack_into_pdu(dl_dcch_msg);
if (pdu == nullptr) {
parent->logger.error("Failed to send DL-DCCH");
logger.error("Failed to send DL-DCCH");
return;
}
fmt::memory_buffer fmtbuf;
@ -213,7 +213,6 @@ int rrc_nr::ue::pack_sp_cell_cfg_ded_init_dl_bwp(asn1::rrc_nr::cell_group_cfg_s&
{
cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp_present = true;
pack_sp_cell_cfg_ded_init_dl_bwp_pdsch_cfg(cell_group_cfg_pack);
pack_sp_cell_cfg_ded_init_dl_bwp_radio_link_monitoring(cell_group_cfg_pack);
return SRSRAN_SUCCESS;
@ -236,58 +235,6 @@ int rrc_nr::ue::pack_sp_cell_cfg_ded_init_dl_bwp_radio_link_monitoring(
return SRSRAN_SUCCESS;
}
int rrc_nr::ue::pack_sp_cell_cfg_ded_init_dl_bwp_pdsch_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack)
{
cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdsch_cfg_present = true;
auto& pdsch_cfg_dedicated = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdsch_cfg;
pdsch_cfg_dedicated.set_setup();
pdsch_cfg_dedicated.setup().dmrs_dl_for_pdsch_map_type_a_present = true;
pdsch_cfg_dedicated.setup().dmrs_dl_for_pdsch_map_type_a.set_setup();
pdsch_cfg_dedicated.setup().dmrs_dl_for_pdsch_map_type_a.setup().dmrs_add_position_present = true;
pdsch_cfg_dedicated.setup().dmrs_dl_for_pdsch_map_type_a.setup().dmrs_add_position =
asn1::rrc_nr::dmrs_dl_cfg_s::dmrs_add_position_opts::pos1;
pdsch_cfg_dedicated.setup().tci_states_to_add_mod_list_present = true;
pdsch_cfg_dedicated.setup().tci_states_to_add_mod_list.resize(1);
pdsch_cfg_dedicated.setup().tci_states_to_add_mod_list[0].tci_state_id = 0;
pdsch_cfg_dedicated.setup().tci_states_to_add_mod_list[0].qcl_type1.ref_sig.set_ssb();
pdsch_cfg_dedicated.setup().tci_states_to_add_mod_list[0].qcl_type1.ref_sig.ssb() = 0;
pdsch_cfg_dedicated.setup().tci_states_to_add_mod_list[0].qcl_type1.qcl_type =
asn1::rrc_nr::qcl_info_s::qcl_type_opts::type_d;
pdsch_cfg_dedicated.setup().res_alloc = pdsch_cfg_s::res_alloc_opts::res_alloc_type1;
pdsch_cfg_dedicated.setup().rbg_size = asn1::rrc_nr::pdsch_cfg_s::rbg_size_opts::cfg1;
pdsch_cfg_dedicated.setup().prb_bundling_type.set_static_bundling();
pdsch_cfg_dedicated.setup().prb_bundling_type.static_bundling().bundle_size_present = true;
pdsch_cfg_dedicated.setup().prb_bundling_type.static_bundling().bundle_size =
asn1::rrc_nr::pdsch_cfg_s::prb_bundling_type_c_::static_bundling_s_::bundle_size_opts::wideband;
// ZP-CSI
pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list_present = false;
pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list.resize(1);
pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].zp_csi_rs_res_id = 0;
pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].res_map.freq_domain_alloc.set_row4();
pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].res_map.freq_domain_alloc.row4().from_number(0b100);
pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].res_map.nrof_ports =
asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p4;
pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].res_map.first_ofdm_symbol_in_time_domain = 8;
pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].res_map.cdm_type =
asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::fd_cdm2;
pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].res_map.density.set_one();
pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].res_map.freq_band.start_rb = 0;
pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].res_map.freq_band.nrof_rbs = 52;
pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].periodicity_and_offset_present = true;
pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].periodicity_and_offset.set_slots80();
pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].periodicity_and_offset.slots80() = 1;
pdsch_cfg_dedicated.setup().p_zp_csi_rs_res_set_present = false;
pdsch_cfg_dedicated.setup().p_zp_csi_rs_res_set.set_setup();
pdsch_cfg_dedicated.setup().p_zp_csi_rs_res_set.setup().zp_csi_rs_res_set_id = 0;
pdsch_cfg_dedicated.setup().p_zp_csi_rs_res_set.setup().zp_csi_rs_res_id_list.resize(1);
return SRSRAN_SUCCESS;
}
int rrc_nr::ue::pack_sp_cell_cfg_ded_ul_cfg_init_ul_bwp_pucch_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack)
{
// PUCCH
@ -357,13 +304,13 @@ int rrc_nr::ue::pack_sp_cell_cfg_ded_ul_cfg_init_ul_bwp_pucch_cfg(asn1::rrc_nr::
pucch_cfg.setup().res_to_add_mod_list_present = true;
pucch_cfg.setup().res_to_add_mod_list.resize(3);
if (not srsran::make_phy_res_config(resource_small, pucch_cfg.setup().res_to_add_mod_list[0], 0)) {
parent->logger.warning("Failed to create 1-2 bit NR PUCCH resource");
logger.warning("Failed to create 1-2 bit NR PUCCH resource");
}
if (not srsran::make_phy_res_config(resource_big, pucch_cfg.setup().res_to_add_mod_list[1], 1)) {
parent->logger.warning("Failed to create >2 bit NR PUCCH resource");
logger.warning("Failed to create >2 bit NR PUCCH resource");
}
if (not srsran::make_phy_res_config(resource_sr, pucch_cfg.setup().res_to_add_mod_list[2], 2)) {
parent->logger.warning("Failed to create SR NR PUCCH resource");
logger.warning("Failed to create SR NR PUCCH resource");
}
// Make 2 PUCCH resource sets
@ -467,14 +414,7 @@ int rrc_nr::ue::pack_sp_cell_cfg_ded_pdcch_serving_cell_cfg(asn1::rrc_nr::cell_g
int rrc_nr::ue::pack_sp_cell_cfg_ded(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack)
{
// SP Cell Dedicated config
cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded_present = true;
cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.first_active_dl_bwp_id_present = true;
if (parent->cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) {
cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.first_active_dl_bwp_id = 0;
} else {
cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.first_active_dl_bwp_id = 1;
}
cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded_present = true;
pack_sp_cell_cfg_ded_ul_cfg(cell_group_cfg_pack);
pack_sp_cell_cfg_ded_init_dl_bwp(cell_group_cfg_pack);
@ -484,7 +424,7 @@ int rrc_nr::ue::pack_sp_cell_cfg_ded(asn1::rrc_nr::cell_group_cfg_s& cell_group_
// spCellConfig
if (fill_sp_cell_cfg_from_enb_cfg(parent->cfg, UE_PSCELL_CC_IDX, cell_group_cfg_pack.sp_cell_cfg) != SRSRAN_SUCCESS) {
parent->logger.error("Failed to pack spCellConfig for rnti=0x%x", rnti);
logger.error("Failed to pack spCellConfig for rnti=0x%x", rnti);
}
return SRSRAN_SUCCESS;
@ -664,7 +604,7 @@ int rrc_nr::ue::pack_secondary_cell_group_cfg(asn1::dyn_octstring& packed_second
packed_secondary_cell_config.resize(256);
asn1::bit_ref bref_pack(packed_secondary_cell_config.data(), packed_secondary_cell_config.size());
if (cell_group_cfg_pack.pack(bref_pack) != asn1::SRSASN_SUCCESS) {
parent->logger.error("Failed to pack NR secondary cell config");
logger.error("Failed to pack NR secondary cell config");
return SRSRAN_ERROR;
}
packed_secondary_cell_config.resize(bref_pack.distance_bytes());
@ -685,7 +625,7 @@ int rrc_nr::ue::pack_rrc_reconfiguration(asn1::dyn_octstring& packed_rrc_reconfi
recfg_ies.secondary_cell_group_present = true;
if (pack_secondary_cell_group_cfg(recfg_ies.secondary_cell_group) == SRSRAN_ERROR) {
parent->logger.error("Failed to pack secondary cell group");
logger.error("Failed to pack secondary cell group");
return SRSRAN_ERROR;
}
@ -693,7 +633,7 @@ int rrc_nr::ue::pack_rrc_reconfiguration(asn1::dyn_octstring& packed_rrc_reconfi
packed_rrc_reconfig.resize(512);
asn1::bit_ref bref_pack(packed_rrc_reconfig.data(), packed_rrc_reconfig.size());
if (reconfig.pack(bref_pack) != asn1::SRSASN_SUCCESS) {
parent->logger.error("Failed to pack RRC Reconfiguration");
logger.error("Failed to pack RRC Reconfiguration");
return SRSRAN_ERROR;
}
packed_rrc_reconfig.resize(bref_pack.distance_bytes());
@ -719,7 +659,7 @@ int rrc_nr::ue::pack_nr_radio_bearer_config(asn1::dyn_octstring& packed_nr_beare
packed_nr_bearer_config.resize(128);
asn1::bit_ref bref_pack(packed_nr_bearer_config.data(), packed_nr_bearer_config.size());
if (radio_bearer_cfg_pack.pack(bref_pack) != asn1::SRSASN_SUCCESS) {
parent->logger.error("Failed to pack NR radio bearer config");
logger.error("Failed to pack NR radio bearer config");
return SRSRAN_ERROR;
}
@ -883,25 +823,36 @@ int rrc_nr::ue::add_drb()
void rrc_nr::ue::handle_rrc_setup_request(const asn1::rrc_nr::rrc_setup_request_s& msg)
{
const uint8_t max_wait_time_secs = 16;
if (not parent->ngap->is_amf_connected()) {
parent->logger.error("MME isn't connected. Sending Connection Reject");
const uint8_t max_wait_time_secs = 16;
send_rrc_reject(max_wait_time_secs); // See TS 38.331, RejectWaitTime
logger.error("MME isn't connected. Sending Connection Reject");
send_rrc_reject(max_wait_time_secs);
return;
}
// TODO: Allocate PUCCH resources and reject if not available
// Allocate PUCCH resources and reject if not available
if (not init_pucch()) {
logger.warning("Could not allocate PUCCH resources for rnti=0x%x. Sending Connection Reject", rnti);
send_rrc_reject(max_wait_time_secs);
return;
}
switch (msg.rrc_setup_request.ue_id.type().value) {
case asn1::rrc_nr::init_ue_id_c::types_opts::ng_minus5_g_s_tmsi_part1:
// TODO: communicate with NGAP
const rrc_setup_request_ies_s& ies = msg.rrc_setup_request;
switch (ies.ue_id.type().value) {
case init_ue_id_c::types_opts::ng_minus5_g_s_tmsi_part1:
ctxt.setup_ue_id = ies.ue_id.ng_minus5_g_s_tmsi_part1().to_number();
break;
case asn1::rrc_nr::init_ue_id_c::types_opts::random_value:
ctxt.setup_ue_id = ies.ue_id.random_value().to_number();
// TODO: communicate with NGAP
break;
default:
parent->logger.error("Unsupported RRCSetupRequest");
logger.error("Unsupported RRCSetupRequest");
send_rrc_reject(max_wait_time_secs);
return;
}
ctxt.connection_cause.value = ies.establishment_cause.value;
send_rrc_setup();
set_activity_timeout(UE_INACTIVITY_TIMEOUT);
@ -912,16 +863,22 @@ void rrc_nr::ue::send_rrc_reject(uint8_t reject_wait_time_secs)
{
dl_ccch_msg_s msg;
rrc_reject_ies_s& reject = msg.msg.set_c1().set_rrc_reject().crit_exts.set_rrc_reject();
// See TS 38.331, RejectWaitTime
if (reject_wait_time_secs > 0) {
reject.wait_time_present = true;
reject.wait_time = reject_wait_time_secs;
}
send_dl_ccch(msg);
// TODO: remove user
}
/// TS 38.331, RRCSetup
void rrc_nr::ue::send_rrc_setup()
{
const uint8_t max_wait_time_secs = 16;
dl_ccch_msg_s msg;
rrc_setup_s& setup = msg.msg.set_c1().set_rrc_setup();
setup.rrc_transaction_id = (uint8_t)((transaction_id++) % 4);
@ -934,6 +891,25 @@ void rrc_nr::ue::send_rrc_setup()
srb_to_add_mod_s& srb1 = setup_ies.radio_bearer_cfg.srb_to_add_mod_list[0];
srb1.srb_id = 1;
{
srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer();
asn1::bit_ref bref{pdu->data(), pdu->get_tailroom()};
if (parent->cell_ctxt->master_cell_group->pack(bref) != SRSRAN_SUCCESS) {
logger.error("Failed to pack master cell group");
send_rrc_reject(max_wait_time_secs);
return;
}
pdu->N_bytes = bref.distance_bytes();
setup_ies.master_cell_group.resize(pdu->N_bytes);
memcpy(setup_ies.master_cell_group.data(), pdu->data(), pdu->N_bytes);
}
if (logger.debug.enabled()) {
asn1::json_writer js;
parent->cell_ctxt->master_cell_group->to_json(js);
logger.debug("Containerized MasterCellGroup: %s", js.to_string().c_str());
}
send_dl_ccch(msg);
}
@ -941,6 +917,9 @@ void rrc_nr::ue::send_rrc_setup()
void rrc_nr::ue::handle_rrc_setup_complete(const asn1::rrc_nr::rrc_setup_complete_s& msg)
{
// TODO: handle RRCSetupComplete
using ngap_cause_t = asn1::ngap_nr::rrcestablishment_cause_opts::options;
auto ngap_cause = (ngap_cause_t)ctxt.connection_cause.value; // NGAP and RRC causes seem to have a 1-1 mapping
parent->ngap->initial_ue(rnti, uecfg.carriers[0].cc, ngap_cause, {}, ctxt.setup_ue_id);
send_security_mode_command();
}
@ -991,6 +970,13 @@ void rrc_nr::ue::handle_ul_information_transfer(const asn1::rrc_nr::ul_info_tran
// TODO: handle UL information transfer
}
bool rrc_nr::ue::init_pucch()
{
// TODO: Allocate PUCCH resources
return true;
}
/**
* @brief Deactivate all Bearers (MAC logical channel) for this specific RNTI
*

View File

@ -146,8 +146,9 @@ void test_rrc_sa_connection()
rrc_nr_cfg_t rrc_cfg_nr = rrc_nr_cfg_t{};
rrc_cfg_nr.cell_list.emplace_back();
rrc_cfg_nr.cell_list[0].phy_cell.carrier.pci = 500;
rrc_cfg_nr.cell_list[0].dl_arfcn = 634240;
rrc_cfg_nr.cell_list[0].band = 78;
rrc_cfg_nr.cell_list[0].dl_arfcn = 368500;
rrc_cfg_nr.cell_list[0].band = 3;
rrc_cfg_nr.cell_list[0].duplex_mode = SRSRAN_DUPLEX_MODE_FDD;
rrc_cfg_nr.is_standalone = true;
args.enb.n_prb = 50;
enb_conf_sections::set_derived_args_nr(&args, &rrc_cfg_nr, &phy_cfg);

View File

@ -63,6 +63,14 @@ void test_rrc_nr_connection_establishment(srsran::task_scheduler& task_sched,
rrc_setup_complete_s& complete = ul_dcch_msg.msg.set_c1().set_rrc_setup_complete();
complete.rrc_transaction_id = dl_ccch_msg.msg.c1().rrc_setup().rrc_transaction_id;
rrc_setup_complete_ies_s& complete_ies = complete.crit_exts.set_rrc_setup_complete();
complete_ies.sel_plmn_id = 1; // First PLMN in list
complete_ies.registered_amf_present = true;
complete_ies.registered_amf.amf_id.from_number(0x800101);
complete_ies.guami_type_present = true;
complete_ies.guami_type.value = rrc_setup_complete_ies_s::guami_type_opts::native;
complete_ies.ded_nas_msg.from_string("7E01280E534C337E004109000BF200F110800101347B80802E02F07071002D7E004109000BF200F"
"110800101347B80801001002E02F0702F0201015200F11000006418010174000090530101");
{
pdu = srsran::make_byte_buffer();
asn1::bit_ref bref{pdu->data(), pdu->get_tailroom()};