|
|
|
@ -57,7 +57,7 @@ bool phch_common::init(srslte_cell_t *cell_, srslte::radio* radio_h_, mac_interf
|
|
|
|
|
mac = mac_;
|
|
|
|
|
memcpy(&cell, cell_, sizeof(srslte_cell_t));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_init(&user_mutex, NULL);
|
|
|
|
|
|
|
|
|
|
is_first_of_burst = true;
|
|
|
|
|
is_first_tx = true;
|
|
|
|
@ -107,80 +107,110 @@ void phch_common::ue_db_clear(uint32_t sf_idx)
|
|
|
|
|
|
|
|
|
|
void phch_common::ue_db_add_rnti(uint16_t rnti)
|
|
|
|
|
{
|
|
|
|
|
pthread_mutex_lock(&user_mutex);
|
|
|
|
|
for (int sf_idx=0;sf_idx<TTIMOD_SZ;sf_idx++) {
|
|
|
|
|
for (uint32_t tb_idx = 0; tb_idx < SRSLTE_MAX_TB; tb_idx++) {
|
|
|
|
|
common_ue_db[rnti].pending_ack.is_pending[sf_idx][tb_idx] = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
pthread_mutex_unlock(&user_mutex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void phch_common::ue_db_rem_rnti(uint16_t rnti)
|
|
|
|
|
{
|
|
|
|
|
pthread_mutex_lock(&user_mutex);
|
|
|
|
|
common_ue_db.erase(rnti);
|
|
|
|
|
pthread_mutex_unlock(&user_mutex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void phch_common::ue_db_set_ack_pending(uint32_t sf_idx, uint16_t rnti, uint32_t tb_idx, uint32_t last_n_pdcch)
|
|
|
|
|
{
|
|
|
|
|
pthread_mutex_lock(&user_mutex);
|
|
|
|
|
if (common_ue_db.count(rnti)) {
|
|
|
|
|
common_ue_db[rnti].pending_ack.is_pending[sf_idx][tb_idx] = true;
|
|
|
|
|
common_ue_db[rnti].pending_ack.n_pdcch[sf_idx] = (uint16_t) last_n_pdcch;
|
|
|
|
|
}
|
|
|
|
|
pthread_mutex_unlock(&user_mutex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool phch_common::ue_db_is_ack_pending(uint32_t sf_idx, uint16_t rnti, uint32_t tb_idx, uint32_t *last_n_pdcch) {
|
|
|
|
|
bool phch_common::ue_db_is_ack_pending(uint32_t sf_idx, uint16_t rnti, uint32_t tb_idx, uint32_t *last_n_pdcch)
|
|
|
|
|
{
|
|
|
|
|
bool ret = false;
|
|
|
|
|
pthread_mutex_lock(&user_mutex);
|
|
|
|
|
if (common_ue_db.count(rnti)) {
|
|
|
|
|
bool ret = common_ue_db[rnti].pending_ack.is_pending[sf_idx][tb_idx];
|
|
|
|
|
ret = common_ue_db[rnti].pending_ack.is_pending[sf_idx][tb_idx];
|
|
|
|
|
common_ue_db[rnti].pending_ack.is_pending[sf_idx][tb_idx] = false;
|
|
|
|
|
|
|
|
|
|
if (ret && last_n_pdcch) {
|
|
|
|
|
*last_n_pdcch = common_ue_db[rnti].pending_ack.n_pdcch[sf_idx];
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
pthread_mutex_unlock(&user_mutex);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void phch_common::ue_db_set_ri(uint16_t rnti, uint8_t ri) {
|
|
|
|
|
pthread_mutex_lock(&user_mutex);
|
|
|
|
|
if (common_ue_db.count(rnti)) {
|
|
|
|
|
common_ue_db[rnti].ri = ri;
|
|
|
|
|
}
|
|
|
|
|
pthread_mutex_unlock(&user_mutex);
|
|
|
|
|
}
|
|
|
|
|
uint8_t phch_common::ue_db_get_ri(uint16_t rnti) {
|
|
|
|
|
|
|
|
|
|
uint8_t phch_common::ue_db_get_ri(uint16_t rnti)
|
|
|
|
|
{
|
|
|
|
|
pthread_mutex_lock(&user_mutex);
|
|
|
|
|
uint8_t ret = 0;
|
|
|
|
|
if (common_ue_db.count(rnti)) {
|
|
|
|
|
ret = common_ue_db[rnti].ri;
|
|
|
|
|
}
|
|
|
|
|
pthread_mutex_unlock(&user_mutex);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
void phch_common::ue_db_set_last_ul_mod(uint16_t rnti, uint32_t tti, srslte_mod_t mcs) {
|
|
|
|
|
|
|
|
|
|
void phch_common::ue_db_set_last_ul_mod(uint16_t rnti, uint32_t tti, srslte_mod_t mcs)
|
|
|
|
|
{
|
|
|
|
|
pthread_mutex_lock(&user_mutex);
|
|
|
|
|
if (!common_ue_db.count(rnti)) {
|
|
|
|
|
ue_db_add_rnti(rnti);
|
|
|
|
|
}
|
|
|
|
|
common_ue_db[rnti].last_ul_mod[TTI_RX(tti)%(2*HARQ_DELAY_MS)] = mcs;
|
|
|
|
|
pthread_mutex_unlock(&user_mutex);
|
|
|
|
|
}
|
|
|
|
|
srslte_mod_t phch_common::ue_db_get_last_ul_mod(uint16_t rnti, uint32_t tti) {
|
|
|
|
|
|
|
|
|
|
srslte_mod_t phch_common::ue_db_get_last_ul_mod(uint16_t rnti, uint32_t tti)
|
|
|
|
|
{
|
|
|
|
|
pthread_mutex_lock(&user_mutex);
|
|
|
|
|
srslte_mod_t ret = SRSLTE_MOD_BPSK;
|
|
|
|
|
if (common_ue_db.count(rnti)) {
|
|
|
|
|
ret = common_ue_db[rnti].last_ul_mod[TTI_RX(tti)%(2*HARQ_DELAY_MS)];
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
pthread_mutex_unlock(&user_mutex);
|
|
|
|
|
}
|
|
|
|
|
void phch_common::ue_db_set_last_ul_tbs(uint16_t rnti, uint32_t tti, int tbs) {
|
|
|
|
|
|
|
|
|
|
void phch_common::ue_db_set_last_ul_tbs(uint16_t rnti, uint32_t tti, int tbs)
|
|
|
|
|
{
|
|
|
|
|
pthread_mutex_lock(&user_mutex);
|
|
|
|
|
if (!common_ue_db.count(rnti)) {
|
|
|
|
|
ue_db_add_rnti(rnti);
|
|
|
|
|
}
|
|
|
|
|
common_ue_db[rnti].last_ul_tbs[TTI_RX(tti)%(2*HARQ_DELAY_MS)] = tbs;
|
|
|
|
|
pthread_mutex_unlock(&user_mutex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int phch_common::ue_db_get_last_ul_tbs(uint16_t rnti, uint32_t tti) {
|
|
|
|
|
int ret = -1;
|
|
|
|
|
pthread_mutex_lock(&user_mutex);
|
|
|
|
|
if (common_ue_db.count(rnti)) {
|
|
|
|
|
ret = common_ue_db[rnti].last_ul_tbs[TTI_RX(tti)%(2*HARQ_DELAY_MS)];
|
|
|
|
|
}
|
|
|
|
|
pthread_mutex_unlock(&user_mutex);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
void phch_common::configure_mbsfn(phy_interface_rrc::phy_cfg_mbsfn_t *cfg) {
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
@ -189,8 +219,8 @@ void phch_common::configure_mbsfn(phy_interface_rrc::phy_cfg_mbsfn_t *cfg) {
|
|
|
|
|
mcch_configured = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void phch_common::build_mch_table() {
|
|
|
|
|
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)
|
|
|
|
@ -203,7 +233,8 @@ void phch_common::build_mch_table() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void phch_common::build_mcch_table() {
|
|
|
|
|
void phch_common::build_mcch_table()
|
|
|
|
|
{
|
|
|
|
|
bzero(&mcch_table[0], sizeof(uint8_t)*10);
|
|
|
|
|
|
|
|
|
|
generate_mcch_table(&mcch_table[0], mbsfn.mbsfn_area_info.sf_alloc_info_r9);
|
|
|
|
@ -215,8 +246,6 @@ void phch_common::build_mcch_table() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool phch_common::is_mcch_subframe(subframe_cfg_t *cfg, uint32_t phy_tti)
|
|
|
|
|
{
|
|
|
|
|
uint32_t sfn; // System Frame Number
|
|
|
|
@ -245,6 +274,7 @@ bool phch_common::is_mcch_subframe(subframe_cfg_t *cfg, uint32_t phy_tti)
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool phch_common::is_mch_subframe(subframe_cfg_t *cfg, uint32_t phy_tti)
|
|
|
|
|
{
|
|
|
|
|
uint32_t sfn; // System Frame Number
|
|
|
|
@ -262,7 +292,7 @@ bool phch_common::is_mch_subframe(subframe_cfg_t *cfg, uint32_t phy_tti)
|
|
|
|
|
cfg->mbsfn_encode = false;
|
|
|
|
|
cfg->is_mcch = false;
|
|
|
|
|
// Check for MCCH
|
|
|
|
|
if(is_mcch_subframe(cfg, phy_tti)) {
|
|
|
|
|
if (is_mcch_subframe(cfg, phy_tti)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -273,16 +303,16 @@ bool phch_common::is_mch_subframe(subframe_cfg_t *cfg, uint32_t phy_tti)
|
|
|
|
|
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) {
|
|
|
|
|
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) {
|
|
|
|
|
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++) {
|
|
|
|
|
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;
|
|
|
|
@ -293,11 +323,11 @@ bool phch_common::is_mch_subframe(subframe_cfg_t *cfg, uint32_t phy_tti)
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}else if(LIBLTE_RRC_SUBFRAME_ALLOCATION_NUM_FRAMES_FOUR == subfr_cnfg->subfr_alloc_num_frames) {
|
|
|
|
|
} 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) {
|
|
|
|
|
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
|
|
|
|
|