refactoring asn1 eMBMS code, removing asn1 from PHY and MAC in eNodeB

master
yagoda 4 years ago committed by Andre Puschmann
parent fb83b5c307
commit b90574975b

@ -224,16 +224,9 @@ public:
class phy_interface_rrc_lte class phy_interface_rrc_lte
{ {
public: public:
struct phy_cfg_mbsfn_t { srslte::phy_cfg_mbsfn_t mbsfn_cfg;
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 configure_mbsfn(asn1::rrc::sib_type2_s* sib2, virtual void configure_mbsfn(srslte::sib2_mbms_t* sib2, srslte::sib13_t* sib13, const srslte::mcch_msg_t& mcch) = 0;
asn1::rrc::sib_type13_r9_s* sib13,
const asn1::rrc::mcch_msg_s& mcch) = 0;
typedef struct { typedef struct {
bool configured = false; ///< Indicates whether PHY shall consider configuring this cell/carrier bool configured = false; ///< Indicates whether PHY shall consider configuring this cell/carrier
@ -291,8 +284,11 @@ public:
virtual int bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, sched_interface::ue_bearer_cfg_t* cfg) = 0; virtual int bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, sched_interface::ue_bearer_cfg_t* cfg) = 0;
virtual int bearer_ue_rem(uint16_t rnti, uint32_t lc_id) = 0; virtual int bearer_ue_rem(uint16_t rnti, uint32_t lc_id) = 0;
virtual void phy_config_enabled(uint16_t rnti, bool enabled) = 0; virtual void phy_config_enabled(uint16_t rnti, bool enabled) = 0;
virtual void virtual void write_mcch(srslte::sib2_mbms_t* sib2_,
write_mcch(asn1::rrc::sib_type2_s* sib2, asn1::rrc::sib_type13_r9_s* sib13, asn1::rrc::mcch_msg_s* mcch) = 0; srslte::sib13_t* sib13_,
srslte::mcch_msg_t* mcch_,
uint8_t* mcch_payload,
uint8_t mcch_payload_length) = 0;
/** /**
* Allocate a C-RNTI for a new user, without adding it to the phy layer and scheduler yet * Allocate a C-RNTI for a new user, without adding it to the phy layer and scheduler yet

@ -363,6 +363,13 @@ struct sib13_t {
mbms_notif_cfg_t notif_cfg; mbms_notif_cfg_t notif_cfg;
}; };
struct sib2_mbms_t {
bool mbsfn_sf_cfg_list_present;
static const uint32_t max_nof_mbsfn_sf_cfg = 8;
int nof_mbsfn_sf_cfg;
mbsfn_sf_cfg_t mbsfn_sf_cfg_list[max_nof_mbsfn_sf_cfg];
};
enum class barring_t { none = 0, mo_data, mo_signalling, mt, all }; enum class barring_t { none = 0, mo_data, mo_signalling, mt, all };
inline std::string to_string(const barring_t& b) inline std::string to_string(const barring_t& b)
{ {

@ -58,9 +58,7 @@ public:
const std::array<bool, SRSLTE_MAX_CARRIERS>& activation) override; const std::array<bool, SRSLTE_MAX_CARRIERS>& activation) override;
/*RRC-PHY interface*/ /*RRC-PHY interface*/
void configure_mbsfn(asn1::rrc::sib_type2_s* sib2, void configure_mbsfn(srslte::sib2_mbms_t* sib2, srslte::sib13_t* sib13, const srslte::mcch_msg_t& mcch) override;
asn1::rrc::sib_type13_r9_s* sib13,
const asn1::rrc::mcch_msg_s& mcch) override;
void start_plot() override; void start_plot() override;
void set_config(uint16_t rnti, const phy_rrc_cfg_list_t& phy_cfg_list) override; void set_config(uint16_t rnti, const phy_rrc_cfg_list_t& phy_cfg_list) override;
@ -74,7 +72,7 @@ public:
void radio_failure() override{}; void radio_failure() override{};
private: private:
phy_cfg_mbsfn_t mbsfn_config = {}; srslte::phy_cfg_mbsfn_t mbsfn_config = {};
uint32_t nof_workers = 0; uint32_t nof_workers = 0;
const static int MAX_WORKERS = 4; const static int MAX_WORKERS = 4;

@ -171,7 +171,7 @@ public:
*/ */
phy_ue_db ue_db; phy_ue_db ue_db;
void configure_mbsfn(phy_interface_stack_lte::phy_cfg_mbsfn_t* cfg); void configure_mbsfn(srslte::phy_cfg_mbsfn_t* cfg);
void build_mch_table(); void build_mch_table();
void build_mcch_table(); void build_mcch_table();
bool is_mbsfn_sf(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti); bool is_mbsfn_sf(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti);
@ -192,7 +192,7 @@ private:
bool have_mtch_stop = false; bool have_mtch_stop = false;
pthread_mutex_t mtch_mutex = {}; pthread_mutex_t mtch_mutex = {};
pthread_cond_t mtch_cvar = {}; pthread_cond_t mtch_cvar = {};
phy_interface_stack_lte::phy_cfg_mbsfn_t mbsfn = {}; srslte::phy_cfg_mbsfn_t mbsfn = {};
bool sib13_configured = false; bool sib13_configured = false;
bool mcch_configured = false; bool mcch_configured = false;
uint8_t mch_table[40] = {}; uint8_t mch_table[40] = {};

@ -99,8 +99,11 @@ public:
bool process_pdus(); bool process_pdus();
void get_metrics(mac_metrics_t metrics[ENB_METRICS_MAX_USERS]); void get_metrics(mac_metrics_t metrics[ENB_METRICS_MAX_USERS]);
void void write_mcch(srslte::sib2_mbms_t* sib2_,
write_mcch(asn1::rrc::sib_type2_s* sib2, asn1::rrc::sib_type13_r9_s* sib13, asn1::rrc::mcch_msg_s* mcch) override; srslte::sib13_t* sib13_,
srslte::mcch_msg_t* mcch_,
uint8_t* mcch_payload,
uint8_t mcch_payload_length) override;
private: private:
static const uint32_t cfi = 3; static const uint32_t cfi = 3;
@ -167,10 +170,9 @@ private:
const static int mcch_payload_len = 3000; // TODO FIND OUT MAX LENGTH const static int mcch_payload_len = 3000; // TODO FIND OUT MAX LENGTH
int current_mcch_length = 0; int current_mcch_length = 0;
uint8_t mcch_payload_buffer[mcch_payload_len] = {}; uint8_t mcch_payload_buffer[mcch_payload_len] = {};
asn1::rrc::mcch_msg_s mcch; srslte::mcch_msg_t mcch;
asn1::rrc::sib_type2_s sib2; srslte::sib2_mbms_t sib2;
asn1::rrc::sib_type13_r9_s sib13; srslte::sib13_t sib13;
const static int mtch_payload_len = 10000; const static int mtch_payload_len = 10000;
uint8_t mtch_payload_buffer[mtch_payload_len] = {}; uint8_t mtch_payload_buffer[mtch_payload_len] = {};

@ -152,7 +152,8 @@ private:
void process_release_complete(uint16_t rnti); void process_release_complete(uint16_t rnti);
void rem_user(uint16_t rnti); void rem_user(uint16_t rnti);
uint32_t generate_sibs(); uint32_t generate_sibs();
void configure_mbsfn_sibs(asn1::rrc::sib_type2_s* sib2, asn1::rrc::sib_type13_r9_s* sib13); void configure_mbsfn_sibs(srslte::sib2_mbms_t* sib2_, srslte::sib13_t* sib13_);
int pack_mcch();
void config_mac(); void config_mac();
void parse_ul_dcch(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t pdu); void parse_ul_dcch(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t pdu);
@ -160,7 +161,9 @@ private:
uint32_t paging_tti = INVALID_TTI; uint32_t paging_tti = INVALID_TTI;
srslte::byte_buffer_t byte_buf_paging; srslte::byte_buffer_t byte_buf_paging;
const static int mcch_payload_len = 3000;
int current_mcch_length = 0;
uint8_t mcch_payload_buffer[mcch_payload_len] = {};
typedef struct { typedef struct {
uint16_t rnti; uint16_t rnti;
uint32_t lcid; uint32_t lcid;

@ -252,14 +252,14 @@ void phy::complete_config(uint16_t rnti)
workers_common.ue_db.complete_config(rnti); workers_common.ue_db.complete_config(rnti);
} }
void phy::configure_mbsfn(sib_type2_s* sib2, sib_type13_r9_s* sib13, const mcch_msg_s& mcch) void phy::configure_mbsfn(srslte::sib2_mbms_t* sib2, srslte::sib13_t* sib13, const srslte::mcch_msg_t& mcch)
{ {
if (sib2->mbsfn_sf_cfg_list_present) { if (sib2->mbsfn_sf_cfg_list_present) {
if (sib2->mbsfn_sf_cfg_list.size() == 0) { if (sib2->nof_mbsfn_sf_cfg == 0) {
Warning("SIB2 does not have any MBSFN config although it was set as present\n"); Warning("SIB2 does not have any MBSFN config although it was set as present\n");
} else { } else {
if (sib2->mbsfn_sf_cfg_list.size() > 1) { if (sib2->nof_mbsfn_sf_cfg > 1) {
Warning("SIB2 has %d MBSFN subframe configs - only 1 supported\n", sib2->mbsfn_sf_cfg_list.size()); Warning("SIB2 has %d MBSFN subframe configs - only 1 supported\n", sib2->nof_mbsfn_sf_cfg);
} }
mbsfn_config.mbsfn_subfr_cnfg = sib2->mbsfn_sf_cfg_list[0]; mbsfn_config.mbsfn_subfr_cnfg = sib2->mbsfn_sf_cfg_list[0];
} }
@ -268,12 +268,12 @@ void phy::configure_mbsfn(sib_type2_s* sib2, sib_type13_r9_s* sib13, const mcch_
return; return;
} }
mbsfn_config.mbsfn_notification_cnfg = sib13->notif_cfg_r9; mbsfn_config.mbsfn_notification_cnfg = sib13->notif_cfg;
if (sib13->mbsfn_area_info_list_r9.size() > 0) { if (sib13->nof_mbsfn_area_info > 0) {
if (sib13->mbsfn_area_info_list_r9.size() > 1) { if (sib13->nof_mbsfn_area_info > 1) {
Warning("SIB13 has %d MBSFN area info elements - only 1 supported\n", sib13->mbsfn_area_info_list_r9.size()); Warning("SIB13 has %d MBSFN area info elements - only 1 supported\n", sib13->nof_mbsfn_area_info);
} }
mbsfn_config.mbsfn_area_info = sib13->mbsfn_area_info_list_r9[0]; mbsfn_config.mbsfn_area_info = sib13->mbsfn_area_info_list[0];
} }
mbsfn_config.mcch = mcch; mbsfn_config.mcch = mcch;

@ -151,7 +151,7 @@ void phy_common::set_mch_period_stop(uint32_t stop)
pthread_mutex_unlock(&mtch_mutex); pthread_mutex_unlock(&mtch_mutex);
} }
void phy_common::configure_mbsfn(phy_interface_stack_lte::phy_cfg_mbsfn_t* cfg) void phy_common::configure_mbsfn(srslte::phy_cfg_mbsfn_t* cfg)
{ {
mbsfn = *cfg; mbsfn = *cfg;
@ -168,11 +168,11 @@ void phy_common::build_mch_table()
// 40 element table represents 4 frames (40 subframes) // 40 element table represents 4 frames (40 subframes)
uint32_t nof_sfs = 0; uint32_t nof_sfs = 0;
if (mbsfn.mbsfn_subfr_cnfg.sf_alloc.type().value == mbsfn_sf_cfg_s::sf_alloc_c_::types::one_frame) { if (mbsfn.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.mbsfn_subfr_cnfg.sf_alloc.one_frame().to_number(), 1); generate_mch_table(&mch_table[0], (uint32_t)mbsfn.mbsfn_subfr_cnfg.sf_alloc, 1);
nof_sfs = 10; nof_sfs = 10;
} else if (mbsfn.mbsfn_subfr_cnfg.sf_alloc.type().value == mbsfn_sf_cfg_s::sf_alloc_c_::types::four_frames) { } else if (mbsfn.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.mbsfn_subfr_cnfg.sf_alloc.four_frames().to_number(), 4); generate_mch_table(&mch_table[0], (uint32_t)mbsfn.mbsfn_subfr_cnfg.sf_alloc, 4);
nof_sfs = 40; nof_sfs = 40;
} else { } else {
fprintf(stderr, "No valid SF alloc\n"); fprintf(stderr, "No valid SF alloc\n");
@ -191,8 +191,7 @@ void phy_common::build_mcch_table()
{ {
ZERO_OBJECT(mcch_table); ZERO_OBJECT(mcch_table);
generate_mcch_table(mcch_table, generate_mcch_table(mcch_table, static_cast<uint32_t>(mbsfn.mbsfn_area_info.mcch_cfg.sf_alloc_info));
static_cast<uint32_t>(mbsfn.mbsfn_area_info.mcch_cfg_r9.sf_alloc_info_r9.to_number()));
std::stringstream ss; std::stringstream ss;
ss << "|"; ss << "|";
@ -212,15 +211,15 @@ bool phy_common::is_mcch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti)
sf = phy_tti % 10; sf = phy_tti % 10;
if (sib13_configured) { if (sib13_configured) {
mbsfn_area_info_r9_s* area_info = &mbsfn.mbsfn_area_info; // mbsfn_area_info_r9_s* area_info = &mbsfn.mbsfn_area_info;
srslte::mbsfn_area_info_t* area_info = &mbsfn.mbsfn_area_info;
offset = area_info->mcch_cfg_r9.mcch_offset_r9; offset = area_info->mcch_cfg.mcch_offset;
period = area_info->mcch_cfg_r9.mcch_repeat_period_r9.to_number(); period = enum_to_number(area_info->mcch_cfg.mcch_repeat_period);
if ((sfn % period == offset) && mcch_table[sf] > 0) { if ((sfn % period == offset) && mcch_table[sf] > 0) {
cfg->mbsfn_area_id = area_info->mbsfn_area_id_r9; cfg->mbsfn_area_id = area_info->mbsfn_area_id;
cfg->non_mbsfn_region_length = area_info->non_mbsfn_region_len.to_number(); cfg->non_mbsfn_region_length = enum_to_number(area_info->non_mbsfn_region_len);
cfg->mbsfn_mcs = area_info->mcch_cfg_r9.sig_mcs_r9.to_number(); cfg->mbsfn_mcs = enum_to_number(area_info->mcch_cfg.sig_mcs);
cfg->enable = true; cfg->enable = true;
cfg->is_mcch = true; cfg->is_mcch = true;
have_mtch_stop = false; have_mtch_stop = false;
@ -255,32 +254,29 @@ bool phy_common::is_mch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti)
} }
// Not MCCH, check for MCH // Not MCCH, check for MCH
mbsfn_sf_cfg_s* subfr_cnfg = &mbsfn.mbsfn_subfr_cnfg; srslte::mbsfn_sf_cfg_t* subfr_cnfg = &mbsfn.mbsfn_subfr_cnfg;
mbsfn_area_info_r9_s* area_info = &mbsfn.mbsfn_area_info; srslte::mbsfn_area_info_t* area_info = &mbsfn.mbsfn_area_info;
offset = subfr_cnfg->radioframe_alloc_offset; offset = subfr_cnfg->radioframe_alloc_offset;
period = subfr_cnfg->radioframe_alloc_period.to_number(); period = 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)) { if ((sfn % period == offset) && (mch_table[sf] > 0)) {
if (sib13_configured) { if (sib13_configured) {
cfg->mbsfn_area_id = area_info->mbsfn_area_id_r9; cfg->mbsfn_area_id = area_info->mbsfn_area_id;
cfg->non_mbsfn_region_length = area_info->non_mbsfn_region_len.to_number(); cfg->non_mbsfn_region_length = enum_to_number(area_info->non_mbsfn_region_len);
if (mcch_configured) { if (mcch_configured) {
// Iterate through PMCH configs to see which one applies in the current frame // Iterate through PMCH configs to see which one applies in the current frame
mbsfn_area_cfg_r9_s* area_r9 = &mbsfn.mcch.msg.c1().mbsfn_area_cfg_r9(); uint32_t frame_alloc_idx = sfn % enum_to_number(mbsfn.mcch.common_sf_alloc_period);
uint32_t mbsfn_per_frame = mbsfn.mcch.pmch_info_list[0].sf_alloc_end /
uint32_t frame_alloc_idx = sfn % area_r9->common_sf_alloc_period_r9.to_number(); +enum_to_number(mbsfn.mcch.pmch_info_list[0].mch_sched_period);
uint32_t mbsfn_per_frame = area_r9->pmch_info_list_r9[0].pmch_cfg_r9.sf_alloc_end_r9 /
+area_r9->pmch_info_list_r9[0].pmch_cfg_r9.mch_sched_period_r9.to_number();
uint32_t sf_alloc_idx = frame_alloc_idx * mbsfn_per_frame + ((sf < 4) ? sf - 1 : sf - 3); uint32_t sf_alloc_idx = frame_alloc_idx * mbsfn_per_frame + ((sf < 4) ? sf - 1 : sf - 3);
while (!have_mtch_stop) { while (!have_mtch_stop) {
pthread_cond_wait(&mtch_cvar, &mtch_mutex); pthread_cond_wait(&mtch_cvar, &mtch_mutex);
} }
for (uint32_t i = 0; i < mbsfn.mcch.nof_pmch_info; i++) {
for (uint32_t i = 0; i < area_r9->pmch_info_list_r9.size(); i++) {
if (sf_alloc_idx <= mch_period_stop) { if (sf_alloc_idx <= mch_period_stop) {
cfg->mbsfn_mcs = mbsfn.mcch.msg.c1().mbsfn_area_cfg_r9().pmch_info_list_r9[i].pmch_cfg_r9.data_mcs_r9; cfg->mbsfn_mcs = mbsfn.mcch.pmch_info_list[i].data_mcs;
cfg->enable = true; cfg->enable = true;
} }
} }
@ -288,13 +284,13 @@ bool phy_common::is_mch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti)
} }
return true; 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; uint8_t idx = sfn % period;
if ((idx >= offset) && (idx < offset + 4)) { if ((idx >= offset) && (idx < offset + 4)) {
if (mch_table[(idx * 10) + sf] > 0) { if (mch_table[(idx * 10) + sf] > 0) {
if (sib13_configured) { if (sib13_configured) {
cfg->mbsfn_area_id = area_info->mbsfn_area_id_r9; cfg->mbsfn_area_id = area_info->mbsfn_area_id;
cfg->non_mbsfn_region_length = area_info->non_mbsfn_region_len.to_number(); cfg->non_mbsfn_region_length = enum_to_number(area_info->non_mbsfn_region_len);
// TODO: check for MCCH configuration, set MCS and decode // TODO: check for MCCH configuration, set MCS and decode
} }
return true; return true;

@ -702,7 +702,7 @@ int mac::get_dl_sched(uint32_t tti_tx_dl, dl_sched_list_t& dl_sched_res_list)
void mac::build_mch_sched(uint32_t tbs) void mac::build_mch_sched(uint32_t tbs)
{ {
int sfs_per_sched_period = mcch.msg.c1().mbsfn_area_cfg_r9().pmch_info_list_r9[0].pmch_cfg_r9.sf_alloc_end_r9; int sfs_per_sched_period = mcch.pmch_info_list[0].sf_alloc_end;
int bytes_per_sf = tbs / 8 - 6; // leave 6 bytes for header int bytes_per_sf = tbs / 8 - 6; // leave 6 bytes for header
int total_space_avail_bytes = sfs_per_sched_period * bytes_per_sf; int total_space_avail_bytes = sfs_per_sched_period * bytes_per_sf;
@ -739,8 +739,8 @@ int mac::get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res
log_h->step(tti); log_h->step(tti);
srslte_ra_tb_t mcs = {}; srslte_ra_tb_t mcs = {};
srslte_ra_tb_t mcs_data = {}; srslte_ra_tb_t mcs_data = {};
mcs.mcs_idx = this->sib13.mbsfn_area_info_list_r9[0].mcch_cfg_r9.sig_mcs_r9.to_number(); mcs.mcs_idx = enum_to_number(this->sib13.mbsfn_area_info_list[0].mcch_cfg.sig_mcs);
mcs_data.mcs_idx = this->mcch.msg.c1().mbsfn_area_cfg_r9().pmch_info_list_r9[0].pmch_cfg_r9.data_mcs_r9; mcs_data.mcs_idx = this->mcch.pmch_info_list[0].data_mcs;
srslte_dl_fill_ra_mcs(&mcs, 0, cell_config[0].cell.nof_prb, false); srslte_dl_fill_ra_mcs(&mcs, 0, cell_config[0].cell.nof_prb, false);
srslte_dl_fill_ra_mcs(&mcs_data, 0, cell_config[0].cell.nof_prb, false); srslte_dl_fill_ra_mcs(&mcs_data, 0, cell_config[0].cell.nof_prb, false);
if (is_mcch) { if (is_mcch) {
@ -924,22 +924,21 @@ bool mac::process_pdus()
return ret; return ret;
} }
void mac::write_mcch(sib_type2_s* sib2_, sib_type13_r9_s* sib13_, mcch_msg_s* mcch_) void mac::write_mcch(srslte::sib2_mbms_t* sib2_,
srslte::sib13_t* sib13_,
srslte::mcch_msg_t* mcch_,
uint8_t* mcch_payload,
uint8_t mcch_payload_length)
{ {
mcch = *mcch_; mcch = *mcch_;
mch.num_mtch_sched = this->mcch.msg.c1().mbsfn_area_cfg_r9().pmch_info_list_r9[0].mbms_session_info_list_r9.size(); mch.num_mtch_sched = this->mcch.pmch_info_list[0].nof_mbms_session_info;
for (uint32_t i = 0; i < mch.num_mtch_sched; ++i) { for (uint32_t i = 0; i < mch.num_mtch_sched; ++i) {
mch.mtch_sched[i].lcid = mch.mtch_sched[i].lcid = this->mcch.pmch_info_list[0].mbms_session_info_list[i].lc_ch_id;
this->mcch.msg.c1().mbsfn_area_cfg_r9().pmch_info_list_r9[0].mbms_session_info_list_r9[i].lc_ch_id_r9;
} }
sib2 = *sib2_; sib2 = *sib2_;
sib13 = *sib13_; sib13 = *sib13_;
memcpy(mcch_payload_buffer, mcch_payload, mcch_payload_length * sizeof(uint8_t));
const int rlc_header_len = 1; current_mcch_length = mcch_payload_length;
asn1::bit_ref bref(&mcch_payload_buffer[rlc_header_len], sizeof(mcch_payload_buffer) - rlc_header_len);
mcch.pack(bref);
current_mcch_length = bref.distance_bytes(&mcch_payload_buffer[1]);
current_mcch_length = current_mcch_length + rlc_header_len;
ue_db[SRSLTE_MRNTI] = ue_db[SRSLTE_MRNTI] =
std::unique_ptr<ue>{new ue(SRSLTE_MRNTI, args.nof_prb, &scheduler, rrc_h, rlc_h, phy_h, log_h, cells.size())}; std::unique_ptr<ue>{new ue(SRSLTE_MRNTI, args.nof_prb, &scheduler, rrc_h, rlc_h, phy_h, log_h, cells.size())};

@ -65,7 +65,53 @@ void rrc::init(const rrc_cfg_t& cfg_,
if (cfg.sibs[12].type() == asn1::rrc::sys_info_r8_ies_s::sib_type_and_info_item_c_::types::sib13_v920 && if (cfg.sibs[12].type() == asn1::rrc::sys_info_r8_ies_s::sib_type_and_info_item_c_::types::sib13_v920 &&
cfg.enable_mbsfn) { cfg.enable_mbsfn) {
configure_mbsfn_sibs(&cfg.sibs[1].sib2(), &cfg.sibs[12].sib13_v920()); srslte::sib2_mbms_t sibs2;
sibs2.mbsfn_sf_cfg_list_present = cfg.sibs[1].sib2().mbsfn_sf_cfg_list_present;
sibs2.nof_mbsfn_sf_cfg = cfg.sibs[1].sib2().mbsfn_sf_cfg_list.size();
for (int i = 0; i < sibs2.nof_mbsfn_sf_cfg; i++) {
sibs2.mbsfn_sf_cfg_list[i].nof_alloc_subfrs = srslte::mbsfn_sf_cfg_t::sf_alloc_type_t::one_frame;
sibs2.mbsfn_sf_cfg_list[i].radioframe_alloc_offset =
cfg.sibs[1].sib2().mbsfn_sf_cfg_list[i].radioframe_alloc_offset;
sibs2.mbsfn_sf_cfg_list[i].radioframe_alloc_period =
(srslte::mbsfn_sf_cfg_t::alloc_period_t)cfg.sibs[1].sib2().mbsfn_sf_cfg_list[i].radioframe_alloc_period.value;
sibs2.mbsfn_sf_cfg_list[i].sf_alloc =
(uint32_t)cfg.sibs[1].sib2().mbsfn_sf_cfg_list[i].sf_alloc.one_frame().to_number();
}
srslte::sib13_t sibs13;
sibs13.notif_cfg.notif_offset = cfg.sibs[12].sib13_v920().notif_cfg_r9.notif_offset_r9;
sibs13.notif_cfg.notif_repeat_coeff =
(srslte::mbms_notif_cfg_t::coeff_t)cfg.sibs[12].sib13_v920().notif_cfg_r9.notif_repeat_coeff_r9.value;
sibs13.notif_cfg.notif_sf_idx = cfg.sibs[12].sib13_v920().notif_cfg_r9.notif_sf_idx_r9;
sibs13.nof_mbsfn_area_info = cfg.sibs[12].sib13_v920().mbsfn_area_info_list_r9.size();
for (uint32_t i = 0; i < sibs13.nof_mbsfn_area_info; i++) {
sibs13.mbsfn_area_info_list[i].mbsfn_area_id =
cfg.sibs[12].sib13_v920().mbsfn_area_info_list_r9[i].mbsfn_area_id_r9;
sibs13.mbsfn_area_info_list[i].notif_ind = cfg.sibs[12].sib13_v920().mbsfn_area_info_list_r9[i].notif_ind_r9;
sibs13.mbsfn_area_info_list[i].mcch_cfg.sig_mcs = (srslte::mbsfn_area_info_t::mcch_cfg_t::sig_mcs_t)cfg.sibs[12]
.sib13_v920()
.mbsfn_area_info_list_r9[i]
.mcch_cfg_r9.sig_mcs_r9.value;
sibs13.mbsfn_area_info_list[i].mcch_cfg.sf_alloc_info =
cfg.sibs[12].sib13_v920().mbsfn_area_info_list_r9[i].mcch_cfg_r9.sf_alloc_info_r9.to_number();
sibs13.mbsfn_area_info_list[i].mcch_cfg.mcch_repeat_period =
(srslte::mbsfn_area_info_t::mcch_cfg_t::repeat_period_t)cfg.sibs[12]
.sib13_v920()
.mbsfn_area_info_list_r9[i]
.mcch_cfg_r9.mcch_repeat_period_r9.value;
sibs13.mbsfn_area_info_list[i].mcch_cfg.mcch_offset =
cfg.sibs[12].sib13_v920().mbsfn_area_info_list_r9[i].mcch_cfg_r9.mcch_offset_r9;
sibs13.mbsfn_area_info_list[i].mcch_cfg.mcch_mod_period =
(srslte::mbsfn_area_info_t::mcch_cfg_t::mod_period_t)cfg.sibs[12]
.sib13_v920()
.mbsfn_area_info_list_r9[i]
.mcch_cfg_r9.mcch_mod_period_r9.value;
sibs13.mbsfn_area_info_list[i].non_mbsfn_region_len = (srslte::mbsfn_area_info_t::region_len_t)cfg.sibs[12]
.sib13_v920()
.mbsfn_area_info_list_r9[i]
.non_mbsfn_region_len.value;
sibs13.mbsfn_area_info_list[i].notif_ind = cfg.sibs[12].sib13_v920().mbsfn_area_info_list_r9[i].notif_ind_r9;
}
configure_mbsfn_sibs(&sibs2, &sibs13);
} }
cell_res_list.reset(new freq_res_common_list{cfg}); cell_res_list.reset(new freq_res_common_list{cfg});
@ -702,9 +748,41 @@ uint32_t rrc::generate_sibs()
return nof_messages; return nof_messages;
} }
void rrc::configure_mbsfn_sibs(sib_type2_s* sib2_, sib_type13_r9_s* sib13_) void rrc::configure_mbsfn_sibs(srslte::sib2_mbms_t* sib2_, srslte::sib13_t* sib13_)
{
pack_mcch();
srslte::mcch_msg_t mcch_t;
mcch_t.common_sf_alloc_period = srslte::mcch_msg_t::common_sf_alloc_period_t::rf64;
mcch_t.nof_common_sf_alloc = 1;
srslte::mbsfn_sf_cfg_t sf_alloc_item = mcch_t.common_sf_alloc[0];
sf_alloc_item.radioframe_alloc_offset = 0;
sf_alloc_item.radioframe_alloc_period = srslte::mbsfn_sf_cfg_t::alloc_period_t::n1;
sf_alloc_item.sf_alloc = 63;
mcch_t.nof_pmch_info = 1;
srslte::pmch_info_t* pmch_item = &mcch_t.pmch_info_list[0];
pmch_item->nof_mbms_session_info = 1;
pmch_item->mbms_session_info_list[0].lc_ch_id = 1;
if (pmch_item->nof_mbms_session_info > 1) {
pmch_item->mbms_session_info_list[1].lc_ch_id = 2;
}
uint16_t mbms_mcs = cfg.mbms_mcs;
if (mbms_mcs > 28) {
mbms_mcs = 28; // TS 36.213, Table 8.6.1-1
rrc_log->warning("PMCH data MCS too high, setting it to 28\n");
}
rrc_log->debug("PMCH data MCS=%d\n", mbms_mcs);
pmch_item->data_mcs = mbms_mcs;
pmch_item->mch_sched_period = srslte::pmch_info_t::mch_sched_period_t::rf64;
pmch_item->sf_alloc_end = 64 * 6;
phy->configure_mbsfn(sib2_, sib13_, mcch_t);
mac->write_mcch(sib2_, sib13_, &mcch_t, mcch_payload_buffer, current_mcch_length);
}
int rrc::pack_mcch()
{ {
// Temp assignment of MCCH, this will eventually come from a cfg file
mcch.msg.set_c1();
mcch.msg.set_c1(); mcch.msg.set_c1();
mbsfn_area_cfg_r9_s& area_cfg_r9 = mcch.msg.c1().mbsfn_area_cfg_r9(); mbsfn_area_cfg_r9_s& area_cfg_r9 = mcch.msg.c1().mbsfn_area_cfg_r9();
area_cfg_r9.common_sf_alloc_period_r9 = mbsfn_area_cfg_r9_s::common_sf_alloc_period_r9_e_::rf64; area_cfg_r9.common_sf_alloc_period_r9 = mbsfn_area_cfg_r9_s::common_sf_alloc_period_r9_e_::rf64;
@ -751,8 +829,12 @@ void rrc::configure_mbsfn_sibs(sib_type2_s* sib2_, sib_type13_r9_s* sib13_)
pmch_item->pmch_cfg_r9.mch_sched_period_r9 = pmch_cfg_r9_s::mch_sched_period_r9_e_::rf64; pmch_item->pmch_cfg_r9.mch_sched_period_r9 = pmch_cfg_r9_s::mch_sched_period_r9_e_::rf64;
pmch_item->pmch_cfg_r9.sf_alloc_end_r9 = 64 * 6; pmch_item->pmch_cfg_r9.sf_alloc_end_r9 = 64 * 6;
phy->configure_mbsfn(sib2_, sib13_, mcch); const int rlc_header_len = 1;
mac->write_mcch(sib2_, sib13_, &mcch); asn1::bit_ref bref(&mcch_payload_buffer[rlc_header_len], sizeof(mcch_payload_buffer) - rlc_header_len);
mcch.pack(bref);
current_mcch_length = bref.distance_bytes(&mcch_payload_buffer[1]);
current_mcch_length = current_mcch_length + rlc_header_len;
return current_mcch_length;
} }
/******************************************************************************* /*******************************************************************************

@ -37,7 +37,11 @@ public:
int bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, sched_interface::ue_bearer_cfg_t* cfg) override { return 0; } int bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, sched_interface::ue_bearer_cfg_t* cfg) override { return 0; }
int bearer_ue_rem(uint16_t rnti, uint32_t lc_id) override { return 0; } int bearer_ue_rem(uint16_t rnti, uint32_t lc_id) override { return 0; }
void phy_config_enabled(uint16_t rnti, bool enabled) override {} void phy_config_enabled(uint16_t rnti, bool enabled) override {}
void write_mcch(asn1::rrc::sib_type2_s* sib2, asn1::rrc::sib_type13_r9_s* sib13, asn1::rrc::mcch_msg_s* mcch) override void write_mcch(srslte::sib2_mbms_t* sib2_,
srslte::sib13_t* sib13_,
srslte::mcch_msg_t* mcch_,
uint8_t* mcch_payload,
uint8_t mcch_payload_length) override
{} {}
uint16_t reserve_new_crnti(const sched_interface::ue_cfg_t& ue_cfg) override { return last_rnti++; } uint16_t reserve_new_crnti(const sched_interface::ue_cfg_t& ue_cfg) override { return last_rnti++; }
@ -121,10 +125,7 @@ public:
class phy_dummy : public phy_interface_rrc_lte class phy_dummy : public phy_interface_rrc_lte
{ {
public: public:
void configure_mbsfn(asn1::rrc::sib_type2_s* sib2, void configure_mbsfn(srslte::sib2_mbms_t* sib2, srslte::sib13_t* sib13, const srslte::mcch_msg_t& mcch) override {}
asn1::rrc::sib_type13_r9_s* sib13,
const asn1::rrc::mcch_msg_s& mcch) override
{}
void set_config(uint16_t rnti, const phy_rrc_cfg_list_t& dedicated_list) override {} void set_config(uint16_t rnti, const phy_rrc_cfg_list_t& dedicated_list) override {}
void complete_config(uint16_t rnti) override{}; void complete_config(uint16_t rnti) override{};
}; };

Loading…
Cancel
Save