mirror of https://github.com/PentHertz/srsLTE.git
introducing support for embms in the enodeb PHY
This commit is contained in:
parent
d80d49a9da
commit
08976bb948
|
@ -30,12 +30,12 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "srslte/interfaces/enb_interfaces.h"
|
#include "srslte/interfaces/enb_interfaces.h"
|
||||||
#include "srslte/interfaces/enb_metrics_interface.h"
|
#include "srslte/interfaces/enb_metrics_interface.h"
|
||||||
|
#include "srslte/common/gen_mch_tables.h"
|
||||||
#include "srslte/common/log.h"
|
#include "srslte/common/log.h"
|
||||||
#include "srslte/common/threads.h"
|
#include "srslte/common/threads.h"
|
||||||
#include "srslte/common/thread_pool.h"
|
#include "srslte/common/thread_pool.h"
|
||||||
#include "srslte/radio/radio.h"
|
#include "srslte/radio/radio.h"
|
||||||
|
#include <string.h>
|
||||||
namespace srsenb {
|
namespace srsenb {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -48,6 +48,26 @@ typedef struct {
|
||||||
bool pregenerate_signals;
|
bool pregenerate_signals;
|
||||||
} phy_args_t;
|
} phy_args_t;
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
SUBFRAME_TYPE_REGULAR = 0,
|
||||||
|
SUBFRAME_TYPE_MBSFN,
|
||||||
|
SUBFRAME_TYPE_N_ITEMS,
|
||||||
|
} subframe_type_t;
|
||||||
|
static const char subframe_type_text[SUBFRAME_TYPE_N_ITEMS][20] = {"Regular", "MBSFN"};
|
||||||
|
|
||||||
|
/* Subframe config */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
subframe_type_t sf_type;
|
||||||
|
uint8_t mbsfn_area_id;
|
||||||
|
uint8_t non_mbsfn_region_length;
|
||||||
|
uint8_t mbsfn_mcs;
|
||||||
|
bool mbsfn_encode;
|
||||||
|
bool is_mcch;
|
||||||
|
} subframe_cfg_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class phch_common
|
class phch_common
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -119,6 +139,12 @@ public:
|
||||||
srslte_mod_t ue_db_get_last_ul_mod(uint16_t rnti, uint32_t tti);
|
srslte_mod_t ue_db_get_last_ul_mod(uint16_t rnti, uint32_t tti);
|
||||||
void ue_db_set_last_ul_tbs(uint16_t rnti, uint32_t tti, int tbs);
|
void ue_db_set_last_ul_tbs(uint16_t rnti, uint32_t tti, int tbs);
|
||||||
int ue_db_get_last_ul_tbs(uint16_t rnti, uint32_t tti);
|
int ue_db_get_last_ul_tbs(uint16_t rnti, uint32_t tti);
|
||||||
|
|
||||||
|
void configure_mbsfn(phy_interface_rrc::phy_cfg_mbsfn_t *cfg);
|
||||||
|
void build_mch_table();
|
||||||
|
void build_mcch_table();
|
||||||
|
void get_sf_config(subframe_cfg_t *cfg, uint32_t phy_tti);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<pthread_mutex_t> tx_mutex;
|
std::vector<pthread_mutex_t> tx_mutex;
|
||||||
|
@ -129,6 +155,17 @@ private:
|
||||||
uint32_t nof_mutex;
|
uint32_t nof_mutex;
|
||||||
uint32_t max_mutex;
|
uint32_t max_mutex;
|
||||||
|
|
||||||
|
phy_interface_rrc::phy_cfg_mbsfn_t mbsfn;
|
||||||
|
bool sib13_configured;
|
||||||
|
bool mcch_configured;
|
||||||
|
uint8_t mch_table[40];
|
||||||
|
uint8_t mcch_table[10];
|
||||||
|
|
||||||
|
uint8_t mch_sf_idx_lut[10];
|
||||||
|
bool is_mch_subframe(subframe_cfg_t *cfg, uint32_t phy_tti);
|
||||||
|
bool is_mcch_subframe(subframe_cfg_t *cfg, uint32_t phy_tti);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace srsenb
|
} // namespace srsenb
|
||||||
|
|
|
@ -76,6 +76,7 @@ private:
|
||||||
void work_imp();
|
void work_imp();
|
||||||
|
|
||||||
int encode_pdsch(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants);
|
int encode_pdsch(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants);
|
||||||
|
int encode_pmch(srslte_enb_dl_pdsch_t *grant, srslte_ra_dl_grant_t *phy_grant);
|
||||||
int decode_pusch(srslte_enb_ul_pusch_t *grants, uint32_t nof_pusch);
|
int decode_pusch(srslte_enb_ul_pusch_t *grants, uint32_t nof_pusch);
|
||||||
int encode_phich(srslte_enb_dl_phich_t *acks, uint32_t nof_acks);
|
int encode_phich(srslte_enb_dl_phich_t *acks, uint32_t nof_acks);
|
||||||
int encode_pdcch_dl(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants);
|
int encode_pdcch_dl(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants);
|
||||||
|
@ -96,7 +97,7 @@ private:
|
||||||
uint32_t t_rx, t_tx_dl, t_tx_ul;
|
uint32_t t_rx, t_tx_dl, t_tx_ul;
|
||||||
srslte_enb_dl_t enb_dl;
|
srslte_enb_dl_t enb_dl;
|
||||||
srslte_enb_ul_t enb_ul;
|
srslte_enb_ul_t enb_ul;
|
||||||
|
srslte_softbuffer_tx_t temp_mbsfn_softbuffer;
|
||||||
srslte_timestamp_t tx_time;
|
srslte_timestamp_t tx_time;
|
||||||
|
|
||||||
// Class to store user information
|
// Class to store user information
|
||||||
|
|
|
@ -62,6 +62,9 @@ public:
|
||||||
/* MAC->PHY interface */
|
/* MAC->PHY interface */
|
||||||
int add_rnti(uint16_t rnti);
|
int add_rnti(uint16_t rnti);
|
||||||
void rem_rnti(uint16_t rnti);
|
void rem_rnti(uint16_t rnti);
|
||||||
|
|
||||||
|
/*RRC-PHY interface*/
|
||||||
|
void configure_mbsfn(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2, LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_13_STRUCT *sib13, LIBLTE_RRC_MCCH_MSG_STRUCT mcch);
|
||||||
|
|
||||||
static uint32_t tti_to_SFN(uint32_t tti);
|
static uint32_t tti_to_SFN(uint32_t tti);
|
||||||
static uint32_t tti_to_subf(uint32_t tti);
|
static uint32_t tti_to_subf(uint32_t tti);
|
||||||
|
@ -73,7 +76,7 @@ public:
|
||||||
void get_metrics(phy_metrics_t metrics[ENB_METRICS_MAX_USERS]);
|
void get_metrics(phy_metrics_t metrics[ENB_METRICS_MAX_USERS]);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
phy_rrc_cfg_t phy_rrc_config;
|
||||||
uint32_t nof_workers;
|
uint32_t nof_workers;
|
||||||
|
|
||||||
const static int MAX_WORKERS = 4;
|
const static int MAX_WORKERS = 4;
|
||||||
|
@ -84,7 +87,7 @@ private:
|
||||||
const static int WORKERS_THREAD_PRIO = 0;
|
const static int WORKERS_THREAD_PRIO = 0;
|
||||||
|
|
||||||
srslte::radio *radio_handler;
|
srslte::radio *radio_handler;
|
||||||
|
srslte::log *log_h;
|
||||||
srslte::thread_pool workers_pool;
|
srslte::thread_pool workers_pool;
|
||||||
std::vector<phch_worker> workers;
|
std::vector<phch_worker> workers;
|
||||||
phch_common workers_common;
|
phch_common workers_common;
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
#include "srslte/common/threads.h"
|
#include "srslte/common/threads.h"
|
||||||
#include "srslte/common/log.h"
|
#include "srslte/common/log.h"
|
||||||
|
#include <sstream>
|
||||||
#include "srsenb/hdr/phy/txrx.h"
|
#include "srsenb/hdr/phy/txrx.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -177,5 +177,144 @@ int phch_common::ue_db_get_last_ul_tbs(uint16_t rnti, uint32_t tti) {
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
void phch_common::configure_mbsfn(phy_interface_rrc::phy_cfg_mbsfn_t *cfg) {
|
||||||
|
|
||||||
|
memcpy(&mbsfn, cfg, sizeof(phy_interface_rrc::phy_cfg_mbsfn_t));
|
||||||
|
|
||||||
|
build_mch_table();
|
||||||
|
build_mcch_table();
|
||||||
|
sib13_configured = true;
|
||||||
|
mcch_configured = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void phch_common::build_mch_table() {
|
||||||
|
// First reset tables
|
||||||
|
bzero(&mch_table[0], sizeof(uint8_t)*40);
|
||||||
|
// 40 element table represents 4 frames (40 subframes)
|
||||||
|
srslte::generate_mch_table(&mch_table[0], mbsfn.mbsfn_subfr_cnfg.subfr_alloc,(LIBLTE_RRC_SUBFRAME_ALLOCATION_NUM_FRAMES_ONE == mbsfn.mbsfn_subfr_cnfg.subfr_alloc_num_frames)?1:4);
|
||||||
|
// Debug
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "|";
|
||||||
|
for(uint32_t j=0; j<40; j++) {
|
||||||
|
ss << (int) mch_table[j] << "|";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void phch_common::build_mcch_table() {
|
||||||
|
bzero(&mcch_table[0], sizeof(uint8_t)*10);
|
||||||
|
|
||||||
|
srslte::generate_mcch_table(&mcch_table[0], mbsfn.mbsfn_area_info.sf_alloc_info_r9);
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "|";
|
||||||
|
for(uint32_t j=0; j<10; j++) {
|
||||||
|
ss << (int) mcch_table[j] << "|";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool phch_common::is_mcch_subframe(subframe_cfg_t *cfg, uint32_t phy_tti)
|
||||||
|
{
|
||||||
|
uint32_t sfn; // System Frame Number
|
||||||
|
uint8_t sf; // Subframe
|
||||||
|
uint8_t offset;
|
||||||
|
uint8_t period;
|
||||||
|
|
||||||
|
sfn = phy_tti/10;
|
||||||
|
sf = phy_tti%10;
|
||||||
|
|
||||||
|
if(sib13_configured) {
|
||||||
|
LIBLTE_RRC_MBSFN_SUBFRAME_CONFIG_STRUCT *subfr_cnfg = &mbsfn.mbsfn_subfr_cnfg;
|
||||||
|
LIBLTE_RRC_MBSFN_AREA_INFO_STRUCT *area_info = &mbsfn.mbsfn_area_info;
|
||||||
|
|
||||||
|
offset = area_info->mcch_offset_r9;
|
||||||
|
period = liblte_rrc_mcch_repetition_period_r9_num[area_info->mcch_repetition_period_r9];
|
||||||
|
|
||||||
|
if((sfn%period == offset) && mcch_table[sf] > 0) {
|
||||||
|
cfg->mbsfn_area_id = area_info->mbsfn_area_id_r9;
|
||||||
|
cfg->non_mbsfn_region_length = liblte_rrc_non_mbsfn_region_length_num[area_info->non_mbsfn_region_length];
|
||||||
|
cfg->mbsfn_mcs = liblte_rrc_mcch_signalling_mcs_r9_num[area_info->signalling_mcs_r9];
|
||||||
|
cfg->mbsfn_encode = true;
|
||||||
|
cfg->is_mcch = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool phch_common::is_mch_subframe(subframe_cfg_t *cfg, uint32_t phy_tti)
|
||||||
|
{
|
||||||
|
uint32_t sfn; // System Frame Number
|
||||||
|
uint8_t sf; // Subframe
|
||||||
|
uint8_t offset;
|
||||||
|
uint8_t period;
|
||||||
|
|
||||||
|
sfn = phy_tti/10;
|
||||||
|
sf = phy_tti%10;
|
||||||
|
|
||||||
|
// Set some defaults
|
||||||
|
cfg->mbsfn_area_id = 0;
|
||||||
|
cfg->non_mbsfn_region_length = 1;
|
||||||
|
cfg->mbsfn_mcs = 2;
|
||||||
|
cfg->mbsfn_encode = false;
|
||||||
|
cfg->is_mcch = false;
|
||||||
|
// Check for MCCH
|
||||||
|
if(is_mcch_subframe(cfg, phy_tti)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not MCCH, check for MCH
|
||||||
|
LIBLTE_RRC_MBSFN_SUBFRAME_CONFIG_STRUCT *subfr_cnfg = &mbsfn.mbsfn_subfr_cnfg;
|
||||||
|
LIBLTE_RRC_MBSFN_AREA_INFO_STRUCT *area_info = &mbsfn.mbsfn_area_info;
|
||||||
|
|
||||||
|
offset = subfr_cnfg->radio_fr_alloc_offset;
|
||||||
|
period = liblte_rrc_radio_frame_allocation_period_num[subfr_cnfg->radio_fr_alloc_period];
|
||||||
|
|
||||||
|
if(LIBLTE_RRC_SUBFRAME_ALLOCATION_NUM_FRAMES_ONE == subfr_cnfg->subfr_alloc_num_frames) {
|
||||||
|
if((sfn%period == offset) && (mch_table[sf] > 0)) {
|
||||||
|
if(sib13_configured) {
|
||||||
|
cfg->mbsfn_area_id = area_info->mbsfn_area_id_r9;
|
||||||
|
cfg->non_mbsfn_region_length = liblte_rrc_non_mbsfn_region_length_num[area_info->non_mbsfn_region_length];
|
||||||
|
if(mcch_configured) {
|
||||||
|
// Iterate through PMCH configs to see which one applies in the current frame
|
||||||
|
LIBLTE_RRC_MCCH_MSG_STRUCT *mcch = &mbsfn.mcch;
|
||||||
|
uint32_t sf_alloc_idx = sfn%liblte_rrc_mbsfn_common_sf_alloc_period_r9_num[mcch->commonsf_allocperiod_r9];
|
||||||
|
for(uint32_t i=0; i<mcch->pmch_infolist_r9_size; i++) {
|
||||||
|
//if(sf_alloc_idx < mch_period_stop) {
|
||||||
|
cfg->mbsfn_mcs = mcch->pmch_infolist_r9[i].pmch_config_r9.datamcs_r9;
|
||||||
|
cfg->mbsfn_encode = true;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}else if(LIBLTE_RRC_SUBFRAME_ALLOCATION_NUM_FRAMES_FOUR == subfr_cnfg->subfr_alloc_num_frames) {
|
||||||
|
uint8_t idx = sfn%period;
|
||||||
|
if((idx >= offset) && (idx < offset+4)) {
|
||||||
|
if(mch_table[(idx*10)+sf] > 0){
|
||||||
|
if(sib13_configured) {
|
||||||
|
cfg->mbsfn_area_id = area_info->mbsfn_area_id_r9;
|
||||||
|
cfg->non_mbsfn_region_length = liblte_rrc_non_mbsfn_region_length_num[area_info->non_mbsfn_region_length];
|
||||||
|
// TODO: check for MCCH configuration, set MCS and decode
|
||||||
|
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void phch_common::get_sf_config(subframe_cfg_t *cfg, uint32_t phy_tti)
|
||||||
|
{
|
||||||
|
if(is_mch_subframe(cfg, phy_tti)) {
|
||||||
|
cfg->sf_type = SUBFRAME_TYPE_MBSFN;
|
||||||
|
}else{
|
||||||
|
cfg->sf_type = SUBFRAME_TYPE_REGULAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -140,7 +140,14 @@ void phch_worker::init(phch_common* phy_, srslte::log *log_h_)
|
||||||
for (int i=0;i<10;i++) {
|
for (int i=0;i<10;i++) {
|
||||||
add_rnti(1+i);
|
add_rnti(1+i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (srslte_softbuffer_tx_init(&temp_mbsfn_softbuffer, phy->cell.nof_prb)) {
|
||||||
|
fprintf(stderr, "Error initiating soft buffer\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
srslte_softbuffer_tx_reset(&temp_mbsfn_softbuffer);
|
||||||
srslte_pucch_set_threshold(&enb_ul.pucch, 0.8);
|
srslte_pucch_set_threshold(&enb_ul.pucch, 0.8);
|
||||||
srslte_sch_set_max_noi(&enb_ul.pusch.ul_sch, phy->params.pusch_max_its);
|
srslte_sch_set_max_noi(&enb_ul.pusch.ul_sch, phy->params.pusch_max_its);
|
||||||
srslte_enb_dl_set_amp(&enb_dl, phy->params.tx_amplitude);
|
srslte_enb_dl_set_amp(&enb_dl, phy->params.tx_amplitude);
|
||||||
|
@ -159,7 +166,7 @@ void phch_worker::stop()
|
||||||
{
|
{
|
||||||
running = false;
|
running = false;
|
||||||
pthread_mutex_lock(&mutex);
|
pthread_mutex_lock(&mutex);
|
||||||
|
srslte_softbuffer_tx_free(&temp_mbsfn_softbuffer);
|
||||||
srslte_enb_dl_free(&enb_dl);
|
srslte_enb_dl_free(&enb_dl);
|
||||||
srslte_enb_ul_free(&enb_ul);
|
srslte_enb_ul_free(&enb_ul);
|
||||||
for (int p = 0; p < SRSLTE_MAX_PORTS; p++) {
|
for (int p = 0; p < SRSLTE_MAX_PORTS; p++) {
|
||||||
|
@ -351,9 +358,11 @@ void phch_worker::work_imp()
|
||||||
if (!running) {
|
if (!running) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
subframe_cfg_t sf_cfg;
|
||||||
|
phy->get_sf_config(&sf_cfg, tti_tx_dl);// TODO difference between tti_tx_dl and t_tx_dl
|
||||||
pthread_mutex_lock(&mutex);
|
pthread_mutex_lock(&mutex);
|
||||||
|
|
||||||
|
|
||||||
mac_interface_phy::ul_sched_t *ul_grants = phy->ul_grants;
|
mac_interface_phy::ul_sched_t *ul_grants = phy->ul_grants;
|
||||||
mac_interface_phy::dl_sched_t *dl_grants = phy->dl_grants;
|
mac_interface_phy::dl_sched_t *dl_grants = phy->dl_grants;
|
||||||
mac_interface_phy *mac = phy->mac;
|
mac_interface_phy *mac = phy->mac;
|
||||||
|
@ -377,9 +386,19 @@ void phch_worker::work_imp()
|
||||||
decode_pucch();
|
decode_pucch();
|
||||||
|
|
||||||
// Get DL scheduling for the TX TTI from MAC
|
// Get DL scheduling for the TX TTI from MAC
|
||||||
if (mac->get_dl_sched(tti_tx_dl, &dl_grants[t_tx_dl]) < 0) {
|
|
||||||
Error("Getting DL scheduling from MAC\n");
|
if(sf_cfg.sf_type == SUBFRAME_TYPE_REGULAR) {
|
||||||
goto unlock;
|
if (mac->get_dl_sched(tti_tx_dl, &dl_grants[t_tx_dl]) < 0) {
|
||||||
|
Error("Getting DL scheduling from MAC\n");
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dl_grants[t_tx_dl].cfi = sf_cfg.non_mbsfn_region_length;
|
||||||
|
srslte_enb_dl_set_non_mbsfn_region(&enb_dl, sf_cfg.non_mbsfn_region_length);
|
||||||
|
if(mac->get_mch_sched(sf_cfg.is_mcch, &dl_grants[t_tx_dl])){
|
||||||
|
Error("Getting MCH packets from MAC\n");
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dl_grants[t_tx_dl].cfi < 1 || dl_grants[t_tx_dl].cfi > 3) {
|
if (dl_grants[t_tx_dl].cfi < 1 || dl_grants[t_tx_dl].cfi > 3) {
|
||||||
|
@ -396,18 +415,30 @@ void phch_worker::work_imp()
|
||||||
// Put base signals (references, PBCH, PCFICH and PSS/SSS) into the resource grid
|
// Put base signals (references, PBCH, PCFICH and PSS/SSS) into the resource grid
|
||||||
srslte_enb_dl_clear_sf(&enb_dl);
|
srslte_enb_dl_clear_sf(&enb_dl);
|
||||||
srslte_enb_dl_set_cfi(&enb_dl, dl_grants[t_tx_dl].cfi);
|
srslte_enb_dl_set_cfi(&enb_dl, dl_grants[t_tx_dl].cfi);
|
||||||
srslte_enb_dl_put_base(&enb_dl, tti_tx_dl);
|
|
||||||
|
if(sf_cfg.sf_type == SUBFRAME_TYPE_REGULAR) {
|
||||||
// Put UL/DL grants to resource grid. PDSCH data will be encoded as well.
|
srslte_enb_dl_put_base(&enb_dl, tti_tx_dl);
|
||||||
encode_pdcch_dl(dl_grants[t_tx_dl].sched_grants, dl_grants[t_tx_dl].nof_grants);
|
} else if (sf_cfg.mbsfn_encode){
|
||||||
|
srslte_enb_dl_put_mbsfn_base(&enb_dl, tti_tx_dl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sf_cfg.sf_type == SUBFRAME_TYPE_REGULAR) {
|
||||||
|
// Put UL/DL grants to resource grid. PDSCH data will be encoded as well.
|
||||||
|
encode_pdcch_dl(dl_grants[t_tx_dl].sched_grants, dl_grants[t_tx_dl].nof_grants);
|
||||||
|
encode_pdsch(dl_grants[t_tx_dl].sched_grants, dl_grants[t_tx_dl].nof_grants);
|
||||||
|
}else {
|
||||||
|
srslte_ra_dl_grant_t phy_grant;
|
||||||
|
phy_grant.mcs[0].idx = sf_cfg.mbsfn_mcs;
|
||||||
|
encode_pmch(&dl_grants[t_tx_dl].sched_grants[0], &phy_grant);
|
||||||
|
}
|
||||||
|
|
||||||
encode_pdcch_ul(ul_grants[t_tx_ul].sched_grants, ul_grants[t_tx_ul].nof_grants);
|
encode_pdcch_ul(ul_grants[t_tx_ul].sched_grants, ul_grants[t_tx_ul].nof_grants);
|
||||||
encode_pdsch(dl_grants[t_tx_dl].sched_grants, dl_grants[t_tx_dl].nof_grants);
|
|
||||||
|
|
||||||
// Put pending PHICH HARQ ACK/NACK indications into subframe
|
// Put pending PHICH HARQ ACK/NACK indications into subframe
|
||||||
encode_phich(ul_grants[t_tx_ul].phich, ul_grants[t_tx_ul].nof_phich);
|
encode_phich(ul_grants[t_tx_ul].phich, ul_grants[t_tx_ul].nof_phich);
|
||||||
|
|
||||||
// Prepare for receive ACK for DL grants in t_tx_dl+4
|
// Prepare for receive ACK for DL grants in t_tx_dl+4
|
||||||
phy->ue_db_clear(TTIMOD(TTI_TX(t_tx_dl)));
|
phy->ue_db_clear(TTIMOD(TTI_TX(t_tx_dl)));
|
||||||
|
|
||||||
for (uint32_t i=0;i<dl_grants[t_tx_dl].nof_grants;i++) {
|
for (uint32_t i=0;i<dl_grants[t_tx_dl].nof_grants;i++) {
|
||||||
// SI-RNTI and RAR-RNTI do not have ACK
|
// SI-RNTI and RAR-RNTI do not have ACK
|
||||||
uint16_t rnti = dl_grants[t_tx_dl].sched_grants[i].rnti;
|
uint16_t rnti = dl_grants[t_tx_dl].sched_grants[i].rnti;
|
||||||
|
@ -424,10 +455,14 @@ void phch_worker::work_imp()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate signal and transmit
|
// Generate signal and transmit
|
||||||
srslte_enb_dl_gen_signal(&enb_dl);
|
if(sf_cfg.sf_type == SUBFRAME_TYPE_REGULAR) {
|
||||||
Debug("Sending to radio\n");
|
srslte_enb_dl_gen_signal(&enb_dl);
|
||||||
|
} else {
|
||||||
|
srslte_enb_dl_gen_signal_mbsfn(&enb_dl);
|
||||||
|
}
|
||||||
|
Debug("Sending to radio\n");
|
||||||
phy->worker_end(tx_mutex_cnt, signal_buffer_tx, SRSLTE_SF_LEN_PRB(phy->cell.nof_prb), tx_time);
|
phy->worker_end(tx_mutex_cnt, signal_buffer_tx, SRSLTE_SF_LEN_PRB(phy->cell.nof_prb), tx_time);
|
||||||
|
|
||||||
#ifdef DEBUG_WRITE_FILE
|
#ifdef DEBUG_WRITE_FILE
|
||||||
|
@ -837,6 +872,25 @@ int phch_worker::encode_pdcch_dl(srslte_enb_dl_pdsch_t *grants, uint32_t nof_gra
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int phch_worker::encode_pmch(srslte_enb_dl_pdsch_t *grant, srslte_ra_dl_grant_t *phy_grant)
|
||||||
|
{
|
||||||
|
|
||||||
|
phy_grant->tb_en[0] = true;
|
||||||
|
phy_grant->tb_en[1] = false;
|
||||||
|
phy_grant->nof_prb = enb_dl.cell.nof_prb;
|
||||||
|
phy_grant->sf_type = SRSLTE_SF_MBSFN;
|
||||||
|
srslte_dl_fill_ra_mcs(&phy_grant->mcs[0], enb_dl.cell.nof_prb);
|
||||||
|
phy_grant->Qm[0] = srslte_mod_bits_x_symbol(phy_grant->mcs[0].mod);
|
||||||
|
for(int i = 0; i < 2; i++){
|
||||||
|
for(uint32_t j = 0; j < phy_grant->nof_prb; j++){
|
||||||
|
phy_grant->prb_idx[i][j] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
srslte_enb_dl_put_pmch(&enb_dl, phy_grant, &temp_mbsfn_softbuffer, sf_tx, &grant->data[0][0]);
|
||||||
|
return SRSLTE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int phch_worker::encode_pdsch(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants) {
|
int phch_worker::encode_pdsch(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants) {
|
||||||
|
|
||||||
/* Scales the Resources Elements affected by the power allocation (p_b) */
|
/* Scales the Resources Elements affected by the power allocation (p_b) */
|
||||||
|
|
|
@ -95,7 +95,9 @@ bool phy::init(phy_args_t *args,
|
||||||
mac_interface_phy *mac,
|
mac_interface_phy *mac,
|
||||||
srslte::log_filter* log_h)
|
srslte::log_filter* log_h)
|
||||||
{
|
{
|
||||||
|
|
||||||
std::vector<srslte::log_filter*> log_vec;
|
std::vector<srslte::log_filter*> log_vec;
|
||||||
|
this->log_h = log_h;
|
||||||
for (int i=0;i<args->nof_phy_threads;i++) {
|
for (int i=0;i<args->nof_phy_threads;i++) {
|
||||||
log_vec.push_back(log_h);
|
log_vec.push_back(log_h);
|
||||||
}
|
}
|
||||||
|
@ -114,7 +116,7 @@ bool phy::init(phy_args_t *args,
|
||||||
|
|
||||||
radio_handler = radio_handler_;
|
radio_handler = radio_handler_;
|
||||||
nof_workers = args->nof_phy_threads;
|
nof_workers = args->nof_phy_threads;
|
||||||
|
this->log_h = (srslte::log*)log_vec[0];
|
||||||
workers_common.params = *args;
|
workers_common.params = *args;
|
||||||
|
|
||||||
workers_common.init(&cfg->cell, radio_handler, mac);
|
workers_common.init(&cfg->cell, radio_handler, mac);
|
||||||
|
@ -227,6 +229,28 @@ void phy::set_config_dedicated(uint16_t rnti, LIBLTE_RRC_PHYSICAL_CONFIG_DEDICAT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void phy::configure_mbsfn(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2, LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_13_STRUCT *sib13, LIBLTE_RRC_MCCH_MSG_STRUCT mcch)
|
||||||
|
{
|
||||||
|
if(sib2->mbsfn_subfr_cnfg_list_size > 1) {
|
||||||
|
Warning("SIB2 has %d MBSFN subframe configs - only 1 supported\n", sib2->mbsfn_subfr_cnfg_list_size);
|
||||||
|
}
|
||||||
|
if(sib2->mbsfn_subfr_cnfg_list_size > 0) {
|
||||||
|
memcpy(&phy_rrc_config.mbsfn.mbsfn_subfr_cnfg, &sib2->mbsfn_subfr_cnfg_list[0], sizeof(LIBLTE_RRC_MBSFN_SUBFRAME_CONFIG_STRUCT));
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&phy_rrc_config.mbsfn.mbsfn_notification_cnfg, &sib13->mbsfn_notification_config, sizeof(LIBLTE_RRC_MBSFN_NOTIFICATION_CONFIG_STRUCT));
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
if(sib13->mbsfn_area_info_list_r9_size > 0) {
|
||||||
|
memcpy(&phy_rrc_config.mbsfn.mbsfn_area_info, &sib13->mbsfn_area_info_list_r9[0], sizeof(LIBLTE_RRC_MBSFN_AREA_INFO_STRUCT));
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&phy_rrc_config.mbsfn.mcch, &mcch, sizeof(LIBLTE_RRC_MCCH_MSG_STRUCT));
|
||||||
|
|
||||||
|
workers_common.configure_mbsfn(&phy_rrc_config.mbsfn);
|
||||||
|
}
|
||||||
|
|
||||||
// Start GUI
|
// Start GUI
|
||||||
void phy::start_plot() {
|
void phy::start_plot() {
|
||||||
((phch_worker) workers[0]).start_plot();
|
((phch_worker) workers[0]).start_plot();
|
||||||
|
|
Loading…
Reference in New Issue