diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index cbae84f56b6c1643884468f09fbc52db0df62694..bec08732769d0758332f4231fd3b7b4a2f9da721 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -450,11 +450,11 @@ void phy_config_sib2_eNB(uint8_t Mod_id, } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration fp->MBSFN_config[i].fourFrames_flag = 1; fp->MBSFN_config[i].mbsfn_SubframeConfig = - mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]| + mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]| (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)| - (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]<<16); + (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]<<16); - LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, + LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", i, fp->MBSFN_config[i].mbsfn_SubframeConfig); } } diff --git a/openair1/PHY/INIT/lte_init_ue.c b/openair1/PHY/INIT/lte_init_ue.c index 62d768a50aeee992662826aff4928d8c5d1e5e08..1ed9e20d602ecc39f4f573f37b83142a5fa60d2d 100644 --- a/openair1/PHY/INIT/lte_init_ue.c +++ b/openair1/PHY/INIT/lte_init_ue.c @@ -165,11 +165,11 @@ void phy_config_sib2_ue(module_id_t Mod_id,int CC_id, } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration fp->MBSFN_config[i].fourFrames_flag = 1; fp->MBSFN_config[i].mbsfn_SubframeConfig = - mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]| + mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]| (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)| - (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]<<16); + (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]<<16); - LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, + LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", i, fp->MBSFN_config[i].mbsfn_SubframeConfig); } } diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c index e268a5b061c0e06031681909be23cfbb4acc87cd..516cb32999b505aa08f1e36c2c23a1d08c747288 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c @@ -61,8 +61,8 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms, temp = 0; for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) { - Re = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[(i<<2)]; - Im = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[1+(i<<2)]; + Re = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[(i<<1)]; + Im = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[1+(i<<1)]; temp += (Re*Re/2) + (Im*Im/2); } @@ -81,7 +81,7 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms, // do not filter to have proactive timing adjustment max_pos_fil = max_pos; - if(subframe == 6) + if(subframe == 5) { diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3); diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c index 732db1fa4e533998a83ede51735111520df19042..c912c8893482c1c00c47b73128a0e7de5b73a052 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c @@ -62,8 +62,8 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms, temp = 0; for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) { - Re = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[(i<<2)]; - Im = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[1+(i<<2)]; + Re = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[(i<<1)]; + Im = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[1+(i<<1)]; temp += (Re*Re/2) + (Im*Im/2); } @@ -82,7 +82,7 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms, // do not filter to have proactive timing adjustment max_pos_fil = max_pos; - if(subframe == 6) + if(subframe == 5) { diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3); diff --git a/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c b/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c index 14def309b7bdb11043ef66712b0828d5546898d6..69dbb705db8fd4cd85f215f50a63949f5fb88ed1 100644 --- a/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c +++ b/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c @@ -54,9 +54,9 @@ void lte_gold_mbsfn(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_mbsfn_tabl for (l=0; l<3; l++) { if (l==0) - x2 = (Nid_mbsfn) + (((1+(Nid_mbsfn<<1))*(1 + 2 + (7*(1+(sfn>>1)))))<<9); //cinit + x2 = (Nid_mbsfn) + (((1+(Nid_mbsfn<<1))*(1 + 2 + (7*(1+(sfn<<1)))))<<9); //cinit else - x2 = (Nid_mbsfn) + (((1+(Nid_mbsfn<<1))*(1 + ((l-1)<<2) + (7*(2+(sfn>>1)))))<<9); //cinit + x2 = (Nid_mbsfn) + (((1+(Nid_mbsfn<<1))*(1 + ((l-1)<<2) + (7*(2+(sfn<<1)))))<<9); //cinit //x2 = frame_parms->Ncp + (Nid_cell<<1) + (1+(Nid_cell<<1))*(1 + (3*l) + (7*(1+ns))); //cinit //n = 0 diff --git a/openair1/PHY/LTE_TRANSPORT/pmch_common.c b/openair1/PHY/LTE_TRANSPORT/pmch_common.c index 1d12c79621ea403c93c1eaa6389da0fa5065aa8c..a4821a420ff27f87731c6b737d515598e5758343 100644 --- a/openair1/PHY/LTE_TRANSPORT/pmch_common.c +++ b/openair1/PHY/LTE_TRANSPORT/pmch_common.c @@ -27,6 +27,7 @@ int is_pmch_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_par uint32_t period; uint8_t i; + uint8_t j; // LOG_D(PHY,"is_pmch_subframe: frame %d, subframe %d, num_MBSFN_config %d\n", // frame,subframe,frame_parms->num_MBSFN_config); @@ -34,8 +35,8 @@ int is_pmch_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_par for (i=0; i<frame_parms->num_MBSFN_config; i++) { // we have at least one MBSFN configuration period = 1<<frame_parms->MBSFN_config[i].radioframeAllocationPeriod; - if ((frame % period) == frame_parms->MBSFN_config[i].radioframeAllocationOffset) { - if (frame_parms->MBSFN_config[i].fourFrames_flag == 0) { + if (frame_parms->MBSFN_config[i].fourFrames_flag == 0) { + if ((frame % period) == frame_parms->MBSFN_config[i].radioframeAllocationOffset) { if (frame_parms->frame_type == FDD) { switch (subframe) { @@ -108,9 +109,96 @@ int is_pmch_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_par break; } } + } + + } else { // handle 4 frames case + + for(j=0;j<4;j++) { + if ((frame % period) == (frame_parms->MBSFN_config[i].radioframeAllocationOffset + j)) { + if (frame_parms->frame_type == FDD) { + switch (subframe) { + case 1: + if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig) & (0x800000>>(j*6))) > 0) { + //LOG_E(PHY,"SubframeConfig<<6(%x),MBSFN_FDD_SF1(%x)\n",frame_parms->MBSFN_config[i].mbsfn_SubframeConfig,0x800000>>(j*6)); + return(1); + } + + break; + + case 2: + if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig) & (0x400000>>(j*6))) > 0) { + //LOG_E(PHY,"SubframeConfig<<6(%x),MBSFN_FDD_SF1(%x)\n",frame_parms->MBSFN_config[i].mbsfn_SubframeConfig,0x400000>>(j*6)); + return(1); + } + + break; + + case 3: + if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig) & (0x200000>>(j*6))) > 0) { + //LOG_E(PHY,"SubframeConfig<<6(%x),MBSFN_FDD_SF1(%x)\n",frame_parms->MBSFN_config[i].mbsfn_SubframeConfig,0x200000>>(j*6)); + return(1); + } + + break; + + case 6: + if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig) & (0x100000>>(j*6))) > 0) { + //LOG_E(PHY,"SubframeConfig<<6(%x),MBSFN_FDD_SF1(%x)\n",frame_parms->MBSFN_config[i].mbsfn_SubframeConfig,0x100000>>(j*6)); + return(1); + } + + break; + + case 7: + if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig) & (0x80000>>(j*6))) > 0) { + //LOG_E(PHY,"SubframeConfig<<6(%x),MBSFN_FDD_SF1(%x)\n",frame_parms->MBSFN_config[i].mbsfn_SubframeConfig,0x80000>>(j*6)); + return(1); + } + + break; - } else { // handle 4 frames case + case 8: + if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig) & (0x40000>>(j*6))) > 0) { + //LOG_E(PHY,"SubframeConfig<<6(%x),MBSFN_FDD_SF1(%x)\n",frame_parms->MBSFN_config[i].mbsfn_SubframeConfig,0x40000>>(j*6)); + return(1); + } + break; + } + } else { + switch (subframe) { + case 3: + if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig>>j*6) & MBSFN_TDD_SF3) > 0) + return(1); + + break; + + case 4: + if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig>>j*6) & MBSFN_TDD_SF4) > 0) + return(1); + + break; + + case 7: + if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig>>j*6) & MBSFN_TDD_SF7) > 0) + return(1); + + break; + + case 8: + if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig>>j*6) & MBSFN_TDD_SF8) > 0) + return(1); + + break; + + case 9: + if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig>>j*6) & MBSFN_TDD_SF9) > 0) + return(1); + + break; + } + } + } } } } diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c index b9fbcad9c9349cbec14cd23f4c75e4ddbab6b6e4..e0ea796a826fb6b05357f5624942a954706cb389 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c @@ -179,29 +179,29 @@ void extract_dci1C_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_ uint32_t rballoc=0; uint8_t mcs=0; + uint8_t Ngap=0; switch (N_RB_DL) { case 6: - mcs = ((DCI1C_5MHz_t *)dci_pdu)->mcs; - rballoc = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc,6); - + mcs = ((DCI1C_1_5MHz_t *)dci_pdu)->mcs; + rballoc = conv_1C_RIV(((DCI1C_1_5MHz_t *)dci_pdu)->rballoc, 6); break; case 25: - mcs = ((DCI1C_5MHz_t *)dci_pdu)->mcs; - rballoc = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc,6); - + mcs = ((DCI1C_5MHz_t *)dci_pdu)->mcs; + rballoc = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc, 25); break; case 50: - mcs = ((DCI1C_10MHz_t *)dci_pdu)->mcs; - rballoc = conv_1C_RIV(((DCI1C_10MHz_t *)dci_pdu)->rballoc,6); - + mcs = ((DCI1C_10MHz_t *)dci_pdu)->mcs; + rballoc = conv_1C_RIV(((DCI1C_10MHz_t *)dci_pdu)->rballoc, 50); + Ngap = ((DCI1C_10MHz_t *)dci_pdu)->Ngap; break; case 100: - mcs = ((DCI1C_20MHz_t *)dci_pdu)->mcs; - rballoc = conv_1C_RIV(((DCI1C_20MHz_t *)dci_pdu)->rballoc,6); + mcs = ((DCI1C_20MHz_t *)dci_pdu)->mcs; + rballoc = conv_1C_RIV(((DCI1C_20MHz_t *)dci_pdu)->rballoc, 100); + Ngap = ((DCI1C_20MHz_t *)dci_pdu)->Ngap; break; default: @@ -211,6 +211,7 @@ void extract_dci1C_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_ pdci_info_extarcted->mcs1 = mcs; pdci_info_extarcted->rballoc = rballoc; + pdci_info_extarcted->Ngap = Ngap; } void extract_dci1_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index ed258ed47c6f0ab6875d15582d5b8879c4b29395..02f3e5aaace3931d380d3fb70551520050bb838b 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -2516,7 +2516,7 @@ void ue_measurement_procedures( T_INT((int)ue->common_vars.freq_offset)); } - if (l==(6-ue->frame_parms.Ncp)) { + if (( (slot%2) == 0) && (l==(6-ue->frame_parms.Ncp))) { // make sure we have signal from PSS/SSS for N0 measurement // LOG_I(PHY," l==(6-ue->frame_parms.Ncp) ue_rrc_measurements\n"); @@ -2982,18 +2982,18 @@ LOG_DEBUG_END else if ((ue->prach_resources[eNB_id]) && (dci_alloc_rx[i].rnti == ue->prach_resources[eNB_id]->ra_RNTI) && - (dci_alloc_rx[i].format == format1A)) { + ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) { LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) - LOG_D(PHY,"[UE %d][RAPROC] subframe %d: Found RA rnti %x, format 1A, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,i); + LOG_D(PHY,"[UE %d][RAPROC] subframe %d: Found RA rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i); LOG_DEBUG_END if (generate_ue_dlsch_params_from_dci(frame_rx, subframe_rx, - (DCI1A_5MHz_TDD_1_6_t *)&dci_alloc_rx[i].dci_pdu, + (void *)&dci_alloc_rx[i].dci_pdu, ue->prach_resources[eNB_id]->ra_RNTI, - format1A, + dci_alloc_rx[i].format, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id], ue->pdsch_vars_ra[eNB_id], &ue->dlsch_ra[eNB_id], @@ -3128,7 +3128,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs // LOG_D(PHY,"ue calling pmch subframe ..\n "); LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Querying for PMCH demodulation\n", - ue->Mod_id,(subframe_rx==9?-1:0)+frame_rx,subframe_rx); + ue->Mod_id,frame_rx,subframe_rx); #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) pmch_mcs = ue_query_mch(ue->Mod_id, @@ -3147,9 +3147,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Programming PMCH demodulation for mcs %d\n",ue->Mod_id,frame_rx,subframe_rx,pmch_mcs); fill_UE_dlsch_MCH(ue,pmch_mcs,1,0,0); - for (l=2; l<12; l++) { - slot_fep_mbsfn(ue, l, subframe_rx, @@ -3164,6 +3162,8 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs } + ue->dlsch_MCH[0]->harq_processes[0]->Qm = get_Qm(pmch_mcs); + ue->dlsch_MCH[0]->harq_processes[0]->G = get_G(&ue->frame_parms, ue->dlsch_MCH[0]->harq_processes[0]->nb_rb, ue->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even, @@ -3177,7 +3177,14 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs dlsch_unscrambling(&ue->frame_parms,1,ue->dlsch_MCH[0], ue->dlsch_MCH[0]->harq_processes[0]->G, ue->pdsch_vars_MCH[0]->llr[0],0,subframe_rx<<1); - + + LOG_D(PHY,"start turbo decode for MCH %d.%d --> nb_rb %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->nb_rb); + LOG_D(PHY,"start turbo decode for MCH %d.%d --> rb_alloc_even %x \n", frame_rx, subframe_rx, (unsigned int)((intptr_t)ue->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even)); + LOG_D(PHY,"start turbo decode for MCH %d.%d --> Qm %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->Qm); + LOG_D(PHY,"start turbo decode for MCH %d.%d --> Nl %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->Nl); + LOG_D(PHY,"start turbo decode for MCH %d.%d --> G %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->G); + LOG_D(PHY,"start turbo decode for MCH %d.%d --> Kmimo %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->Kmimo); + ret = dlsch_decoding(ue, ue->pdsch_vars_MCH[0]->llr[0], &ue->frame_parms, @@ -3206,7 +3213,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3, ue->dlsch_MCH[0]->max_turbo_iterations, ue->dlsch_MCH[0]->harq_processes[0]->G); - dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx); + // dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx); LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) for (int i=0; i<ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3; i++) { @@ -3222,25 +3229,24 @@ LOG_DEBUG_END } else { // decoding successful #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - if (mcch_active == 1) { - ue_send_mch_sdu(ue->Mod_id, - CC_id, - frame_rx, - ue->dlsch_MCH[0]->harq_processes[0]->b, - ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3, - eNB_id,// not relevant in eMBMS context - sync_area); + ue_send_mch_sdu(ue->Mod_id, + CC_id, + frame_rx, + ue->dlsch_MCH[0]->harq_processes[0]->b, + ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3, + eNB_id,// not relevant in eMBMS context + sync_area); + + if (mcch_active == 1) ue->dlsch_mcch_received[sync_area][0]++; - - - if (ue->dlsch_mch_received_sf[subframe_rx%5][0] == 1 ) { - ue->dlsch_mch_received_sf[subframe_rx%5][0]=0; - } else { - ue->dlsch_mch_received[0]+=1; - ue->dlsch_mch_received_sf[subframe_rx][0]=1; - } - - + else + ue->dlsch_mtch_received[sync_area][0]++; + + if (ue->dlsch_mch_received_sf[subframe_rx%5][0] == 1 ) { + ue->dlsch_mch_received_sf[subframe_rx%5][0]=0; + } else { + ue->dlsch_mch_received[0]+=1; + ue->dlsch_mch_received_sf[subframe_rx][0]=1; } #endif // #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) @@ -4179,7 +4185,7 @@ LOG_DEBUG_END if (subframe_select(&ue->frame_parms,subframe_rx) == SF_S) { // S-subframe, do first 5 symbols only - l2 = 5; + l2 = 4; } else if (pmch_flag == 1) { // do first 2 symbols only l2 = 1; } else { // normal subframe, last symbol to be processed is the first of the second slot @@ -4665,7 +4671,7 @@ LOG_DEBUG_END if (subframe_select(&ue->frame_parms,subframe_rx) == SF_S) { // S-subframe, do first 5 symbols only - l2 = 5; + l2 = 4; } else if (pmch_flag == 1) { // do first 2 symbols only l2 = 1; } else { // normal subframe, last symbol to be processed is the first of the second slot @@ -4709,7 +4715,7 @@ LOG_DEBUG_END if (do_pdcch_flag) { if ((l==pilot1) || - ((pmch_flag==1)&(l==l2))) { + ((pmch_flag==1)&&(l==l2))) { LOG_D(PHY,"[UE %d] Frame %d: Calling pdcch procedures (eNB %d)\n",ue->Mod_id,frame_rx,eNB_id); //start_meas(&ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]]); @@ -4729,9 +4735,22 @@ LOG_DEBUG_END ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode); LOG_D(PHY," ------ end FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - // If this is PMCH, call procedures and return + + // If this is PMCH, call procedures, do channel estimation for first symbol of next DL subframe and return if (pmch_flag == 1) { ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag); + + int next_subframe_rx = (1+subframe_rx)%10; + if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL) + { + slot_fep(ue, + 0, + (next_subframe_rx<<1), + 0, + 0, + 0); + } + return 0; } @@ -4841,6 +4860,7 @@ LOG_DEBUG_END ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode); } // for l=1..l2 + ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode); // do first symbol of next downlink subframe for channel estimation int next_subframe_rx = (1+subframe_rx)%10; diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index d9e914f087009858a77e323fb2c3597609ca3d38..f8121310b1e413496d6663701662051d256f95ed 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -442,7 +442,7 @@ typedef struct { /*!\brief LCID of MCCH for DL */ #define MCCH_LCHANID 0 /*!\brief LCID of MCH scheduling info for DL */ -#define MCH_SCHDL_INFO 3 +#define MCH_SCHDL_INFO 30 /*!\brief LCID of Carrier component activation/deactivation */ #define CC_ACT_DEACT 27 //TTN (for D2D) @@ -1502,7 +1502,16 @@ typedef struct { /// MCCH status uint8_t mcch_status; /// MSI status - uint8_t msi_status; // could be an array if there are >1 MCH in one MBSFN area + uint8_t msi_status_v[28]; + uint8_t msi_current_alloc; + uint8_t msi_pmch; + + struct MBSFN_SubframeConfig *commonSF_Alloc_r9_mbsfn_SubframeConfig[8]; // FIXME replace 8 by MAX_MBSFN_AREA? + uint8_t commonSF_AllocPeriod_r9; + int common_num_sf_alloc; + + uint8_t pmch_lcids[28]; + uint16_t pmch_stop_mtch[28]; #endif //#ifdef CBA /// CBA RNTI for each group diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index dd78da72751db65b3ae551d921b25353e9fcc33f..581fe9587dd024a236995f73e74544bf1a8c38b4 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -750,7 +750,7 @@ ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, uint8_t sync_area) { - unsigned char num_sdu, i, *payload_ptr; + unsigned char num_sdu, i, j, *payload_ptr; unsigned char rx_lcids[NB_RB_MAX]; unsigned short rx_lengths[NB_RB_MAX]; #if UE_TIMING_TRACE @@ -771,47 +771,76 @@ ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, num_sdu); for (i = 0; i < num_sdu; i++) { - if (rx_lcids[i] == MCH_SCHDL_INFO) { - if (UE_mac_inst[module_idP].mcch_status == 1) { - LOG_I(MAC, - "[UE %d] Frame %d : MCH->MSI for sync area %d (eNB %d, %d bytes)\n", - module_idP, frameP, sync_area, eNB_index, - rx_lengths[i]); - // ??store necessary scheduling info to ue_mac_inst in order to - // calculate exact position of interested service (for the complex case has >1 mtch) - // set msi_status to 1 - UE_mac_inst[module_idP].msi_status = 1; - } - } else if (rx_lcids[i] == MCCH_LCHANID) { - LOG_I(MAC, - "[UE %d] Frame %d : SDU %d MCH->MCCH for sync area %d (eNB %d, %d bytes)\n", - module_idP, frameP, i, sync_area, eNB_index, - rx_lengths[i]); - mac_rrc_data_ind_ue(module_idP, CC_id, frameP, 0, // unknown subframe - M_RNTI, - MCCH, - payload_ptr, rx_lengths[i], eNB_index, - sync_area); - } else if (rx_lcids[i] == MTCH) { - if (UE_mac_inst[module_idP].msi_status == 1) { - LOG_I(MAC, - "[UE %d] Frame %d : MCH->MTCH for sync area %d (eNB %d, %d bytes)\n", - module_idP, frameP, sync_area, eNB_index, - rx_lengths[i]); + if (rx_lcids[i] == MCH_SCHDL_INFO) { + if (rx_lengths[i] & 0x01) { + LOG_E(MAC,"MCH Scheduling Information MAC Control Element should have an even size\n"); + } - mac_rlc_data_ind(module_idP, UE_mac_inst[module_idP].crnti, eNB_index, frameP, ENB_FLAG_NO, MBMS_FLAG_YES, MTCH, /*+ (maxDRB + 3), */ - (char *) payload_ptr, rx_lengths[i], 1, - NULL); + LOG_D(MAC,"MCH Scheduling Information, len(%d)\n",rx_lengths[i]); - } - } else { - LOG_W(MAC, - "[UE %d] Frame %d : unknown sdu %d rx_lcids[%d]=%d mcch status %d eNB %d \n", - module_idP, frameP, rx_lengths[i], i, rx_lcids[i], - UE_mac_inst[module_idP].mcch_status, eNB_index); - } + for (j=0; j<rx_lengths[i]/2; j++) { + uint16_t stop_mtch_val = ((uint16_t)(payload_ptr[2*j] & 0x07) << 8) | (uint16_t)payload_ptr[2*j+1]; + + UE_mac_inst[module_idP].pmch_lcids[j] = (payload_ptr[2*j] & 0xF8) >> 3; + UE_mac_inst[module_idP].pmch_stop_mtch[j] = stop_mtch_val; + LOG_D(MAC,"lcid(%d),stop_mtch_val %d frameP(%d)\n", UE_mac_inst[module_idP].pmch_lcids[j], stop_mtch_val, frameP); + + if ((stop_mtch_val >= 2043) && (stop_mtch_val <= 2046)) { + LOG_D(MAC,"(reserved)\n"); + } + + UE_mac_inst[module_idP].msi_status_v[j] = 0; - payload_ptr += rx_lengths[i]; + if (UE_mac_inst[module_idP].mcch_status==1) { + LOG_D(MAC,"[UE %d] Frame %d : MCH->MSI for sync area %d (eNB %d, %d bytes), i(%d)\n", module_idP, frameP, sync_area, eNB_index, rx_lengths[i], UE_mac_inst[module_idP].pmch_stop_mtch[j]); + if (UE_mac_inst[module_idP].pmch_stop_mtch[j] < 2043) { + UE_mac_inst[module_idP].pmch_stop_mtch[j] += UE_mac_inst[module_idP].msi_current_alloc; + UE_mac_inst[module_idP].msi_status_v[j] = 1; + } + } + } + } else if (rx_lcids[i] == MCCH_LCHANID) { + LOG_D(MAC,"[UE %d] Frame %d : SDU %d MCH->MCCH for sync area %d (eNB %d, %d bytes)\n",module_idP,frameP, i, sync_area, eNB_index, rx_lengths[i]); + mac_rrc_data_ind_ue(module_idP, + CC_id, + frameP,0, // unknown subframe + M_RNTI, + MCCH, + payload_ptr + 1, // Skip RLC layer 1st byte + rx_lengths[i] - 1, + eNB_index, + sync_area); + } else if (rx_lcids[i] <= 28) { + for (j=0; j<28; j++) { + if (rx_lcids[i] == UE_mac_inst[module_idP].pmch_lcids[j]) + break; + } + + if (j<28 && UE_mac_inst[module_idP].msi_status_v[j]==1) { + LOG_D(MAC,"[UE %d] Frame %d : MCH->MTCH for sync area %d (eNB %d, %d bytes), j=%d\n", module_idP, frameP, sync_area, eNB_index, rx_lengths[i], j); + + mac_rlc_data_ind( + module_idP, + UE_mac_inst[module_idP].crnti, + eNB_index, + frameP, + ENB_FLAG_NO, + MBMS_FLAG_YES, + rx_lcids[i], /*+ (maxDRB + 3),*/ + (char *)payload_ptr, + rx_lengths[i], + 1, + NULL); + + } + } else { + LOG_W(MAC, + "[UE %d] Frame %d : unknown sdu %d rx_lcids[%d]=%d mcch status %d eNB %d \n", + module_idP, frameP, rx_lengths[i], i, rx_lcids[i], + UE_mac_inst[module_idP].mcch_status, eNB_index); + } + + payload_ptr += rx_lengths[i]; } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME @@ -916,406 +945,591 @@ int8_t ue_get_mbsfn_sf_alloction (module_id_t module_idP, uint8_t mbsfn_sync_are } } -int -ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, - uint32_t subframe, uint8_t eNB_index, uint8_t * sync_area, - uint8_t * mcch_active) +int ue_query_p_mch_info(module_id_t module_idP, uint32_t frameP, uint32_t subframe, int commonSFAlloc_period, int commonSFAlloc_offset, int num_sf_alloc, int *mtch_active, int *msi_active, uint8_t *mch_lcid) { + int i, mtch_mcs = -1; + int mtch_flag = 0; + int msi_flag = 0; - int i = 0, j = 0, ii = 0, msi_pos = 0, mcch_mcs = -1; - int mcch_flag = 0, mtch_flag = 0, msi_flag = 0; - int mbsfn_period = 0; // 1<<(UE_mac_inst[module_idP].mbsfn_SubframeConfig[0]->radioframeAllocationPeriod); - int mcch_period = 0; // 32<<(UE_mac_inst[module_idP].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_RepetitionPeriod_r9); - int mch_scheduling_period = -1; + for (i = 0; i < 4; i++) { + if (UE_mac_inst[module_idP].pmch_Config[i] == NULL) + continue; - int frame_FDD = 1; + int mch_scheduling_period = 8 << UE_mac_inst[module_idP].pmch_Config[i]->mch_SchedulingPeriod_r9; + uint8_t sf_AllocEnd_r9 = UE_mac_inst[module_idP].pmch_Config[i]->sf_AllocEnd_r9; + if (sf_AllocEnd_r9 == 2047) { + msi_flag = 1; + break; + } -#if UE_TIMING_TRACE - start_meas(&UE_mac_inst[module_idP].ue_query_mch); -#endif + if ((frameP % mch_scheduling_period) == (commonSFAlloc_offset + (frameP % 4))) { + if (i == 0) { + //msi and mtch are mutally excluded then the break is safe + if ((num_sf_alloc == 0) && (sf_AllocEnd_r9 >= 1)) { + msi_flag = 1; + LOG_D(MAC,"msi(%d) should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),sf_AllocEnd_r9(%d),common_num_sf_alloc(%d)\n",i,frameP,subframe,num_sf_alloc,sf_AllocEnd_r9,UE_mac_inst[module_idP].common_num_sf_alloc); + UE_mac_inst[module_idP].msi_current_alloc = num_sf_alloc; + UE_mac_inst[module_idP].msi_pmch = i; + } + } else { //more that one MCH ?? check better this condition + //msi and mtch are mutally excluded then the break is safe + if ((num_sf_alloc == UE_mac_inst[module_idP].pmch_Config[i-1]->sf_AllocEnd_r9 + 1) && (sf_AllocEnd_r9 >= (num_sf_alloc+1))) { + //msi should be just after + msi_flag = 1; + LOG_D(MAC,"msi(%d) should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),sf_AllocEnd_r9(%d),common_num_sf_alloc(%d)\n",i,frameP,subframe,num_sf_alloc,sf_AllocEnd_r9,UE_mac_inst[module_idP].common_num_sf_alloc); + UE_mac_inst[module_idP].msi_current_alloc = num_sf_alloc; + UE_mac_inst[module_idP].msi_pmch = i; + } + } + } + } - if (UE_mac_inst[module_idP].pmch_Config[0]) { - mch_scheduling_period = - 8 << (UE_mac_inst[module_idP]. - pmch_Config[0]->mch_SchedulingPeriod_r9); + for (i = 0; i < 28; i++) { + if (UE_mac_inst[module_idP].pmch_stop_mtch[i] >= num_sf_alloc) { + if (UE_mac_inst[module_idP].pmch_stop_mtch[i] != 2047) { + mtch_flag = 1; + if (UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch] != NULL) + mtch_mcs = UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch]->dataMCS_r9; + else + mtch_mcs = -1; + *mch_lcid = (uint8_t)i; + LOG_D(MAC,"mtch should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),mtch_mcs(%d),pmch_stop_mtch(%d),lcid(%d),msi_pmch(%d)\n",frameP,subframe,num_sf_alloc,mtch_mcs,UE_mac_inst[module_idP].pmch_stop_mtch[i],UE_mac_inst[module_idP].pmch_lcids[i],UE_mac_inst[module_idP].msi_pmch); + break; + } } + } - for (i = 0; i < UE_mac_inst[module_idP].num_active_mbsfn_area; i++) { - // assume, that there is always a mapping - if ((j = - ue_get_mbsfn_sf_alloction(module_idP, i, eNB_index)) == -1) { - return -1; // continue; - } + *mtch_active = mtch_flag; + *msi_active = msi_flag; - ii = 0; - msi_pos = 0; - mbsfn_period = - 1 << (UE_mac_inst[module_idP]. - mbsfn_SubframeConfig[0]->radioframeAllocationPeriod); - mcch_period = - 32 << (UE_mac_inst[module_idP]. - mbsfn_AreaInfo[0]->mcch_Config_r9. - mcch_RepetitionPeriod_r9); + return mtch_mcs; +} - LOG_D(MAC, - "[UE %d] Frame %d subframe %d: Checking MBSFN Sync Area %d/%d with SF allocation %d/%d for MCCH and MTCH (mbsfn period %d, mcch period %d,mac sched period (%d,%ld))\n", - module_idP, frameP, subframe, i, - UE_mac_inst[module_idP].num_active_mbsfn_area, j, - UE_mac_inst[module_idP].num_sf_allocation_pattern, - mbsfn_period, mcch_period, mch_scheduling_period, - UE_mac_inst[module_idP]. - mbsfn_SubframeConfig[j]->radioframeAllocationOffset); - - // get the real MCS value - switch (UE_mac_inst[module_idP].mbsfn_AreaInfo[i]-> - mcch_Config_r9.signallingMCS_r9) { - case 0: - mcch_mcs = 2; - break; - - case 1: - mcch_mcs = 7; - break; - - case 2: - mcch_mcs = 13; - break; - - case 3: - mcch_mcs = 19; - break; - } +int ue_query_p_mch(module_id_t module_idP, uint32_t frameP, uint32_t subframe, int *mtch_active, int *msi_active, uint8_t *mch_lcid) +{ + int i, j, mtch_mcs = -1; + int mtch_flag = 0; + + // Acount for sf_allocable in CSA + int num_sf_alloc = 0; + for (i = 0; i < 8; i++) { + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] == NULL) + continue; + + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) // one-frameP format + continue; + + // four-frameP format + uint32_t common_mbsfn_SubframeConfig = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[2] | + (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[1]<<8) | + (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]<<16); + for (j = 0; j < 24; j++) + num_sf_alloc += ((common_mbsfn_SubframeConfig & (0x800000 >> j)) == (0x800000 >> j)); + } - if (frameP % mbsfn_period == UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->radioframeAllocationOffset) { // MBSFN frameP - if (UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format + for (i = 0; i < 8; i++ ) { + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] == NULL) + continue; + + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) // one-frameP format + continue; + + // four-frameP format + int common_mbsfn_alloc_offset = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->radioframeAllocationOffset; + int common_mbsfn_period = 1 << UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->radioframeAllocationPeriod; + int commonSF_AllocPeriod = 4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9; + + uint32_t common_mbsfn_SubframeConfig = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[2] | + (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[1]<<8) | + (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]<<16); + + int jj = frameP % 4; + if ((frameP % common_mbsfn_period) != (common_mbsfn_alloc_offset + jj)) + continue; + + if(UE_mac_inst[module_idP].tdd_Config == NULL){ + switch (subframe) { + case 1: + if ((common_mbsfn_SubframeConfig & (0x800000 >> (jj*6))) == (0x800000 >> (jj*6))) { + mtch_flag = 1; + mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); + UE_mac_inst[module_idP].common_num_sf_alloc++; + UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period);//48; + } + break; + case 2: + if ((common_mbsfn_SubframeConfig & (0x400000 >> (jj*6))) == (0x400000 >> (jj*6))) { + mtch_flag = 1; + mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); + UE_mac_inst[module_idP].common_num_sf_alloc++; + UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period);//48; + } + break; + case 3: + if ((common_mbsfn_SubframeConfig & (0x200000 >> (jj*6))) == (0x200000 >> (jj*6))) { + mtch_flag = 1; + mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); + UE_mac_inst[module_idP].common_num_sf_alloc++; + UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period);//48; + } + break; + case 6: + if ((common_mbsfn_SubframeConfig & (0x100000 >> (jj*6))) == (0x100000 >> (jj*6))) { + mtch_flag = 1; + mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); + UE_mac_inst[module_idP].common_num_sf_alloc++; + UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period);//48; + } + break; + case 7: + if ((common_mbsfn_SubframeConfig & (0x80000 >> (jj*6))) == (0x80000 >> (jj*6))) { + mtch_flag = 1; + mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); + UE_mac_inst[module_idP].common_num_sf_alloc++; + UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period);//48; + } + break; + case 8: + if ((common_mbsfn_SubframeConfig & (0x40000 >> (jj*6))) == (0x40000 >> (jj*6))) { + mtch_flag = 1; + mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); + UE_mac_inst[module_idP].common_num_sf_alloc++; + UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc% ( num_sf_alloc*commonSF_AllocPeriod/common_mbsfn_period);//48; + } + break; + } + } else { + // TODO TDD + } + if (mtch_flag == 1) + break; + } - if (UE_mac_inst[module_idP].pmch_Config[0]) { - // Find the first subframe in this MCH to transmit MSI - if (frameP % mch_scheduling_period == - UE_mac_inst[module_idP]. - mbsfn_SubframeConfig - [j]->radioframeAllocationOffset) { - while (ii == 0) { - ii = UE_mac_inst[module_idP]. - mbsfn_SubframeConfig[j]-> - subframeAllocation.choice. - oneFrame.buf[0] & (0x80 >> msi_pos); - msi_pos++; - } - } - } + return mtch_mcs; +} - if (UE_mac_inst[module_idP].tdd_Config == NULL) - frame_FDD = 1; - else - frame_FDD = 0; - // Check if the subframe is for MSI, MCCH or MTCHs and Set the correspoding flag to 1 - switch (subframe) { - case 1: - if (frame_FDD == 1) { - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig - [j]->subframeAllocation.choice.oneFrame. - buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) { - if (msi_pos == 1) { - msi_flag = 1; - } +int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_t subframe, uint8_t eNB_index,uint8_t *sync_area, uint8_t *mcch_active) +{ - if ((frameP % mcch_period == - UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.mcch_Offset_r9) - && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF1) == - MBSFN_FDD_SF1)) { - mcch_flag = 1; - } + int i = 0, j = 0, ii = 0, jj = 0, msi_pos = 0, mcch_mcs = -1, mtch_mcs = -1; + int mcch_flag = 0, mtch_flag = 0, msi_flag = 0; + long mch_scheduling_period = -1; + uint8_t mch_lcid = 0; - mtch_flag = 1; - } - } +#if UE_TIMING_TRACE + start_meas(&UE_mac_inst[module_idP].ue_query_mch); +#endif - break; + if (UE_mac_inst[module_idP].pmch_Config[0]) { + mch_scheduling_period = 8 << UE_mac_inst[module_idP].pmch_Config[0]->mch_SchedulingPeriod_r9; + } - case 2: - if (frame_FDD == 1) { - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig - [j]->subframeAllocation.choice.oneFrame. - buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) { - if (msi_pos == 2) { - msi_flag = 1; - } + for (i = 0; + i < UE_mac_inst[module_idP].num_active_mbsfn_area; + i++ ) + { + // assume, that there is always a mapping + if ((j = ue_get_mbsfn_sf_alloction(module_idP,i,eNB_index)) == -1) { + return -1; // continue; + } - if ((frameP % mcch_period == - UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.mcch_Offset_r9) - && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF2) == - MBSFN_FDD_SF2)) { - mcch_flag = 1; - } + ii = 0; + msi_pos = 0; + + long mbsfn_period = 1 << UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->radioframeAllocationPeriod; + long mbsfn_alloc_offset = UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->radioframeAllocationOffset; + long mcch_period = 32 << UE_mac_inst[module_idP].mbsfn_AreaInfo[j]->mcch_Config_r9.mcch_RepetitionPeriod_r9; + long mcch_offset = UE_mac_inst[module_idP].mbsfn_AreaInfo[j]->mcch_Config_r9.mcch_Offset_r9; - mtch_flag = 1; - } - } + LOG_D(MAC, + "[UE %d] Frame %d subframe %d: Checking MBSFN Sync Area %d/%d with SF allocation %d/%d for MCCH and MTCH (mbsfn period %ld, mcch period %ld,mac sched period (%ld,%ld))\n", + module_idP,frameP, subframe,i,UE_mac_inst[module_idP].num_active_mbsfn_area, + j,UE_mac_inst[module_idP].num_sf_allocation_pattern,mbsfn_period,mcch_period, + mcch_offset,mbsfn_alloc_offset); + + // get the real MCS value + switch (UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.signallingMCS_r9) { + case 0: + mcch_mcs = 2; + break; - break; + case 1: + mcch_mcs = 7; + break; - case 3: - if (frame_FDD == 0) { //TDD - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig - [j]->subframeAllocation.choice.oneFrame. - buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) { - if (msi_pos == 1) { - msi_flag = 1; - } + case 2: + mcch_mcs = 13; + break; - if ((frameP % mcch_period == - UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.mcch_Offset_r9) - && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_TDD_SF3) == - MBSFN_TDD_SF3)) { - mcch_flag = 1; - } + case 3: + mcch_mcs = 19; + break; + } - mtch_flag = 1; - } - } else { // FDD - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig - [j]->subframeAllocation.choice.oneFrame. - buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) { - if (msi_pos == 3) { - msi_flag = 1; - } + if (UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format + if (frameP % mbsfn_period == mbsfn_alloc_offset) { // MBSFN frameP - if ((frameP % mcch_period == - UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.mcch_Offset_r9) - && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF3) == - MBSFN_FDD_SF3)) { - mcch_flag = 1; - } + if (UE_mac_inst[module_idP].pmch_Config[0]) { + // Find the first subframe in this MCH to transmit MSI + if (frameP % mch_scheduling_period == mbsfn_alloc_offset) { + while (ii == 0) { + ii = UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & (0x80 >> msi_pos); + msi_pos++; + } + } + } + + // Check if the subframe is for MSI, MCCH or MTCHs and Set the correspoding flag to 1 + switch (subframe) { + case 1: + if (UE_mac_inst[module_idP].tdd_Config == NULL) { + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) { + if (msi_pos == 1) { + msi_flag = 1; + } + + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } - mtch_flag = 1; - } - } + break; - break; + case 2: + if (UE_mac_inst[module_idP].tdd_Config == NULL) { + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) { + if (msi_pos == 2) { + msi_flag = 1; + } - case 4: - if (frame_FDD == 0) { - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig - [j]->subframeAllocation.choice.oneFrame. - buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) { - if (msi_pos == 2) { - msi_flag = 1; - } + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2)) { + mcch_flag = 1; + } - if ((frameP % mcch_period == - UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.mcch_Offset_r9) - && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_TDD_SF4) == - MBSFN_TDD_SF4)) { - mcch_flag = 1; - } + mtch_flag = 1; + } + } - mtch_flag = 1; - } - } + break; - break; + case 3: + if (UE_mac_inst[module_idP].tdd_Config != NULL) { // TDD + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) { + if (msi_pos == 1) { + msi_flag = 1; + } - case 6: - if (frame_FDD == 1) { - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig - [j]->subframeAllocation.choice.oneFrame. - buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) { - if (msi_pos == 4) { - msi_flag = 1; - } + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3)) { + mcch_flag = 1; + } - if ((frameP % mcch_period == - UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.mcch_Offset_r9) - && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF6) == - MBSFN_FDD_SF6)) { - mcch_flag = 1; - } + mtch_flag = 1; + } + } else { // FDD + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) { + if (msi_pos == 3) { + msi_flag = 1; + } + + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } - mtch_flag = 1; - } - } + break; - break; + case 4: + if (UE_mac_inst[module_idP].tdd_Config != NULL) { + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) { + if (msi_pos == 2) { + msi_flag = 1; + } - case 7: - if (frame_FDD == 0) { // TDD - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig - [j]->subframeAllocation.choice.oneFrame. - buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) { - if (msi_pos == 3) { - msi_flag = 1; - } + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4)) { + mcch_flag = 1; + } - if ((frameP % mcch_period == - UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.mcch_Offset_r9) - && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_TDD_SF7) == - MBSFN_TDD_SF7)) { - mcch_flag = 1; - } + mtch_flag = 1; + } + } - mtch_flag = 1; - } - } else { // FDD - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig - [j]->subframeAllocation.choice.oneFrame. - buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) { - if (msi_pos == 5) { - msi_flag = 1; - } + break; - if ((frameP % mcch_period == - UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.mcch_Offset_r9) - && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF7) == - MBSFN_FDD_SF7)) { - mcch_flag = 1; - } + case 6: + if (UE_mac_inst[module_idP].tdd_Config == NULL) { + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) { + if (msi_pos == 4) { + msi_flag = 1; + } - mtch_flag = 1; - } - } + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6)) { + mcch_flag = 1; + } - break; + mtch_flag = 1; + } + } - case 8: - if (frame_FDD == 0) { //TDD - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig - [j]->subframeAllocation.choice.oneFrame. - buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) { - if (msi_pos == 4) { - msi_flag = 1; - } + break; - if ((frameP % mcch_period == - UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.mcch_Offset_r9) - && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_TDD_SF8) == - MBSFN_TDD_SF8)) { - mcch_flag = 1; - } + case 7: + if (UE_mac_inst[module_idP].tdd_Config != NULL) { // TDD + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) { + if (msi_pos == 3) { + msi_flag = 1; + } - mtch_flag = 1; - } - } else { // FDD - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig - [j]->subframeAllocation.choice.oneFrame. - buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) { - if (msi_pos == 6) { - msi_flag = 1; - } + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7)) { + mcch_flag = 1; + } - if ((frameP % mcch_period == - UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.mcch_Offset_r9) - && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF8) == - MBSFN_FDD_SF8)) { - mcch_flag = 1; - } + mtch_flag = 1; + } + } else { // FDD + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) { + if (msi_pos == 5) { + msi_flag = 1; + } + + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } - mtch_flag = 1; - } - } + break; - break; + case 8: + if (UE_mac_inst[module_idP].tdd_Config != NULL) { //TDD + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) { + if (msi_pos == 4) { + msi_flag = 1; + } - case 9: - if (frame_FDD == 0) { - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig - [j]->subframeAllocation.choice.oneFrame. - buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) { - if (msi_pos == 5) { - msi_flag = 1; - } + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8)) { + mcch_flag = 1; + } - if ((frameP % mcch_period == - UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.mcch_Offset_r9) - && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_TDD_SF9) == - MBSFN_TDD_SF9)) { - mcch_flag = 1; - } + mtch_flag = 1; + } + } else { // FDD + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) { + if (msi_pos == 6) { + msi_flag = 1; + } + + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } - mtch_flag = 1; - } - } + break; - break; - } // end switch + case 9: + if (UE_mac_inst[module_idP].tdd_Config != NULL) { + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) { + if (msi_pos == 5) { + msi_flag = 1; + } - // sf allocation is non-overlapping - if ((msi_flag == 1) || (mcch_flag == 1) - || (mtch_flag == 1)) { - LOG_D(MAC, - "[UE %d] Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n", - module_idP, frameP, subframe, i, j, msi_flag, - mcch_flag, mtch_flag); + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } + + break; + }// end switch + + // Acount for sf_allocable in CSA + int num_sf_alloc = 0; + for (i = 0; i < 8; i++) { + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] == NULL) + continue; + + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.present != MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) + continue; + + uint32_t common_mbsfn_SubframeConfig = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]; + for (j = 0; j < 6; j++) + num_sf_alloc += ((common_mbsfn_SubframeConfig & (0x80 >> j)) == (0x80 >> j)); + } + + for (i = 0; i < 28; i++) { + if (UE_mac_inst[module_idP].pmch_stop_mtch[i] >= num_sf_alloc) { + if (UE_mac_inst[module_idP].pmch_stop_mtch[i] != 2047) { + if (UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch] != NULL) + mtch_mcs = UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch]->dataMCS_r9; + else + mtch_mcs = -1; + mch_lcid = (uint8_t)i; + break; + } + } + } + + // sf allocation is non-overlapping + if ((msi_flag==1) || (mcch_flag==1) || (mtch_flag==1)) { + LOG_D(MAC,"[UE %d] Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n", + module_idP, frameP, subframe,i,j,msi_flag,mcch_flag,mtch_flag); + + *sync_area=i; + break; + } + } + } else { // four-frameP format + uint32_t mbsfn_SubframeConfig = UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[2] | + (UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[1]<<8) | + (UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0]<<16); + uint32_t MCCH_mbsfn_SubframeConfig = /* UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[2] | + (UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[1]<<8) | */ + (UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0]<<16); + + jj=frameP%4; + if ((frameP % mbsfn_period) == (mbsfn_alloc_offset+jj)) { + if (UE_mac_inst[module_idP].tdd_Config == NULL) { + switch (subframe) { + case 1: + if ((mbsfn_SubframeConfig & (0x800000>>(jj*6))) == (0x800000>>(jj*6))) { + if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x800000>>(jj*6))) == (0x800000>>(jj*6)))) { + mcch_flag=1; + LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", + frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x800000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); + if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) + UE_mac_inst[module_idP].common_num_sf_alloc++; + } + } + break; + case 2: + if ((mbsfn_SubframeConfig & (0x400000>>(jj*6))) == (0x400000>>(jj*6))) { + if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x400000>>(jj*6))) == (0x400000>>(jj*6)))) { + mcch_flag=1; + LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", + frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x400000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); + if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) + UE_mac_inst[module_idP].common_num_sf_alloc++; + } + } + break; + case 3: + if ((mbsfn_SubframeConfig & (0x200000>>(jj*6))) == (0x200000>>(jj*6))) { + if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x200000>>(jj*6))) == (0x200000>>(jj*6)))) { + LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", + frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x200000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); + mcch_flag=1; + if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) + UE_mac_inst[module_idP].common_num_sf_alloc++; + } + } + break; + case 6: + if ((mbsfn_SubframeConfig & (0x100000>>(jj*6))) == (0x100000>>(jj*6))) { + if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x100000>>(jj*6))) == (0x100000>>(jj*6)))) { + LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", + frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x100000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); + mcch_flag=1; + if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) + UE_mac_inst[module_idP].common_num_sf_alloc++; + } + } + break; + case 7: + if ((mbsfn_SubframeConfig & (0x80000>>(jj*6))) == (0x80000>>(jj*6))) { + if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x80000>>(jj*6))) == (0x80000>>(jj*6)))) { + LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", + frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x80000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); + if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) + UE_mac_inst[module_idP].common_num_sf_alloc++; + mcch_flag=1; + } + } + break; + case 8: + if ((mbsfn_SubframeConfig & (0x40000>>(jj*6))) == (0x40000>>(jj*6))) { + if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x40000>>(jj*6))) == (0x40000>>(jj*6)))) { + LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", + frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x40000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); + if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) + UE_mac_inst[module_idP].common_num_sf_alloc++; + mcch_flag=1; + } + } + break; + }// end switch + } else { + // TODO TDD + } + + mtch_mcs = ue_query_p_mch(module_idP, frameP, subframe, &mtch_flag, &msi_flag, &mch_lcid); + + // sf allocation is non-overlapping + if ((msi_flag==1) || (mcch_flag==1) || (mtch_flag==1)) { + LOG_D(MAC,"[UE %d] Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n", + module_idP, frameP, subframe,i,j,msi_flag,mcch_flag,mtch_flag); + *sync_area=i; + break; + } + } + } + } // end of for - *sync_area = i; - break; - } - } else { // four-frameP format - } - } - } // end of for #if UE_TIMING_TRACE - stop_meas(&UE_mac_inst[module_idP].ue_query_mch); + stop_meas(&UE_mac_inst[module_idP].ue_query_mch); #endif - if ((mcch_flag == 1)) { // || (msi_flag==1)) - *mcch_active = 1; - } + if ((mcch_flag == 1)) { // || (msi_flag==1)) + *mcch_active = 1; + } - if ((mcch_flag == 1) - || ((msi_flag == 1) && (UE_mac_inst[module_idP].mcch_status == 1))) { - return mcch_mcs; - } else if ((mtch_flag == 1) - && (UE_mac_inst[module_idP].msi_status == 1)) { - return UE_mac_inst[module_idP].pmch_Config[0]->dataMCS_r9; + if ( (mcch_flag==1) || ((msi_flag==1) && (UE_mac_inst[module_idP].mcch_status==1)) ) { + if (msi_flag!=1) { + for (i=0; i<8; i++) + UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] = NULL; + for (i=0; i<15; i++) + UE_mac_inst[module_idP].pmch_Config[i] = NULL; + for (i=0; i<28 ;i++) { + UE_mac_inst[module_idP].pmch_lcids[i] = -1; + UE_mac_inst[module_idP].pmch_stop_mtch[i] = 2047; + UE_mac_inst[module_idP].msi_status_v[i] = 0; + } } else { - return -1; + for (i=0; i<28; i++) { + UE_mac_inst[module_idP].pmch_lcids[i] = -1; + UE_mac_inst[module_idP].pmch_stop_mtch[i] = 2047; + UE_mac_inst[module_idP].msi_status_v[i] = 0; + } } + return mcch_mcs; + } else if ((mtch_flag==1) && (UE_mac_inst[module_idP].msi_status_v[(mch_lcid > 27) ? 27 : mch_lcid] == 1)) { + return mtch_mcs; + } else { + return -1; + } } #endif diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index e12fb80e1bda913de5e770730d3fe9ca97aa9ba6..04999bab38da83a7722c3c7a024c32c60324a40f 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -30,6 +30,8 @@ #define PDCP_C //#define DEBUG_PDCP_FIFO_FLUSH_SDU +#define MBMS_MULTICAST_OUT + #include "assertions.h" #include "hashtable.h" #include "pdcp.h" @@ -66,6 +68,17 @@ extern int otg_enabled; #include "common/ran_context.h" extern RAN_CONTEXT_t RC; +#ifdef MBMS_MULTICAST_OUT +# include <sys/types.h> +# include <sys/socket.h> +# include <netinet/in.h> +# include <netinet/ip.h> +# include <netinet/udp.h> +# include <unistd.h> + +static int mbms_socket = -1; +#endif + //----------------------------------------------------------------------------- /* * If PDCP_UNIT_TEST is set here then data flow between PDCP and RLC is broken @@ -758,11 +771,26 @@ pdcp_data_ind( packet_forwarded = FALSE; #endif +#ifdef MBMS_MULTICAST_OUT + if ((MBMS_flagP != 0) && (mbms_socket != -1)) { + struct iphdr *ip_header = (struct iphdr*)&sdu_buffer_pP->data[payload_offset]; + struct udphdr *udp_header = (struct udphdr*)&sdu_buffer_pP->data[payload_offset + sizeof(struct iphdr)]; + struct sockaddr_in dest_addr; + + dest_addr.sin_family = AF_INET; + dest_addr.sin_port = udp_header->dest; + dest_addr.sin_addr.s_addr = ip_header->daddr; + + sendto(mbms_socket, &sdu_buffer_pP->data[payload_offset], sdu_buffer_sizeP - payload_offset, MSG_DONTWAIT, (struct sockaddr*)&dest_addr, sizeof(dest_addr)); + packet_forwarded = TRUE; + } +#endif + if (FALSE == packet_forwarded) { new_sdu_p = get_free_mem_block(sdu_buffer_sizeP - payload_offset + sizeof (pdcp_data_ind_header_t), __func__); if (new_sdu_p) { - if (pdcp_p->rlc_mode == RLC_MODE_AM ) { + if ((MBMS_flagP == 0) && (pdcp_p->rlc_mode == RLC_MODE_AM)) { pdcp_p->last_submitted_pdcp_rx_sn = sequence_number; } @@ -803,7 +831,6 @@ pdcp_data_ind( } - } /* Print octets of incoming data in hexadecimal form */ LOG_D(PDCP, "Following content has been received from RLC (%d,%d)(PDCP header has already been removed):\n", @@ -839,13 +866,14 @@ pdcp_data_ind( #if defined(STOP_ON_IP_TRAFFIC_OVERLOAD) - else { - AssertFatal(0, PROTOCOL_PDCP_CTXT_FMT" PDCP_DATA_IND SDU DROPPED, OUT OF MEMORY \n", - PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p)); - } - + else { + AssertFatal(0, PROTOCOL_PDCP_CTXT_FMT" PDCP_DATA_IND SDU DROPPED, OUT OF MEMORY \n", + PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p)); + } #endif + } + free_mem_block(sdu_buffer_pP, __func__); if (ctxt_pP->enb_flag) { @@ -1458,8 +1486,12 @@ rrc_pdcp_config_asn1_req ( for (j=0; j<mbms_SessionInfoList_r9_p->list.count; j++) { MBMS_SessionInfo_p = mbms_SessionInfoList_r9_p->list.array[j]; - lc_id = MBMS_SessionInfo_p->sessionId_r9->buf[0]; + if (MBMS_SessionInfo_p->sessionId_r9) + lc_id = MBMS_SessionInfo_p->sessionId_r9->buf[0]; + else + lc_id = MBMS_SessionInfo_p->logicalChannelIdentity_r9; mch_id = MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[2]; //serviceId is 3-octet string +// mch_id = j; // can set the mch_id = i if (ctxt_pP->enb_flag) { @@ -1480,6 +1512,14 @@ rrc_pdcp_config_asn1_req ( } } + LOG_D(PDCP, "lc_id (%02ld) mch_id(%02x,%02x,%02x) drb_id(%ld) action(%d)\n", + lc_id, + MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[0], + MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[1], + MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[2], + drb_id, + action); + pdcp_config_req_asn1 ( ctxt_pP, NULL, // unused for MBMS @@ -2018,6 +2058,12 @@ void pdcp_layer_init(void) #endif } +#ifdef MBMS_MULTICAST_OUT + mbms_socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); + if (mbms_socket == -1) + LOG_W(PDCP, "Could not create RAW socket, MBMS packets will not be put to the network\n"); +#endif + LOG_I(PDCP, "PDCP layer has been initialized\n"); pdcp_output_sdu_bytes_to_write=0; @@ -2068,6 +2114,12 @@ void pdcp_layer_cleanup (void) { list_free (&pdcp_sdu_list); hashtable_destroy(pdcp_coll_p); +#ifdef MBMS_MULTICAST_OUT + if(mbms_socket != -1) { + close(mbms_socket); + mbms_socket = -1; + } +#endif } #ifdef PDCP_USE_RT_FIFO diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h index ff49b2d056f12f2e07a6a642322411e0841c5398..8c557188a2a2e115300b7ea9d15ef4032da49e1e 100644 --- a/openair2/LAYER2/RLC/rlc.h +++ b/openair2/LAYER2/RLC/rlc.h @@ -208,7 +208,7 @@ rlc_mbms_id_t rlc_mbms_lcid2service_session_id_eNB[MAX_eNB][RLC_MAX_MBMS_ #define rlc_mbms_ue_get_lcid_by_rb_id(uE_mOD,rB_iD) rlc_mbms_rbid2lcid_ue[uE_mOD][rB_iD] #define rlc_mbms_ue_set_lcid_by_rb_id(uE_mOD,rB_iD,lOG_cH_iD) do { \ - AssertFatal(rB_iD<NB_RB_MAX, "INVALID RB ID %u", rB_iD); \ + AssertFatal(rB_iD<NB_RB_MBMS_MAX, "INVALID RB ID %u", rB_iD); \ rlc_mbms_rbid2lcid_ue[uE_mOD][rB_iD] = lOG_cH_iD; \ } while (0); diff --git a/openair2/LAYER2/RLC/rlc_rrc.c b/openair2/LAYER2/RLC/rlc_rrc.c index aa00ffb773c876f4c8e99edac83394794e457822..8977e422b60591d100fd809aa36643c090469cb2 100644 --- a/openair2/LAYER2/RLC/rlc_rrc.c +++ b/openair2/LAYER2/RLC/rlc_rrc.c @@ -414,9 +414,13 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP for (j=0; j<mbms_SessionInfoList_r9_p->list.count; j++) { MBMS_SessionInfo_p = mbms_SessionInfoList_r9_p->list.array[j]; - mbms_session_id = MBMS_SessionInfo_p->sessionId_r9->buf[0]; + if (MBMS_SessionInfo_p->sessionId_r9) + mbms_session_id = MBMS_SessionInfo_p->sessionId_r9->buf[0]; + else + mbms_session_id = MBMS_SessionInfo_p->logicalChannelIdentity_r9; lc_id = mbms_session_id; mbms_service_id = MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[2]; //serviceId is 3-octet string +// mbms_service_id = j; // can set the mch_id = i if (ctxt_pP->enb_flag) { diff --git a/openair2/NETWORK_DRIVER/LITE/common.c b/openair2/NETWORK_DRIVER/LITE/common.c index 0d616d5764fa16e47ec5971b8f81346c54d110c8..2ae6f5279d12ce5f2be1f2b1d36ee59d5ddfbef2 100644 --- a/openair2/NETWORK_DRIVER/LITE/common.c +++ b/openair2/NETWORK_DRIVER/LITE/common.c @@ -333,7 +333,7 @@ void oai_nw_drv_common_class_wireless2ip(uint16_t dlen, printk("\n"); #endif //OAI_DRV_DEBUG_RECEIVE - netif_rx(skb); + netif_rx_ni(skb); #ifdef OAI_DRV_DEBUG_RECEIVE printk("[OAI_IP_DRV][%s] end\n",__FUNCTION__); #endif diff --git a/openair2/NETWORK_DRIVER/MESH/common.c b/openair2/NETWORK_DRIVER/MESH/common.c index d380b8a4d829cf31bf1369996d05de279cab73a5..1c7b8e4d123d41c11b1dfb9f5b47ffc916d8d997 100644 --- a/openair2/NETWORK_DRIVER/MESH/common.c +++ b/openair2/NETWORK_DRIVER/MESH/common.c @@ -309,7 +309,7 @@ void nas_COMMON_receive(uint16_t dlen, printk("\n"); #endif //NAS_DEBUG_RECEIVE - netif_rx(skb); + netif_rx_ni(skb); #ifdef NAS_DEBUG_RECEIVE printk("NAS_COMMON_RECEIVE: end\n"); #endif diff --git a/openair2/NETWORK_DRIVER/UE_IP/common.c b/openair2/NETWORK_DRIVER/UE_IP/common.c index 84f425ef3c004646069f1e0496620a6cca4327a9..b21ca5f2dcc7bd9c8fab015f9f95d5b546fa4b77 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/common.c +++ b/openair2/NETWORK_DRIVER/UE_IP/common.c @@ -222,7 +222,7 @@ skb_p->mark = rb_idP; printk("\n"); #endif //OAI_DRV_DEBUG_RECEIVE - netif_rx(skb_p); + netif_rx_ni(skb_p); #ifdef OAI_DRV_DEBUG_RECEIVE printk("[UE_IP_DRV][%s] end\n",__FUNCTION__); #endif diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index c23bf12d52a8b533bb54f6023025ee1566fba317..ecdc451eee075c3415e524c1f17bc35c596e48cf 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -4594,10 +4594,30 @@ int decode_MCCH_Message( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB //----------------------------------------------------------------------------- void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_index, frame_t frameP, uint8_t mbsfn_sync_area ) { + uint8_t i; protocol_ctxt_t ctxt; LOG_I(RRC,"[UE %d] Frame %d : Number of MCH(s) in the MBSFN Sync Area %d is %d\n", ue_mod_idP, frameP, mbsfn_sync_area, UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->pmch_InfoList_r9.list.count); + + // Configure commonSF_Alloc + for(i=0; i< UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.count;i++){ + LOG_W(RRC,"[UE %d] Frame %d, commonSF_Alloc_r9: radioframeAllocationPeriod(%ldn),radioframeAllocationOffset(%ld), subframeAllocation(%x,%x,%x)\n", + ue_mod_idP, frameP, + UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]->radioframeAllocationPeriod<<1, + UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]->radioframeAllocationOffset, + UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]->subframeAllocation.choice.oneFrame.buf[0], + UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]->subframeAllocation.choice.oneFrame.buf[1], + UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]->subframeAllocation.choice.oneFrame.buf[2]); + UE_mac_inst[ue_mod_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] = UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]; + } + LOG_W(RRC,"[UE %d] Frame %d, commonSF_AllocPeriod_r9 %drf \n", + ue_mod_idP, frameP, + 4<<UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_AllocPeriod_r9); + + // Configure commonSF_AllocPeriod + UE_mac_inst[ue_mod_idP].commonSF_AllocPeriod_r9 = UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_AllocPeriod_r9; + // store to MAC/PHY necessary parameters for receiving MTCHs rrc_mac_config_req_ue(ue_mod_idP,0,eNB_index,