diff --git a/lib/include/srslte/asn1/rrc_nr_utils.h b/lib/include/srslte/asn1/rrc_nr_utils.h index 716aefca6..8530a7435 100644 --- a/lib/include/srslte/asn1/rrc_nr_utils.h +++ b/lib/include/srslte/asn1/rrc_nr_utils.h @@ -13,6 +13,8 @@ #ifndef SRSLTE_RRC_NR_UTILS_H #define SRSLTE_RRC_NR_UTILS_H +#include "srslte/interfaces/pdcp_interface_types.h" +#include "srslte/interfaces/rlc_interface_types.h" #include "srslte/interfaces/rrc_interface_types.h" #include "srslte/interfaces/sched_interface.h" @@ -24,6 +26,8 @@ namespace rrc_nr { struct plmn_id_s; struct sib1_s; +struct rlc_cfg_c; +struct pdcp_cfg_s; } // namespace rrc_nr } // namespace asn1 @@ -36,6 +40,16 @@ namespace srslte { plmn_id_t make_plmn_id_t(const asn1::rrc_nr::plmn_id_s& asn1_type); void to_asn1(asn1::rrc_nr::plmn_id_s* asn1_type, const plmn_id_t& cfg); +/*************************** + * RLC Config + **************************/ +rlc_config_t make_rlc_config_t(const asn1::rrc_nr::rlc_cfg_c& asn1_type); + +/*************************** + * PDCP Config + **************************/ +pdcp_config_t make_drb_pdcp_config_t(const uint8_t bearer_id, bool is_ue, const asn1::rrc_nr::pdcp_cfg_s& pdcp_cfg); + } // namespace srslte namespace srsenb { diff --git a/lib/include/srslte/interfaces/rlc_interface_types.h b/lib/include/srslte/interfaces/rlc_interface_types.h index cc2e0b2e7..8679f360d 100644 --- a/lib/include/srslte/interfaces/rlc_interface_types.h +++ b/lib/include/srslte/interfaces/rlc_interface_types.h @@ -216,7 +216,7 @@ public: } else if (sn_size == 12) { cnfg.um_nr.sn_field_length = rlc_um_nr_sn_size_t::size12bits; cnfg.um_nr.UM_Window_Size = 2048; - cnfg.um_nr.mod = 64; + cnfg.um_nr.mod = 4096; } else { return {}; } diff --git a/lib/src/asn1/rrc_nr_utils.cc b/lib/src/asn1/rrc_nr_utils.cc index 18b8195ae..ba44ed40e 100644 --- a/lib/src/asn1/rrc_nr_utils.cc +++ b/lib/src/asn1/rrc_nr_utils.cc @@ -13,10 +13,13 @@ #include "srslte/asn1/rrc_nr_utils.h" #include "srslte/asn1/rrc_nr.h" #include "srslte/config.h" +#include "srslte/interfaces/pdcp_interface_types.h" +#include "srslte/interfaces/rlc_interface_types.h" #include namespace srslte { +using namespace asn1::rrc_nr; /*************************** * PLMN ID **************************/ @@ -47,6 +50,82 @@ void to_asn1(asn1::rrc_nr::plmn_id_s* asn1_type, const plmn_id_t& cfg) std::copy(&cfg.mnc[0], &cfg.mnc[cfg.nof_mnc_digits], &asn1_type->mnc[0]); } +rlc_config_t make_rlc_config_t(const rlc_cfg_c& asn1_type) +{ + rlc_config_t rlc_cfg = rlc_config_t::default_rlc_um_nr_config(); + rlc_cfg.rat = srslte_rat_t::nr; + switch (asn1_type.type().value) { + case rlc_cfg_c::types_opts::am: + break; + case rlc_cfg_c::types_opts::um_bi_dir: + case rlc_cfg_c::types_opts::um_uni_dir_dl: + case rlc_cfg_c::types_opts::um_uni_dir_ul: + rlc_cfg.rlc_mode = rlc_mode_t::um; + rlc_cfg.um_nr.t_reassembly_ms = asn1_type.um_bi_dir().dl_um_rlc.t_reassembly.value; + rlc_cfg.um_nr.sn_field_length = (rlc_um_nr_sn_size_t)asn1_type.um_bi_dir().dl_um_rlc.sn_field_len.value; + rlc_cfg.um_nr.mod = (rlc_cfg.um_nr.sn_field_length == rlc_um_nr_sn_size_t::size6bits) ? 64 : 4096; + rlc_cfg.um_nr.UM_Window_Size = (rlc_cfg.um_nr.sn_field_length == rlc_um_nr_sn_size_t::size6bits) ? 32 : 2048; + break; + default: + break; + } + return rlc_cfg; +} + +srslte::pdcp_config_t make_drb_pdcp_config_t(const uint8_t bearer_id, bool is_ue, const pdcp_cfg_s& pdcp_cfg) +{ + // TODO: complete config processing + // TODO: check if is drb_cfg.pdcp_cfg.drb_present if not return Error + // TODO: different pdcp sn size for ul and dl + pdcp_discard_timer_t discard_timer = pdcp_discard_timer_t::infinity; + if (pdcp_cfg.drb.discard_timer_present) { + switch (pdcp_cfg.drb.discard_timer.to_number()) { + case 10: + discard_timer = pdcp_discard_timer_t::ms10; + break; + case 100: + discard_timer = pdcp_discard_timer_t::ms100; + break; + default: + discard_timer = pdcp_discard_timer_t::infinity; + break; + } + } + + pdcp_t_reordering_t t_reordering = pdcp_t_reordering_t::ms500; + if (pdcp_cfg.t_reordering_present) { + switch (pdcp_cfg.t_reordering.to_number()) { + case 0: + t_reordering = pdcp_t_reordering_t::ms0; + break; + default: + t_reordering = pdcp_t_reordering_t::ms500; + } + } + + uint8_t sn_len = srslte::PDCP_SN_LEN_12; + if (pdcp_cfg.drb.pdcp_sn_size_dl_present) { + switch (pdcp_cfg.drb.pdcp_sn_size_dl.value) { + case pdcp_cfg_s::drb_s_::pdcp_sn_size_dl_opts::options::len12bits: + sn_len = srslte::PDCP_SN_LEN_12; + break; + case pdcp_cfg_s::drb_s_::pdcp_sn_size_dl_opts::options::len18bits: + sn_len = srslte::PDCP_SN_LEN_18; + default: + break; + } + } + + pdcp_config_t cfg(bearer_id, + PDCP_RB_IS_DRB, + is_ue ? SECURITY_DIRECTION_UPLINK : SECURITY_DIRECTION_DOWNLINK, + is_ue ? SECURITY_DIRECTION_DOWNLINK : SECURITY_DIRECTION_UPLINK, + sn_len, + t_reordering, + discard_timer); + return cfg; +} + } // namespace srslte namespace srsenb { diff --git a/lib/test/asn1/CMakeLists.txt b/lib/test/asn1/CMakeLists.txt index 05c297dd4..cc3a0a54f 100644 --- a/lib/test/asn1/CMakeLists.txt +++ b/lib/test/asn1/CMakeLists.txt @@ -54,6 +54,10 @@ if (ENABLE_5GNR) add_executable(ngap_asn1_test ngap_test.cc) target_link_libraries(ngap_asn1_test ngap_nr_asn1 srslte_common) add_test(ngap_asn1_test ngap_asn1_test) + + add_executable(rrc_nr_utils_test rrc_nr_utils_test.cc) + target_link_libraries(rrc_nr_utils_test ngap_nr_asn1 srslte_common rrc_nr_asn1) + add_test(rrc_nr_utils_test rrc_nr_utils_test) endif(ENABLE_5GNR) add_executable(rrc_asn1_decoder rrc_asn1_decoder.cc) diff --git a/lib/test/asn1/rrc_nr_utils_test.cc b/lib/test/asn1/rrc_nr_utils_test.cc new file mode 100644 index 000000000..085e0bf27 --- /dev/null +++ b/lib/test/asn1/rrc_nr_utils_test.cc @@ -0,0 +1,53 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include +#include + +#include "srslte/asn1/rrc_nr.h" +#include "srslte/asn1/rrc_nr_utils.h" +#include "srslte/common/common.h" +#include "srslte/common/log.h" +#include "srslte/common/logmap.h" +#include "srslte/common/test_common.h" + +using namespace srslte; + +int test_rlc_config() +{ + asn1::rrc_nr::rlc_cfg_c rlc_cfg_asn1; + rlc_cfg_asn1.set_um_bi_dir(); + rlc_cfg_asn1.um_bi_dir().dl_um_rlc.sn_field_len_present = true; + rlc_cfg_asn1.um_bi_dir().dl_um_rlc.sn_field_len = asn1::rrc_nr::sn_field_len_um_e::size12; + rlc_cfg_asn1.um_bi_dir().dl_um_rlc.t_reassembly = asn1::rrc_nr::t_reassembly_e::ms50; + rlc_cfg_asn1.um_bi_dir().ul_um_rlc.sn_field_len_present = true; + rlc_cfg_asn1.um_bi_dir().ul_um_rlc.sn_field_len = asn1::rrc_nr::sn_field_len_um_e::size12; + asn1::json_writer jw; + rlc_cfg_asn1.to_json(jw); + logmap::get("RRC")->info_long("RLC NR Config: \n %s \n", jw.to_string().c_str()); + + rlc_config_t rlc_cfg = make_rlc_config_t(rlc_cfg_asn1); + TESTASSERT(rlc_cfg.rat == srslte_rat_t::nr); + TESTASSERT(rlc_cfg.um_nr.sn_field_length == rlc_um_nr_sn_size_t::size12bits); + TESTASSERT(rlc_cfg.um_nr.UM_Window_Size == 2048); + return SRSLTE_SUCCESS; +} + +int main() +{ + srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_DEBUG); + + TESTASSERT(test_rlc_config() == 0); + + printf("Success\n"); + return 0; +}