diff --git a/lib/include/srslte/asn1/rrc_asn1_utils.h b/lib/include/srslte/asn1/rrc_asn1_utils.h index f0e6c2b8d..5c9a30aa4 100644 --- a/lib/include/srslte/asn1/rrc_asn1_utils.h +++ b/lib/include/srslte/asn1/rrc_asn1_utils.h @@ -46,6 +46,12 @@ struct pucch_cfg_common_s; struct srs_ul_cfg_common_c; struct ul_pwr_ctrl_common_s; struct scell_to_add_mod_r10_s; +struct mbms_notif_cfg_r9_s; +struct mbsfn_area_info_r9_s; +struct mbsfn_sf_cfg_s; +struct mcch_msg_s; +struct sib_type13_r9_s; + } // namespace rrc } // namespace asn1 @@ -87,6 +93,14 @@ void set_phy_cfg_t_common_srs(phy_cfg_t* cfg, const asn1::rrc::srs_ul_cfg_common void set_phy_cfg_t_common_pwr_ctrl(phy_cfg_t* cfg, const asn1::rrc::ul_pwr_ctrl_common_s& asn1_type); void set_phy_cfg_t_scell_config(phy_cfg_t* cfg, const asn1::rrc::scell_to_add_mod_r10_s& asn1_type); void set_phy_cfg_t_enable_64qam(phy_cfg_t* cfg, const bool enabled); -} + +// mbms +mbms_notif_cfg_t make_mbms_notif_cfg(const asn1::rrc::mbms_notif_cfg_r9_s& asn1_type); +mbsfn_area_info_t make_mbsfn_area_info(const asn1::rrc::mbsfn_area_info_r9_s& asn1_type); +mbsfn_sf_cfg_t make_mbsfn_sf_cfg(const asn1::rrc::mbsfn_sf_cfg_s& sf_cfg); +mcch_msg_t make_mcch_msg(const asn1::rrc::mcch_msg_s& asn1_type); +sib13_t make_sib13(const asn1::rrc::sib_type13_r9_s& asn1_type); + +} // namespace srslte #endif // SRSLTE_RRC_ASN1_UTILS_H diff --git a/lib/include/srslte/interfaces/rrc_interface_types.h b/lib/include/srslte/interfaces/rrc_interface_types.h index 73bda37db..5ba26c400 100644 --- a/lib/include/srslte/interfaces/rrc_interface_types.h +++ b/lib/include/srslte/interfaces/rrc_interface_types.h @@ -520,6 +520,120 @@ struct phy_cfg_t { srslte_prach_cfg_t prach_cfg; }; +struct mbsfn_sf_cfg_t { + enum class alloc_period_t { n1, n2, n4, n8, n16, n32, nulltype }; + alloc_period_t radioframe_alloc_period; + uint8_t radioframe_alloc_offset = 0; + enum class sf_alloc_type_t { one_frame, four_frames, nulltype }; + sf_alloc_type_t nof_alloc_subfrs; + uint32_t sf_alloc; +}; +inline uint16_t enum_to_number(const mbsfn_sf_cfg_t::alloc_period_t& radioframe_period) +{ + constexpr static uint16_t options[] = {1, 2, 4, 8, 16, 32}; + return enum_to_number(options, (uint32_t)mbsfn_sf_cfg_t::alloc_period_t::nulltype, (uint32_t)radioframe_period); +} + +struct mbms_notif_cfg_t { + enum class coeff_t { n2, n4 }; + coeff_t notif_repeat_coeff = coeff_t::n2; + uint8_t notif_offset = 0; + uint8_t notif_sf_idx = 1; +}; + +// MBSFN-AreaInfo-r9 ::= SEQUENCE +struct mbsfn_area_info_t { + uint8_t mbsfn_area_id = 0; + enum class region_len_t { s1, s2, nulltype } non_mbsfn_region_len; + uint8_t notif_ind = 0; + struct mcch_cfg_t { + enum class repeat_period_t { rf32, rf64, rf128, rf256, nulltype } mcch_repeat_period; + uint8_t mcch_offset = 0; + enum class mod_period_t { rf512, rf1024 } mcch_mod_period; + uint8_t sf_alloc_info = 0; + enum class sig_mcs_t { n2, n7, n13, n19, nulltype } sig_mcs; + } mcch_cfg; +}; +inline uint16_t enum_to_number(const mbsfn_area_info_t::region_len_t& region_len) +{ + constexpr static uint16_t options[] = {1, 2}; + return enum_to_number(options, (uint32_t)mbsfn_area_info_t::region_len_t::nulltype, (uint32_t)region_len); +} +inline uint16_t enum_to_number(const mbsfn_area_info_t::mcch_cfg_t::repeat_period_t& repeat_period) +{ + constexpr static uint16_t options[] = {32, 64, 128, 256}; + return enum_to_number( + options, (uint32_t)mbsfn_area_info_t::mcch_cfg_t::repeat_period_t::nulltype, (uint32_t)repeat_period); +} +inline uint16_t enum_to_number(const mbsfn_area_info_t::mcch_cfg_t::sig_mcs_t& sig_mcs) +{ + constexpr static uint16_t options[] = {2, 7, 13, 19}; + return enum_to_number(options, (uint32_t)mbsfn_area_info_t::mcch_cfg_t::sig_mcs_t::nulltype, (uint32_t)sig_mcs); +} + +// TMGI-r9 +struct tmgi_t { + enum class plmn_id_type_t { plmn_idx, explicit_value } plmn_id_type; + union choice { + uint8_t plmn_idx; + plmn_id_t explicit_value; + choice() : plmn_idx(0) {} + } plmn_id; + uint8_t serviced_id[3]; + tmgi_t() : plmn_id_type(plmn_id_type_t::plmn_idx) {} +}; + +struct pmch_info_t { + // pmch_cfg_t + uint16_t sf_alloc_end = 0; + uint8_t data_mcs = 0; + enum class mch_sched_period_t { rf8, rf16, rf32, rf64, rf128, rf256, rf512, rf1024, nulltype } mch_sched_period; + // mbms_session_info_list + struct mbms_session_info_t { + bool session_id_present = false; + tmgi_t tmgi; + uint8_t session_id; + uint8_t lc_ch_id = 0; + }; + uint32_t nof_mbms_session_info; + static const uint32_t max_session_per_pmch = 29; + mbms_session_info_t mbms_session_info_list[max_session_per_pmch]; +}; +inline uint16_t enum_to_number(const pmch_info_t::mch_sched_period_t& mch_period) +{ + constexpr static uint16_t options[] = {8, 16, 32, 64, 128, 256, 512, 1024}; + return enum_to_number(options, (uint32_t)pmch_info_t::mch_sched_period_t::nulltype, (uint32_t)mch_period); +} + +struct mcch_msg_t { + uint32_t nof_common_sf_alloc = 0; + mbsfn_sf_cfg_t common_sf_alloc[8]; + enum class common_sf_alloc_period_t { rf4, rf8, rf16, rf32, rf64, rf128, rf256, nulltype } common_sf_alloc_period; + uint32_t nof_pmch_info; + pmch_info_t pmch_info_list[15]; + // mbsfn_area_cfg_v930_ies non crit ext OPTIONAL +}; +inline uint16_t enum_to_number(const mcch_msg_t::common_sf_alloc_period_t& alloc_period) +{ + constexpr static uint16_t options[] = {4, 8, 16, 32, 64, 128, 256}; + return enum_to_number(options, (uint32_t)mcch_msg_t::common_sf_alloc_period_t::nulltype, (uint32_t)alloc_period); +} + +struct phy_cfg_mbsfn_t { + mbsfn_sf_cfg_t mbsfn_subfr_cnfg; + mbms_notif_cfg_t mbsfn_notification_cnfg; + mbsfn_area_info_t mbsfn_area_info; + mcch_msg_t mcch; +}; + +// SystemInformationBlockType13-r9 +struct sib13_t { + static const uint32_t max_mbsfn_area = 8; + uint32_t nof_mbsfn_area_info = 0; + mbsfn_area_info_t mbsfn_area_info_list[max_mbsfn_area]; + mbms_notif_cfg_t notif_cfg; +}; + } // namespace srslte #endif // SRSLTE_RRC_INTERFACE_TYPES_H diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index c9dc1011e..7df8900c6 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -32,7 +32,6 @@ #include "rrc_interface_types.h" #include "srslte/asn1/liblte_mme.h" -#include "srslte/asn1/rrc_asn1.h" #include "srslte/common/common.h" #include "srslte/common/interfaces_common.h" #include "srslte/common/security.h" @@ -574,28 +573,21 @@ public: class phy_interface_rrc_lte { public: - struct phy_cfg_mbsfn_t { - asn1::rrc::mbsfn_sf_cfg_s mbsfn_subfr_cnfg; - asn1::rrc::mbms_notif_cfg_r9_s mbsfn_notification_cnfg; - asn1::rrc::mbsfn_area_info_r9_s mbsfn_area_info; - asn1::rrc::mcch_msg_s mcch; - }; - - virtual void get_current_cell(srslte_cell_t *cell, uint32_t *current_earfcn = NULL) = 0; - virtual uint32_t get_current_earfcn() = 0; - virtual uint32_t get_current_pci() = 0; + virtual void get_current_cell(srslte_cell_t* cell, uint32_t* current_earfcn = NULL) = 0; + virtual uint32_t get_current_earfcn() = 0; + virtual uint32_t get_current_pci() = 0; virtual void set_config(srslte::phy_cfg_t& config, uint32_t cc_idx = 0, uint32_t earfcn = 0, - srslte_cell_t* cell_info = nullptr) = 0; - virtual void set_config_tdd(srslte_tdd_config_t& tdd_config) = 0; - virtual void set_config_mbsfn_sib2(asn1::rrc::sib_type2_s* sib2) = 0; - virtual void set_config_mbsfn_sib13(asn1::rrc::sib_type13_r9_s* sib13) = 0; - virtual void set_config_mbsfn_mcch(asn1::rrc::mcch_msg_s* mcch) = 0; + srslte_cell_t* cell_info = nullptr) = 0; + virtual void set_config_tdd(srslte_tdd_config_t& tdd_config) = 0; + virtual void set_config_mbsfn_sib2(srslte::mbsfn_sf_cfg_t* cfg_list, uint32_t nof_cfgs) = 0; + virtual void set_config_mbsfn_sib13(const srslte::sib13_t& sib13) = 0; + virtual void set_config_mbsfn_mcch(const srslte::mcch_msg_t& mcch) = 0; /* Measurements interface */ - virtual void meas_reset() = 0; + virtual void meas_reset() = 0; virtual int meas_start(uint32_t earfcn, int pci = -1) = 0; virtual int meas_stop(uint32_t earfcn, int pci = -1) = 0; diff --git a/lib/src/asn1/rrc_asn1_utils.cc b/lib/src/asn1/rrc_asn1_utils.cc index 65c7ee4f1..c18bf8dec 100644 --- a/lib/src/asn1/rrc_asn1_utils.cc +++ b/lib/src/asn1/rrc_asn1_utils.cc @@ -684,4 +684,98 @@ void set_phy_cfg_t_scell_config(phy_cfg_t* cfg, const asn1::rrc::scell_to_add_mo } } +// MBMS + +mbms_notif_cfg_t make_mbms_notif_cfg(const asn1::rrc::mbms_notif_cfg_r9_s& asn1_type) +{ + mbms_notif_cfg_t ret; + ret.notif_repeat_coeff = (mbms_notif_cfg_t::coeff_t)asn1_type.notif_repeat_coeff_r9.value; + ret.notif_offset = asn1_type.notif_offset_r9; + ret.notif_sf_idx = asn1_type.notif_sf_idx_r9; + return ret; +} + +mbsfn_area_info_t make_mbsfn_area_info(const asn1::rrc::mbsfn_area_info_r9_s& asn1_type) +{ + mbsfn_area_info_t ret; + ret.mbsfn_area_id = asn1_type.mbsfn_area_id_r9; + ret.non_mbsfn_region_len = (mbsfn_area_info_t::region_len_t)asn1_type.non_mbsfn_region_len.value; + ret.notif_ind = asn1_type.notif_ind_r9; + ret.mcch_cfg.mcch_repeat_period = + (mbsfn_area_info_t::mcch_cfg_t::repeat_period_t)asn1_type.mcch_cfg_r9.mcch_repeat_period_r9.value; + ret.mcch_cfg.mcch_offset = asn1_type.mcch_cfg_r9.mcch_offset_r9; + ret.mcch_cfg.mcch_mod_period = + (mbsfn_area_info_t::mcch_cfg_t::mod_period_t)asn1_type.mcch_cfg_r9.mcch_mod_period_r9.value; + ret.mcch_cfg.sf_alloc_info = asn1_type.mcch_cfg_r9.sf_alloc_info_r9.to_number(); + ret.mcch_cfg.sig_mcs = (mbsfn_area_info_t::mcch_cfg_t::sig_mcs_t)asn1_type.mcch_cfg_r9.sig_mcs_r9.value; + return ret; +} + +mbsfn_sf_cfg_t make_mbsfn_sf_cfg(const asn1::rrc::mbsfn_sf_cfg_s& sf_cfg) +{ + mbsfn_sf_cfg_t cfg; + cfg.radioframe_alloc_period = (mbsfn_sf_cfg_t::alloc_period_t)sf_cfg.radioframe_alloc_period.value; + cfg.radioframe_alloc_offset = sf_cfg.radioframe_alloc_offset; + cfg.nof_alloc_subfrs = (mbsfn_sf_cfg_t::sf_alloc_type_t)sf_cfg.sf_alloc.type().value; + if (sf_cfg.sf_alloc.type().value == asn1::rrc::mbsfn_sf_cfg_s::sf_alloc_c_::types_opts::one_frame) { + cfg.sf_alloc = sf_cfg.sf_alloc.one_frame().to_number(); + } else { + cfg.sf_alloc = sf_cfg.sf_alloc.four_frames().to_number(); + } + return cfg; +} + +pmch_info_t make_pmch_info(const asn1::rrc::pmch_info_r9_s& asn1_type) +{ + pmch_info_t ret; + ret.sf_alloc_end = asn1_type.pmch_cfg_r9.sf_alloc_end_r9; + ret.data_mcs = asn1_type.pmch_cfg_r9.data_mcs_r9; + ret.mch_sched_period = (pmch_info_t::mch_sched_period_t)asn1_type.pmch_cfg_r9.mch_sched_period_r9.value; + + ret.nof_mbms_session_info = asn1_type.mbms_session_info_list_r9.size(); + for (uint32_t i = 0; i < ret.nof_mbms_session_info; ++i) { + auto& asn1item = asn1_type.mbms_session_info_list_r9[i]; + auto& item = ret.mbms_session_info_list[i]; + item.session_id_present = asn1item.session_id_r9_present; + item.lc_ch_id = asn1item.lc_ch_id_r9; + item.session_id = asn1item.session_id_r9[0]; + item.tmgi.plmn_id_type = (tmgi_t::plmn_id_type_t)asn1item.tmgi_r9.plmn_id_r9.type().value; + if (item.tmgi.plmn_id_type == tmgi_t::plmn_id_type_t::plmn_idx) { + item.tmgi.plmn_id.plmn_idx = asn1item.tmgi_r9.plmn_id_r9.plmn_idx_r9(); + } else { + item.tmgi.plmn_id.explicit_value = make_plmn_id_t(asn1item.tmgi_r9.plmn_id_r9.explicit_value_r9()); + } + memcpy(item.tmgi.serviced_id, &asn1item.tmgi_r9.service_id_r9[0], 3); + } + return ret; +} + +mcch_msg_t make_mcch_msg(const asn1::rrc::mcch_msg_s& asn1_type) +{ + mcch_msg_t msg; + auto& r9 = asn1_type.msg.c1().mbsfn_area_cfg_r9(); + msg.nof_common_sf_alloc = r9.common_sf_alloc_r9.size(); + for (uint32_t i = 0; i < msg.nof_common_sf_alloc; ++i) { + msg.common_sf_alloc[i] = make_mbsfn_sf_cfg(r9.common_sf_alloc_r9[i]); + } + msg.common_sf_alloc_period = (mcch_msg_t::common_sf_alloc_period_t)r9.common_sf_alloc_period_r9.value; + msg.nof_pmch_info = r9.pmch_info_list_r9.size(); + for (uint32_t i = 0; i < msg.nof_pmch_info; ++i) { + msg.pmch_info_list[i] = make_pmch_info(r9.pmch_info_list_r9[i]); + } + return msg; +} +static_assert(ASN1_RRC_MAX_SESSION_PER_PMCH == pmch_info_t::max_session_per_pmch, "ASN1 to srsLTE interface mismatch"); + +sib13_t make_sib13(const asn1::rrc::sib_type13_r9_s& asn1_type) +{ + sib13_t sib13; + sib13.nof_mbsfn_area_info = asn1_type.mbsfn_area_info_list_r9.size(); + for (uint32_t i = 0; i < asn1_type.mbsfn_area_info_list_r9.size(); ++i) { + sib13.mbsfn_area_info_list[i] = make_mbsfn_area_info(asn1_type.mbsfn_area_info_list_r9[i]); + } + sib13.notif_cfg = make_mbms_notif_cfg(asn1_type.notif_cfg_r9); + return sib13; +} + } // namespace srslte diff --git a/srsue/hdr/phy/phy.h b/srsue/hdr/phy/phy.h index d349884e8..3ba0588b0 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -110,10 +110,9 @@ public: void set_config(srslte::phy_cfg_t& config, uint32_t cc_idx, uint32_t earfcn, srslte_cell_t* cell_info) final; void set_config_tdd(srslte_tdd_config_t& tdd_config) final; -#pragma message("Remove ASN1 from MBSFN") - void set_config_mbsfn_sib2(asn1::rrc::sib_type2_s* sib2) final; - void set_config_mbsfn_sib13(asn1::rrc::sib_type13_r9_s* sib13) final; - void set_config_mbsfn_mcch(asn1::rrc::mcch_msg_s* mcch) final; + void set_config_mbsfn_sib2(srslte::mbsfn_sf_cfg_t* cfg_list, uint32_t nof_cfgs) final; + void set_config_mbsfn_sib13(const srslte::sib13_t& sib13) final; + void set_config_mbsfn_mcch(const srslte::mcch_msg_t& mcch) final; /*Set MAC->PHY MCH period stopping point*/ void set_mch_period_stop(uint32_t stop) final; diff --git a/srsue/hdr/phy/phy_common.h b/srsue/hdr/phy/phy_common.h index d198a03a5..29703974f 100644 --- a/srsue/hdr/phy/phy_common.h +++ b/srsue/hdr/phy/phy_common.h @@ -55,7 +55,7 @@ public: phy_args_t* args = nullptr; stack_interface_phy_lte* stack = nullptr; - phy_interface_rrc_lte::phy_cfg_mbsfn_t mbsfn_config; + srslte::phy_cfg_mbsfn_t mbsfn_config; /* Power control variables */ float pathloss[SRSLTE_MAX_CARRIERS] = {}; diff --git a/srsue/hdr/stack/rrc/rrc.h b/srsue/hdr/stack/rrc/rrc.h index 569a421be..cc8ac07f3 100644 --- a/srsue/hdr/stack/rrc/rrc.h +++ b/srsue/hdr/stack/rrc/rrc.h @@ -26,6 +26,7 @@ #include "rrc_common.h" #include "rrc_metrics.h" +#include "srslte/asn1/rrc_asn1.h" #include "srslte/asn1/rrc_asn1_utils.h" #include "srslte/common/bcd_helpers.h" #include "srslte/common/block_queue.h" @@ -37,8 +38,8 @@ #include "srslte/common/threads.h" #include "srslte/interfaces/ue_interfaces.h" -#include #include +#include #include #define SRSLTE_RRC_N_BANDS 43 diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index 4afb78b33..e023dbbc0 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -488,36 +488,34 @@ void phy::set_config_tdd(srslte_tdd_config_t& tdd_config_) } } -void phy::set_config_mbsfn_sib2(sib_type2_s* sib2) +void phy::set_config_mbsfn_sib2(srslte::mbsfn_sf_cfg_t* cfg_list, uint32_t nof_cfgs) { - if (sib2->mbsfn_sf_cfg_list_present and sib2->mbsfn_sf_cfg_list.size() > 1) { - Warning("SIB2 has %d MBSFN subframe configs - only 1 supported\n", sib2->mbsfn_sf_cfg_list.size()); + if (nof_cfgs > 1) { + Warning("SIB2 has %d MBSFN subframe configs - only 1 supported\n", nof_cfgs); } - if (sib2->mbsfn_sf_cfg_list_present and sib2->mbsfn_sf_cfg_list.size() > 0) { - common.mbsfn_config.mbsfn_subfr_cnfg = sib2->mbsfn_sf_cfg_list[0]; + if (nof_cfgs > 0) { + common.mbsfn_config.mbsfn_subfr_cnfg = cfg_list[0]; common.build_mch_table(); } } -void phy::set_config_mbsfn_sib13(sib_type13_r9_s* sib13) +void phy::set_config_mbsfn_sib13(const srslte::sib13_t& sib13) { - common.mbsfn_config.mbsfn_notification_cnfg = sib13->notif_cfg_r9; - if (sib13->mbsfn_area_info_list_r9.size() > 1) { - Warning("SIB13 has %d MBSFN area info elements - only 1 supported\n", sib13->mbsfn_area_info_list_r9.size()); + common.mbsfn_config.mbsfn_notification_cnfg = sib13.notif_cfg; + if (sib13.nof_mbsfn_area_info > 1) { + Warning("SIB13 has %d MBSFN area info elements - only 1 supported\n", sib13.nof_mbsfn_area_info); } - if (sib13->mbsfn_area_info_list_r9.size() > 0) { - common.mbsfn_config.mbsfn_area_info = sib13->mbsfn_area_info_list_r9[0]; + if (sib13.nof_mbsfn_area_info > 0) { + common.mbsfn_config.mbsfn_area_info = sib13.mbsfn_area_info_list[0]; common.build_mcch_table(); } } -void phy::set_config_mbsfn_mcch(mcch_msg_s* mcch) +void phy::set_config_mbsfn_mcch(const srslte::mcch_msg_t& mcch) { - common.mbsfn_config.mcch = *mcch; - stack->set_mbsfn_config( - common.mbsfn_config.mcch.msg.c1().mbsfn_area_cfg_r9().pmch_info_list_r9[0].mbms_session_info_list_r9.size()); - common.set_mch_period_stop( - common.mbsfn_config.mcch.msg.c1().mbsfn_area_cfg_r9().pmch_info_list_r9[0].pmch_cfg_r9.sf_alloc_end_r9); + common.mbsfn_config.mcch = mcch; + stack->set_mbsfn_config(common.mbsfn_config.mcch.pmch_info_list[0].nof_mbms_session_info); + common.set_mch_period_stop(common.mbsfn_config.mcch.pmch_info_list[0].sf_alloc_end); common.set_mcch(); } diff --git a/srsue/src/phy/phy_common.cc b/srsue/src/phy/phy_common.cc index 822d9ecec..79f8a6e5e 100644 --- a/srsue/src/phy/phy_common.cc +++ b/srsue/src/phy/phy_common.cc @@ -705,11 +705,10 @@ void phy_common::build_mch_table() bzero(&mch_table[0], sizeof(uint8_t) * 40); // 40 element table represents 4 frames (40 subframes) - if (mbsfn_config.mbsfn_subfr_cnfg.sf_alloc.type() == asn1::rrc::mbsfn_sf_cfg_s::sf_alloc_c_::types::one_frame) { - generate_mch_table(&mch_table[0], (uint32_t)mbsfn_config.mbsfn_subfr_cnfg.sf_alloc.one_frame().to_number(), 1u); - } else if (mbsfn_config.mbsfn_subfr_cnfg.sf_alloc.type() == - asn1::rrc::mbsfn_sf_cfg_s::sf_alloc_c_::types::four_frames) { - generate_mch_table(&mch_table[0], (uint32_t)mbsfn_config.mbsfn_subfr_cnfg.sf_alloc.four_frames().to_number(), 4u); + if (mbsfn_config.mbsfn_subfr_cnfg.nof_alloc_subfrs == srslte::mbsfn_sf_cfg_t::sf_alloc_type_t::one_frame) { + generate_mch_table(&mch_table[0], (uint32_t)mbsfn_config.mbsfn_subfr_cnfg.sf_alloc, 1u); + } else if (mbsfn_config.mbsfn_subfr_cnfg.nof_alloc_subfrs == srslte::mbsfn_sf_cfg_t::sf_alloc_type_t::four_frames) { + generate_mch_table(&mch_table[0], (uint32_t)mbsfn_config.mbsfn_subfr_cnfg.sf_alloc, 4u); } else { log_h->error("The subframe config has not been set for MBSFN\n"); } @@ -727,7 +726,7 @@ void phy_common::build_mcch_table() { // First reset tables bzero(&mcch_table[0], sizeof(uint8_t) * 10); - generate_mcch_table(&mcch_table[0], (uint32_t)mbsfn_config.mbsfn_area_info.mcch_cfg_r9.sf_alloc_info_r9.to_number()); + generate_mcch_table(&mcch_table[0], (uint32_t)mbsfn_config.mbsfn_area_info.mcch_cfg.sf_alloc_info); // Debug std::stringstream ss; ss << "|"; @@ -776,21 +775,21 @@ bool phy_common::is_mch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti) // Not MCCH, check for MCH if (sib13_configured) { - mbsfn_sf_cfg_s* subfr_cnfg = &mbsfn_config.mbsfn_subfr_cnfg; - asn1::rrc::mbsfn_area_info_r9_s* area_info = &mbsfn_config.mbsfn_area_info; - offset = subfr_cnfg->radioframe_alloc_offset; - period = subfr_cnfg->radioframe_alloc_period.to_number(); + srslte::mbsfn_sf_cfg_t& subfr_cnfg = mbsfn_config.mbsfn_subfr_cnfg; + srslte::mbsfn_area_info_t& area_info = mbsfn_config.mbsfn_area_info; + offset = subfr_cnfg.radioframe_alloc_offset; + period = srslte::enum_to_number(subfr_cnfg.radioframe_alloc_period); - if (subfr_cnfg->sf_alloc.type() == mbsfn_sf_cfg_s::sf_alloc_c_::types::one_frame) { + if (subfr_cnfg.nof_alloc_subfrs == srslte::mbsfn_sf_cfg_t::sf_alloc_type_t::one_frame) { if ((sfn % period == offset) && (mch_table[sf] > 0)) { - cfg->mbsfn_area_id = area_info->mbsfn_area_id_r9; - cfg->non_mbsfn_region_length = area_info->non_mbsfn_region_len.to_number(); + cfg->mbsfn_area_id = area_info.mbsfn_area_id; + cfg->non_mbsfn_region_length = enum_to_number(area_info.non_mbsfn_region_len); if (mcch_configured) { // Iterate through PMCH configs to see which one applies in the current frame - mbsfn_area_cfg_r9_s* mcch = &mbsfn_config.mcch.msg.c1().mbsfn_area_cfg_r9(); - uint32_t mbsfn_per_frame = mcch->pmch_info_list_r9[0].pmch_cfg_r9.sf_alloc_end_r9 / - mcch->pmch_info_list_r9[0].pmch_cfg_r9.mch_sched_period_r9.to_number(); - uint32_t frame_alloc_idx = sfn % mcch->common_sf_alloc_period_r9.to_number(); + srslte::mcch_msg_t& mcch = mbsfn_config.mcch; + uint32_t mbsfn_per_frame = + mcch.pmch_info_list[0].sf_alloc_end / enum_to_number(mcch.pmch_info_list[0].mch_sched_period); + uint32_t frame_alloc_idx = sfn % enum_to_number(mcch.common_sf_alloc_period); uint32_t sf_alloc_idx = frame_alloc_idx * mbsfn_per_frame + ((sf < 4) ? sf - 1 : sf - 3); std::unique_lock lock(mtch_mutex); while (!have_mtch_stop) { @@ -798,10 +797,10 @@ bool phy_common::is_mch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti) } mtch_mutex.unlock(); - for (uint32_t i = 0; i < mcch->pmch_info_list_r9.size(); i++) { + for (uint32_t i = 0; i < mcch.nof_pmch_info; i++) { if (sf_alloc_idx <= mch_period_stop) { // trigger conditional variable, has ot be untriggered by mtch stop location - cfg->mbsfn_mcs = mcch->pmch_info_list_r9[i].pmch_cfg_r9.data_mcs_r9; + cfg->mbsfn_mcs = mcch.pmch_info_list[i].data_mcs; cfg->enable = true; } else { // have_mtch_stop = false; @@ -811,12 +810,12 @@ bool phy_common::is_mch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti) } return true; } - } else if (subfr_cnfg->sf_alloc.type() == mbsfn_sf_cfg_s::sf_alloc_c_::types::four_frames) { + } else if (subfr_cnfg.nof_alloc_subfrs == srslte::mbsfn_sf_cfg_t::sf_alloc_type_t::four_frames) { uint8_t idx = sfn % period; if ((idx >= offset) && (idx < offset + 4)) { if (mch_table[(idx * 10) + sf] > 0) { - cfg->mbsfn_area_id = area_info->mbsfn_area_id_r9; - cfg->non_mbsfn_region_length = area_info->non_mbsfn_region_len.to_number(); + cfg->mbsfn_area_id = area_info.mbsfn_area_id; + cfg->non_mbsfn_region_length = enum_to_number(area_info.non_mbsfn_region_len); // TODO: check for MCCH configuration, set MCS and decode return true; } @@ -840,15 +839,15 @@ bool phy_common::is_mcch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti) sf = (uint8_t)(phy_tti % 10); if (sib13_configured) { - mbsfn_area_info_r9_s* area_info = &mbsfn_config.mbsfn_area_info; + srslte::mbsfn_area_info_t& area_info = mbsfn_config.mbsfn_area_info; - offset = area_info->mcch_cfg_r9.mcch_offset_r9; - period = area_info->mcch_cfg_r9.mcch_repeat_period_r9.to_number(); + offset = area_info.mcch_cfg.mcch_offset; + period = enum_to_number(area_info.mcch_cfg.mcch_repeat_period); if ((sfn % period == offset) && mcch_table[sf] > 0) { - cfg->mbsfn_area_id = area_info->mbsfn_area_id_r9; - cfg->non_mbsfn_region_length = area_info->non_mbsfn_region_len.to_number(); - cfg->mbsfn_mcs = area_info->mcch_cfg_r9.sig_mcs_r9.to_number(); + cfg->mbsfn_area_id = area_info.mbsfn_area_id; + cfg->non_mbsfn_region_length = enum_to_number(area_info.non_mbsfn_region_len); + cfg->mbsfn_mcs = enum_to_number(area_info.mcch_cfg.sig_mcs); cfg->enable = true; have_mtch_stop = false; Debug("MCCH subframe TTI:%d\n", phy_tti); diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index 057c25872..b922b1619 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -1644,7 +1644,13 @@ void rrc::handle_sib2() mac->set_config(current_mac_cfg); // Set MBSFN configs - phy->set_config_mbsfn_sib2(sib2); + if (sib2->mbsfn_sf_cfg_list_present) { + srslte::mbsfn_sf_cfg_t list[ASN1_RRC_MAX_MBSFN_ALLOCS]; + for (uint32_t i = 0; i < sib2->mbsfn_sf_cfg_list.size(); ++i) { + list[i] = srslte::make_mbsfn_sf_cfg(sib2->mbsfn_sf_cfg_list[i]); + } + phy->set_config_mbsfn_sib2(&list[0], sib2->mbsfn_sf_cfg_list.size()); + } // Apply PHY RR Config Common set_phy_cfg_t_common_pdsch(¤t_phy_cfg, sib2->rr_cfg_common.pdsch_cfg_common); @@ -1720,7 +1726,7 @@ void rrc::handle_sib13() sib_type13_r9_s* sib13 = serving_cell->sib13ptr(); - phy->set_config_mbsfn_sib13(sib13); + phy->set_config_mbsfn_sib13(srslte::make_sib13(*sib13)); add_mrb(0, 0); // Add MRB0 } @@ -1806,7 +1812,7 @@ void rrc::parse_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu) return; } serving_cell->has_mcch = true; - phy->set_config_mbsfn_mcch(&serving_cell->mcch); + phy->set_config_mbsfn_mcch(srslte::make_mcch_msg(serving_cell->mcch)); log_rrc_message("MCH", Rx, pdu.get(), serving_cell->mcch); if (args.mbms_service_id >= 0) { rrc_log->info("Attempting to auto-start MBMS service %d\n", args.mbms_service_id); diff --git a/srsue/test/mac_test.cc b/srsue/test/mac_test.cc index 7e328cbbc..26170f499 100644 --- a/srsue/test/mac_test.cc +++ b/srsue/test/mac_test.cc @@ -19,6 +19,7 @@ * */ +#include "srslte/asn1/rrc_asn1.h" #include "srslte/asn1/rrc_asn1_utils.h" #include "srslte/common/log_filter.h" #include "srslte/common/mac_pcap.h"