diff --git a/srsgnb/hdr/stack/rrc/cell_asn1_config.h b/srsgnb/hdr/stack/rrc/cell_asn1_config.h index 202f18a49..df14ed406 100644 --- a/srsgnb/hdr/stack/rrc/cell_asn1_config.h +++ b/srsgnb/hdr/stack/rrc/cell_asn1_config.h @@ -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); diff --git a/srsgnb/hdr/stack/rrc/rrc_nr.h b/srsgnb/hdr/stack/rrc/rrc_nr.h index 9f3b3c39c..560165396 100644 --- a/srsgnb/hdr/stack/rrc/rrc_nr.h +++ b/srsgnb/hdr/stack/rrc/rrc_nr.h @@ -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 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 sib_buffer; + std::unique_ptr master_cell_group; }; std::unique_ptr cell_ctxt; rnti_map_t > users; diff --git a/srsgnb/hdr/stack/rrc/rrc_nr_ue.h b/srsgnb/hdr/stack/rrc/rrc_nr_ue.h index f79c01712..1b3a588d2 100644 --- a/srsgnb/hdr/stack/rrc/rrc_nr_ue.h +++ b/srsgnb/hdr/stack/rrc/rrc_nr_ue.h @@ -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 void log_rrc_message(srsran::nr_srb srb, @@ -133,6 +131,11 @@ private: template 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; diff --git a/srsgnb/src/stack/rrc/cell_asn1_config.cc b/srsgnb/src/stack/rrc/cell_asn1_config.cc index 16db18d9d..93ddfdc2a 100644 --- a/srsgnb/src/stack/rrc/cell_asn1_config.cc +++ b/srsgnb/src/stack/rrc/cell_asn1_config.cc @@ -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 = diff --git a/srsgnb/src/stack/rrc/rrc_nr.cc b/srsgnb/src/stack/rrc/rrc_nr.cc index f9f2e06ba..ada6213ef 100644 --- a/srsgnb/src/stack/rrc/rrc_nr.cc +++ b/srsgnb/src/stack/rrc/rrc_nr.cc @@ -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 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; diff --git a/srsgnb/src/stack/rrc/rrc_nr_ue.cc b/srsgnb/src/stack/rrc/rrc_nr_ue.cc index 77fc9e430..4778bdbaa 100644 --- a/srsgnb/src/stack/rrc/rrc_nr_ue.cc +++ b/srsgnb/src/stack/rrc/rrc_nr_ue.cc @@ -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(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 * diff --git a/srsgnb/src/stack/rrc/test/rrc_nr_test.cc b/srsgnb/src/stack/rrc/test/rrc_nr_test.cc index 02bcbedea..7e4a05f93 100644 --- a/srsgnb/src/stack/rrc/test/rrc_nr_test.cc +++ b/srsgnb/src/stack/rrc/test/rrc_nr_test.cc @@ -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); diff --git a/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.cc b/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.cc index 7d4a8a62a..14485b158 100644 --- a/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.cc +++ b/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.cc @@ -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()};