diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index 9eb91c6249c35a63026befe0b6fa32d0d17e260c..3679ccacf55bc02ece4691fc7d5a900aea56a259 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -315,6 +315,7 @@ void phy_config_sib13_ue(u8 Mod_id,u8 CH_index,int mbsfn_Area_idx, if (mbsfn_Area_idx == 0) { lte_frame_parms->Nid_cell_mbsfn = (uint16_t)mbsfn_AreaId_r9; + LOG_N(PHY,"Fix me: only called when mbsfn_Area_idx == 0)\n"); } lte_gold_mbsfn(lte_frame_parms,PHY_vars_UE_g[Mod_id]->lte_gold_mbsfn_table,lte_frame_parms->Nid_cell_mbsfn); @@ -332,6 +333,7 @@ void phy_config_sib13_eNB(u8 Mod_id,int mbsfn_Area_idx, if (mbsfn_Area_idx == 0) { lte_frame_parms->Nid_cell_mbsfn = (uint16_t)mbsfn_AreaId_r9; + LOG_N(PHY,"Fix me: only called when mbsfn_Area_idx == 0)\n"); } lte_gold_mbsfn(lte_frame_parms,PHY_vars_eNB_g[Mod_id]->lte_gold_mbsfn_table,lte_frame_parms->Nid_cell_mbsfn); diff --git a/openair1/PHY/LTE_TRANSPORT/pmch.c b/openair1/PHY/LTE_TRANSPORT/pmch.c index 3bf509246bc2d5581a35fb1820720d7b401fad1d..97f276256a7a3db27dddddc0e1beeae9fa20adc4 100644 --- a/openair1/PHY/LTE_TRANSPORT/pmch.c +++ b/openair1/PHY/LTE_TRANSPORT/pmch.c @@ -74,37 +74,37 @@ void dump_mch(PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u16 coded_bits_per_codeword,int int is_pmch_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms) { uint32_t period; + uint8_t i; - if (frame_parms->num_MBSFN_config > 0) { // we have at least one MBSFN configuration - - period = 1<<frame_parms->MBSFN_config[0].radioframeAllocationPeriod; - if ((frame % period) == frame_parms->MBSFN_config[0].radioframeAllocationOffset) { - if (frame_parms->MBSFN_config[0].fourFrames_flag == 0) { + 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->frame_type == FDD) { switch (subframe) { case 1: - if ((frame_parms->MBSFN_config[0].mbsfn_SubframeConfig & MBSFN_FDD_SF1) > 0) + if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_FDD_SF1) > 0) return(1); break; case 2: - if ((frame_parms->MBSFN_config[0].mbsfn_SubframeConfig & MBSFN_FDD_SF2) > 0) + if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_FDD_SF2) > 0) return(1); break; case 3: - if ((frame_parms->MBSFN_config[0].mbsfn_SubframeConfig & MBSFN_FDD_SF3) > 0) + if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_FDD_SF3) > 0) return(1); break; case 6: - if ((frame_parms->MBSFN_config[0].mbsfn_SubframeConfig & MBSFN_FDD_SF6) > 0) + if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_FDD_SF6) > 0) return(1); break; case 7: - if ((frame_parms->MBSFN_config[0].mbsfn_SubframeConfig & MBSFN_FDD_SF7) > 0) + if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_FDD_SF7) > 0) return(1); break; case 8: - if ((frame_parms->MBSFN_config[0].mbsfn_SubframeConfig & MBSFN_FDD_SF8) > 0) + if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_FDD_SF8) > 0) return(1); break; } @@ -112,23 +112,23 @@ int is_pmch_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_par else { switch (subframe) { case 3: - if ((frame_parms->MBSFN_config[0].mbsfn_SubframeConfig & MBSFN_TDD_SF3) > 0) + if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_TDD_SF3) > 0) return(1); break; case 4: - if ((frame_parms->MBSFN_config[0].mbsfn_SubframeConfig & MBSFN_TDD_SF4) > 0) + if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_TDD_SF4) > 0) return(1); break; case 7: - if ((frame_parms->MBSFN_config[0].mbsfn_SubframeConfig & MBSFN_TDD_SF7) > 0) + if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_TDD_SF7) > 0) return(1); break; case 8: - if ((frame_parms->MBSFN_config[0].mbsfn_SubframeConfig & MBSFN_TDD_SF8) > 0) + if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_TDD_SF8) > 0) return(1); break; case 9: - if ((frame_parms->MBSFN_config[0].mbsfn_SubframeConfig & MBSFN_TDD_SF9) > 0) + if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_TDD_SF9) > 0) return(1); break; } diff --git a/openair1/PHY/LTE_TRANSPORT/print_stats.c b/openair1/PHY/LTE_TRANSPORT/print_stats.c index 6f33c63e82943a036b2260cf24b3d5a03a0eabb1..c818a52b82c0aca7ba3ebc2572cf074a0e98f072 100644 --- a/openair1/PHY/LTE_TRANSPORT/print_stats.c +++ b/openair1/PHY/LTE_TRANSPORT/print_stats.c @@ -210,6 +210,16 @@ int dump_ue_stats(PHY_VARS_UE *phy_vars_ue, char* buffer, int length, runmode_t len += sprintf(&buffer[len], "[UE PROC] DLSCH Total %d, Error %d, FER %d\n",phy_vars_ue->dlsch_received[0],phy_vars_ue->dlsch_errors[0],phy_vars_ue->dlsch_fer[0]); len += sprintf(&buffer[len], "[UE PROC] DLSCH (SI) Total %d, Error %d\n",phy_vars_ue->dlsch_SI_received[0],phy_vars_ue->dlsch_SI_errors[0]); len += sprintf(&buffer[len], "[UE PROC] DLSCH (RA) Total %d, Error %d\n",phy_vars_ue->dlsch_ra_received[0],phy_vars_ue->dlsch_ra_errors[0]); +#ifdef Rel10 + int i=0; + //len += sprintf(&buffer[len], "[UE PROC] MCH Total %d\n", phy_vars_ue->dlsch_mch_received[0]); + for(i=0; i <phy_vars_ue->lte_frame_parms.num_MBSFN_config; i++ ){ + len += sprintf(&buffer[len], "[UE PROC] MCH (MCCH MBSFN %d) Total %d, Error %d, Trials %d\n", + i, phy_vars_ue->dlsch_mcch_received[i][0],phy_vars_ue->dlsch_mcch_errors[i][0],phy_vars_ue->dlsch_mcch_trials[i][0]); + len += sprintf(&buffer[len], "[UE PROC] MCH (MTCH MBSFN %d) Total %d, Error %d, Trials %d\n", + i, phy_vars_ue->dlsch_mtch_received[i][0],phy_vars_ue->dlsch_mtch_errors[i][0],phy_vars_ue->dlsch_mtch_trials[i][0]); + } +#endif len += sprintf(&buffer[len], "[UE PROC] DLSCH Bitrate %dkbps\n",(phy_vars_ue->bitrate[0]/1000)); len += sprintf(&buffer[len], "[UE PROC] Total Received Bits %dkbits\n",(phy_vars_ue->total_received_bits[0]/1000)); diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index 0d77332c2beb256e0008677eb1a4f7269e467188..592a25ccc6f5a6a1e54843002bc056893c774ae5 100755 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -135,7 +135,6 @@ #include "PHY/CODING/defs.h" #include "PHY/TOOLS/defs.h" - #ifdef OPENAIR_LTE //#include "PHY/LTE_ESTIMATION/defs.h" @@ -159,8 +158,7 @@ enum transmission_access_mode{ }; /// Top-level PHY Data Structure for eNB -typedef struct -{ +typedef struct { /// Module ID indicator for this instance u8 Mod_id; u8 local_flag; @@ -388,7 +386,14 @@ typedef struct int dlsch_SI_errors[NUMBER_OF_CONNECTED_eNB_MAX]; int dlsch_ra_received[NUMBER_OF_CONNECTED_eNB_MAX]; int dlsch_ra_errors[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_mch_errors[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mch_received_sf[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mch_received[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mcch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mtch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mcch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mtch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mcch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mtch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; int current_dlsch_cqi[NUMBER_OF_CONNECTED_eNB_MAX]; unsigned char first_run_timing_advance[NUMBER_OF_CONNECTED_eNB_MAX]; u8 generate_prach; @@ -480,7 +485,19 @@ typedef struct time_stats_t dlsch_tc_intl2_stats; } PHY_VARS_UE; - +/// Top-level PHY Data Structure for RN +typedef struct { + /// Module ID indicator for this instance + u8 Mod_id; + u32 frame; + // phy_vars_eNB + // phy_vars ue + // cuurently only used to store and forward the PMCH + u8 mch_avtive[10]; + u8 sync_area[10]; // num SF + LTE_UE_DLSCH_t *dlsch_rn_MCH[10]; + +} PHY_VARS_RN; #include "PHY/INIT/defs.h" #include "PHY/LTE_REFSIG/defs.h" diff --git a/openair1/PHY/extern.h b/openair1/PHY/extern.h index aec88c566f78f78ea343dc25e30b969a700e2b94..07078d71ec2245428352c98fd713ca0ee4aa0cd1 100755 --- a/openair1/PHY/extern.h +++ b/openair1/PHY/extern.h @@ -27,6 +27,7 @@ extern unsigned int DAQ_MBOX; extern PHY_VARS_UE **PHY_vars_UE_g; extern PHY_VARS_eNB **PHY_vars_eNB_g; +extern PHY_VARS_RN **PHY_vars_RN_g; extern LTE_DL_FRAME_PARMS *lte_frame_parms_g; diff --git a/openair1/PHY/vars.h b/openair1/PHY/vars.h index 03f91963daffcf17a2f7ec44ac2a8caa0b04ba7e..cae0782dd2ff681a8751f0151b19ee289b8eb7a2 100755 --- a/openair1/PHY/vars.h +++ b/openair1/PHY/vars.h @@ -36,6 +36,7 @@ s16 *primary_synch2_time; //PHY_VARS *PHY_vars; PHY_VARS_UE **PHY_vars_UE_g; PHY_VARS_eNB **PHY_vars_eNB_g; +PHY_VARS_RN **PHY_vars_RN_g; LTE_DL_FRAME_PARMS *lte_frame_parms_g; short *twiddle_ifft,*twiddle_fft,*twiddle_fft_times4,*twiddle_ifft_times4,*twiddle_fft_half,*twiddle_ifft_half; diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h index 797f92c7fd825e84402c8772fbeedf27a4924d3d..531b5ca323f7ac23cbf077450c2d3e3b280ed30d 100644 --- a/openair1/SCHED/defs.h +++ b/openair1/SCHED/defs.h @@ -126,8 +126,9 @@ void cleanup_dlsch_threads(void); @param phy_vars_eNB Pointer to eNB variables on which to act @param abstraction_flag Indicator of PHY abstraction @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying + @param *phy_vars_rn pointer to RN variables */ -void phy_procedures_eNB_lte(u8 last_slot, u8 next_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag, relaying_type_t r_type); +void phy_procedures_eNB_lte(u8 last_slot, u8 next_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag, relaying_type_t r_type, PHY_VARS_RN *phy_vars_rn); /*! \brief Top-level entry routine for UE procedures. Called every slot by process scheduler. In even slots, it performs RX functions from previous subframe (if required). On odd slots, it generate TX waveform for the following subframe. @param last_slot Index of last slot (0-19) @@ -137,8 +138,9 @@ void phy_procedures_eNB_lte(u8 last_slot, u8 next_slot,PHY_VARS_eNB *phy_vars_eN @param abstraction_flag Indicator of PHY abstraction @param mode calibration/debug mode @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying + @param *phy_vars_rn pointer to RN variables */ -void phy_procedures_UE_lte(u8 last_slot, u8 next_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,runmode_t mode, relaying_type_t r_type); +void phy_procedures_UE_lte(u8 last_slot, u8 next_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,runmode_t mode,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn); #ifdef Rel10 /*! @@ -175,8 +177,9 @@ void phy_procedures_UE_TX(u8 next_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abs @param abstraction_flag Indicator of PHY abstraction @param mode calibration/debug mode @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying + @param phy_vars_rn pointer to RN variables */ -int phy_procedures_UE_RX(u8 last_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,runmode_t mode,relaying_type_t r_type); +int phy_procedures_UE_RX(u8 last_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,runmode_t mode,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn); /*! \brief Scheduling for UE TX procedures in TDD S-subframes. @@ -204,8 +207,9 @@ void phy_procedures_UE_S_RX(u8 last_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 a @param phy_vars_eNB Pointer to eNB variables on which to act @param abstraction_flag Indicator of PHY abstraction @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying + @param phy_vars_rn pointer to the RN variables */ -void phy_procedures_eNB_TX(u8 next_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag,relaying_type_t r_type); +void phy_procedures_eNB_TX(u8 next_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn); /*! \brief Scheduling for eNB RX procedures in normal subframes. diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 98bd21a5467d8b25ab0561cc3c9b03610c46af61..fca5c17b1534d57b2b191b800b6141e4ad1f9ea9 100755 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -888,7 +888,8 @@ void fill_dci_emos(DCI_PDU *DCI_pdu, u8 subframe, PHY_VARS_eNB *phy_vars_eNB) { int QPSK[4]={AMP_OVER_SQRT2|(AMP_OVER_SQRT2<<16),AMP_OVER_SQRT2|((65536-AMP_OVER_SQRT2)<<16),((65536-AMP_OVER_SQRT2)<<16)|AMP_OVER_SQRT2,((65536-AMP_OVER_SQRT2)<<16)|(65536-AMP_OVER_SQRT2)}; int QPSK2[4]={AMP_OVER_2|(AMP_OVER_2<<16),AMP_OVER_2|((65536-AMP_OVER_2)<<16),((65536-AMP_OVER_2)<<16)|AMP_OVER_2,((65536-AMP_OVER_2)<<16)|(65536-AMP_OVER_2)}; -void phy_procedures_eNB_TX(unsigned char next_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag,relaying_type_t r_type) { +void phy_procedures_eNB_TX(unsigned char next_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag, + relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn) { u8 *pbch_pdu=&phy_vars_eNB->pbch_pdu[0]; // unsigned int nb_dci_ue_spec = 0, nb_dci_common = 0; u16 input_buffer_length, re_allocated=0; @@ -911,7 +912,9 @@ void phy_procedures_eNB_TX(unsigned char next_slot,PHY_VARS_eNB *phy_vars_eNB,u8 int re_offset; uint32_t *txptr; #ifdef Rel10 - MCH_PDU *mch_pdu; + MCH_PDU *mch_pduP; + MCH_PDU mch_pdu; + u8 sync_area=255; #endif #if defined(SMBV) && !defined(EXMIMO) // counts number of allocations in subframe @@ -970,17 +973,66 @@ void phy_procedures_eNB_TX(unsigned char next_slot,PHY_VARS_eNB *phy_vars_eNB,u8 next_slot,1); #ifdef Rel10 - // get MCH from MAC - mch_pdu = mac_xface->get_mch_sdu(phy_vars_eNB->Mod_id,phy_vars_eNB->frame,next_slot>>1); - - fill_eNB_dlsch_MCH(phy_vars_eNB,mch_pdu->mcs,1,0); - - LOG_D(PHY,"[eNB%d][MCH] Frame %d: Got MCH pdu for MBSFN Subframe %d : MCS %d, TBS %d\n",phy_vars_eNB->Mod_id,phy_vars_eNB->frame,next_slot>>1,mch_pdu->mcs,phy_vars_eNB->dlsch_eNB_MCH->harq_processes[0]->TBS>>3); - // Generate PMCH - generate_mch(phy_vars_eNB,next_slot>>1,(uint8_t*)mch_pdu->payload); - /*for (i=0;i<phy_vars_eNB->dlsch_eNB_MCH->harq_processes[0]->TBS>>3;i++) - printf("%2x.",(uint8_t)mch_pdu->payload[i]); - printf("\n");*/ + // if mcch is active, send regardless of the node type: eNB or RN + // when mcch is active, MAC sched does not allow MCCH and MTCH multiplexing + mch_pduP = mac_xface->get_mch_sdu(phy_vars_eNB->Mod_id,phy_vars_eNB->frame,next_slot>>1); + switch (r_type){ + case no_relay: + if ((mch_pduP->Pdu_size > 0) && (mch_pduP->sync_area == 0)) // TEST: only transmit mcch for sync area 0 + //if ((mch_pduP->sync_area == 0)) // TEST: only transmit mcch for sync area 0 + LOG_I(PHY,"[eNB%d] Frame %d subframe %d : Got MCH pdu for MBSFN (MCS %d, TBS %d) \n", + phy_vars_eNB->Mod_id,phy_vars_eNB->frame,next_slot>>1,mch_pduP->mcs, + phy_vars_eNB->dlsch_eNB_MCH->harq_processes[0]->TBS>>3); + else { + LOG_D(PHY,"[DeNB %d] Frame %d subframe %d : Do not transmit MCH pdu for MBSFN sync area %d (%s)\n", + phy_vars_eNB->Mod_id,phy_vars_eNB->frame,next_slot>>1,mch_pduP->sync_area, + (mch_pduP->Pdu_size == 0)? "Empty MCH PDU":"Let RN transmit for the moment"); + mch_pduP = NULL; + } + break; + case multicast_relay: + if ((mch_pduP->Pdu_size > 0) && ((mch_pduP->mcch_active == 1) || mch_pduP->msi_active==1)){ + //if (((mch_pduP->mcch_active == 1) || mch_pduP->msi_active==1)){ + LOG_I(PHY,"[RN %d] Frame %d subframe %d: Got the MCH PDU for MBSFN sync area %d (MCS %d, TBS %d)\n", + phy_vars_rn->Mod_id,phy_vars_rn->frame, next_slot>>1, + mch_pduP->sync_area,mch_pduP->mcs,mch_pduP->Pdu_size); + } else if (phy_vars_rn->mch_avtive[(next_slot>>1)%5] == 1){ // SF2 -> SF7, SF3 -> SF8 + mch_pduP= &mch_pdu; + memcpy(&mch_pduP->payload, // could be a simple copy + phy_vars_rn->dlsch_rn_MCH[(next_slot>>1)%5]->harq_processes[0]->b, + phy_vars_rn->dlsch_rn_MCH[(next_slot>>1)%5]->harq_processes[0]->TBS>>3); + mch_pduP->Pdu_size = (uint16_t) (phy_vars_rn->dlsch_rn_MCH[(next_slot>>1)%5]->harq_processes[0]->TBS>>3); + mch_pduP->mcs = phy_vars_rn->dlsch_rn_MCH[(next_slot>>1)%5]->harq_processes[0]->mcs; + LOG_I(PHY,"[RN %d] Frame %d subframe %d: Forward the MCH PDU for MBSFN received on SF %d sync area %d (MCS %d, TBS %d)\n", + phy_vars_rn->Mod_id,phy_vars_rn->frame, next_slot>>1,(next_slot>>1)%5, + phy_vars_rn->sync_area[(next_slot>>1)%5],mch_pduP->mcs,mch_pduP->Pdu_size); + } else { + /* LOG_I(PHY,"[RN %d] Frame %d subframe %d: do not forward MCH pdu for MBSFN sync area %d (MCS %d, TBS %d)\n", + phy_vars_rn->Mod_id,phy_vars_rn->frame, next_slot>>1, + mch_pduP->sync_area,mch_pduP->mcs,mch_pduP->Pdu_size);*/ + mch_pduP=NULL; + } + phy_vars_rn->mch_avtive[next_slot>>1]=0; + break; + default: + LOG_W(PHY,"[eNB %d] Frame %d subframe %d: unknown relaying type %d \n", + phy_vars_eNB->Mod_id,phy_vars_eNB->frame,next_slot>>1,r_type); + mch_pduP=NULL; + break; + }// switch + + if (mch_pduP){ + fill_eNB_dlsch_MCH(phy_vars_eNB,mch_pduP->mcs,1,0); + // Generate PMCH + generate_mch(phy_vars_eNB,next_slot>>1,(uint8_t*)mch_pduP->payload); +#ifdef DEBUG_PHY + for (i=0;i<mch_pduP->Pdu_size;i++) + msg("%2x.",(uint8_t)mch_pduP->payload[i]); + msg("\n"); +#endif + } else { + LOG_D(PHY,"[eNB/RN] Frame %d subframe %d: MCH not generated \n",phy_vars_eNB->frame,next_slot>>1); + } #endif } } @@ -3377,7 +3429,7 @@ int phy_procedures_RN_eNB_TX(unsigned char last_slot, unsigned char next_slot, r do_proc= no_relay; // perform the normal eNB operation break; case multicast_relay: - if ( ((next_slot >>1) < 6) || ((next_slot >>1) > 8)) + if (((next_slot >>1) < 6) || ((next_slot >>1) > 8)) do_proc = 0; // do nothing else // SF#6, SF#7 and SF#8 do_proc = multicast_relay; // do PHY procedures eNB TX @@ -3390,7 +3442,8 @@ int phy_procedures_RN_eNB_TX(unsigned char last_slot, unsigned char next_slot, r return do_proc; } #endif -void phy_procedures_eNB_lte(unsigned char last_slot, unsigned char next_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag, relaying_type_t r_type) { +void phy_procedures_eNB_lte(unsigned char last_slot, unsigned char next_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag, + relaying_type_t r_type, PHY_VARS_RN *phy_vars_rn) { /* if (phy_vars_eNB->frame >= 1000) mac_xface->macphy_exit("Exiting after 1000 Frames\n"); @@ -3404,7 +3457,7 @@ void phy_procedures_eNB_lte(unsigned char last_slot, unsigned char next_slot,PHY #ifdef Rel10 if (phy_procedures_RN_eNB_TX(last_slot, next_slot, r_type) != 0 ) #endif - phy_procedures_eNB_TX(next_slot,phy_vars_eNB,abstraction_flag,r_type); + phy_procedures_eNB_TX(next_slot,phy_vars_eNB,abstraction_flag,r_type,phy_vars_rn); } if (((phy_vars_eNB->lte_frame_parms.frame_type == 1 )&&(subframe_select(&phy_vars_eNB->lte_frame_parms,last_slot>>1)==SF_UL))|| (phy_vars_eNB->lte_frame_parms.frame_type == 0)){ @@ -3415,7 +3468,7 @@ void phy_procedures_eNB_lte(unsigned char last_slot, unsigned char next_slot,PHY #ifdef Rel10 if (phy_procedures_RN_eNB_TX(last_slot, next_slot, r_type) != 0 ) #endif - phy_procedures_eNB_TX(next_slot,phy_vars_eNB,abstraction_flag,r_type); + phy_procedures_eNB_TX(next_slot,phy_vars_eNB,abstraction_flag,r_type,phy_vars_rn); } if ((subframe_select(&phy_vars_eNB->lte_frame_parms,last_slot>>1)==SF_S) && ((last_slot&1)==0)){ diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index d94d67323075fff47c267d0b8f980b8396737ae7..901db1d5e459323c2e79d652ca43a286d4f54f82 100755 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -1279,7 +1279,8 @@ void phy_procedures_UE_TX(u8 next_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abs } } - LOG_D(PHY,"[UE %p] frame %d subframe %d : generate_prach %d, prach_cnt %d\n",phy_vars_ue,phy_vars_ue->frame,next_slot>>1,phy_vars_ue->generate_prach,phy_vars_ue->prach_cnt); + LOG_D(PHY,"[UE %d] frame %d subframe %d : generate_prach %d, prach_cnt %d\n", + phy_vars_ue->Mod_id,phy_vars_ue->frame,next_slot>>1,phy_vars_ue->generate_prach,phy_vars_ue->prach_cnt); phy_vars_ue->prach_cnt++; if (phy_vars_ue->prach_cnt==3) @@ -1542,7 +1543,7 @@ void phy_procedures_emos_UE_RX(PHY_VARS_UE *phy_vars_ue,u8 last_slot,u8 eNB_id) void restart_phy(PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag) { // u8 last_slot; - + u8 i; LOG_D(PHY,"[UE %d] frame %d, slot %d, restarting PHY!\n",phy_vars_ue->Mod_id,phy_vars_ue->frame); mac_xface->macphy_exit(""); // first_run = 1; @@ -1580,7 +1581,17 @@ void restart_phy(PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag) { phy_vars_ue->dlsch_ra_received[eNB_id] = 0; phy_vars_ue->dlsch_SI_errors[eNB_id] = 0; phy_vars_ue->dlsch_ra_errors[eNB_id] = 0; - phy_vars_ue->dlsch_mch_errors[eNB_id] = 0; + + phy_vars_ue->dlsch_mch_received[eNB_id] = 0; + for (i=0; i < MAX_MBSFN_AREA ; i ++){ + phy_vars_ue->dlsch_mch_received_sf[i][eNB_id] = 0; + phy_vars_ue->dlsch_mcch_received[i][eNB_id] = 0; + phy_vars_ue->dlsch_mtch_received[i][eNB_id] = 0; + phy_vars_ue->dlsch_mcch_errors[i][eNB_id] = 0; + phy_vars_ue->dlsch_mtch_errors[i][eNB_id] = 0; + phy_vars_ue->dlsch_mcch_trials[i][eNB_id] = 0; + phy_vars_ue->dlsch_mtch_trials[i][eNB_id] = 0; +} //phy_vars_ue->total_TBS[eNB_id] = 0; //phy_vars_ue->total_TBS_last[eNB_id] = 0; //phy_vars_ue->bitrate[eNB_id] = 0; @@ -2163,7 +2174,8 @@ int lte_ue_pdcch_procedures(u8 eNB_id,u8 last_slot, PHY_VARS_UE *phy_vars_ue,u8 } -int phy_procedures_UE_RX(u8 last_slot, PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,runmode_t mode,relaying_type_t r_type) { + int phy_procedures_UE_RX(u8 last_slot, PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,runmode_t mode, + relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn) { u16 l,m,n_symb; // int eNB_id = 0, @@ -2179,16 +2191,16 @@ int phy_procedures_UE_RX(u8 last_slot, PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abs u8 *rar; #endif int pmch_flag=0; - + u8 sync_area=255; int pmch_mcs=-1; - + u8 mcch_active=0; vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN); - //msg("UE_RX 1 last_slot %d \n",last_slot); #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[%s %d] Frame %d subframe %d: Doing phy_procedures_UE_RX(%d)\n", (r_type == multicast_relay) ? "RN/UE" : "UE", phy_vars_ue->Mod_id,phy_vars_ue->frame, last_slot>>1, last_slot); #endif + if (phy_vars_ue->lte_frame_parms.Ncp == 0) { // normal prefix pilot1 = 4; pilot2 = 7; @@ -2937,11 +2949,14 @@ int phy_procedures_UE_RX(u8 last_slot, PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abs }// l loop if (is_pmch_subframe(((last_slot>>1)==9?-1:0)+phy_vars_ue->frame,last_slot>>1,&phy_vars_ue->lte_frame_parms)) { + if ((last_slot%2)==1) { - LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Querying for PMCH demodulation\n", - phy_vars_ue->Mod_id,((last_slot>>1)==9?-1:0)+phy_vars_ue->frame,last_slot>>1); + LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Querying for PMCH demodulation(%d)\n", + phy_vars_ue->Mod_id,((last_slot>>1)==9?-1:0)+phy_vars_ue->frame,last_slot>>1,last_slot); #ifdef Rel10 - pmch_mcs = mac_xface->ue_query_mch(phy_vars_ue->Mod_id,((last_slot>>1)==9?-1:0)+phy_vars_ue->frame,last_slot>>1); + pmch_mcs = mac_xface->ue_query_mch(phy_vars_ue->Mod_id,((last_slot>>1)==9?-1:0)+phy_vars_ue->frame,last_slot>>1,eNB_id,&sync_area,&mcch_active); + if (phy_vars_rn) + phy_vars_rn->mch_avtive[last_slot>>1]=0; #else pmch_mcs=-1; #endif @@ -2990,11 +3005,24 @@ int phy_procedures_UE_RX(u8 last_slot, PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abs last_slot>>1, 0, 0,0); + if (mcch_active == 1) + phy_vars_ue->dlsch_mcch_trials[sync_area][0]++; + else + phy_vars_ue->dlsch_mtch_trials[sync_area][0]++; if (ret == (1+phy_vars_ue->dlsch_ue_MCH[0]->max_turbo_iterations)) { - phy_vars_ue->dlsch_mch_errors[0]++; - LOG_D(PHY,"number of errors: %d\n",phy_vars_ue->dlsch_mch_errors[0]); - LOG_D(PHY,"[UE %d] Frame %d, subframe %d: PMCH in error, not passing to L2 (TBS %d, iter %d,G %d)\n",phy_vars_ue->Mod_id,((last_slot>>1)==9?-1:0)+phy_vars_ue->frame,last_slot>>1,phy_vars_ue->dlsch_ue_MCH[0]->harq_processes[0]->TBS>>3,phy_vars_ue->dlsch_ue_MCH[0]->max_turbo_iterations,phy_vars_ue->dlsch_ue_MCH[0]->harq_processes[0]->G); + if (mcch_active == 1) + phy_vars_ue->dlsch_mcch_errors[sync_area][0]++; + else + phy_vars_ue->dlsch_mtch_errors[sync_area][0]++; + LOG_D(PHY,"[%s %d] Frame %d, subframe %d: PMCH in error (%d,%d), not passing to L2 (TBS %d, iter %d,G %d)\n", + (r_type == no_relay)? "UE": "RN/UE", phy_vars_ue->Mod_id, + ((last_slot>>1)==9?-1:0)+phy_vars_ue->frame,last_slot>>1, + phy_vars_ue->dlsch_mcch_errors[sync_area][0], + phy_vars_ue->dlsch_mtch_errors[sync_area][0], + phy_vars_ue->dlsch_ue_MCH[0]->harq_processes[0]->TBS>>3, + phy_vars_ue->dlsch_ue_MCH[0]->max_turbo_iterations, + phy_vars_ue->dlsch_ue_MCH[0]->harq_processes[0]->G); dump_mch(phy_vars_ue,0,phy_vars_ue->dlsch_ue_MCH[0]->harq_processes[0]->G,(last_slot>>1)); #ifdef DEBUG_DLSCH for (i=0;i<phy_vars_ue->dlsch_ue_MCH[0]->harq_processes[0]->TBS>>3;i++){ @@ -3006,11 +3034,53 @@ int phy_procedures_UE_RX(u8 last_slot, PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abs } else { #ifdef Rel10 - mac_xface->ue_send_mch_sdu(phy_vars_ue->Mod_id, - ((last_slot>>1)==9?-1:0)+phy_vars_ue->frame, - phy_vars_ue->dlsch_ue_MCH[0]->harq_processes[0]->b, - phy_vars_ue->dlsch_ue_MCH[0]->harq_processes[0]->TBS>>3, - 0); + if ((r_type == no_relay) || (mcch_active == 1)) { + mac_xface->ue_send_mch_sdu(phy_vars_ue->Mod_id, + ((last_slot>>1)==9?-1:0)+phy_vars_ue->frame, + phy_vars_ue->dlsch_ue_MCH[0]->harq_processes[0]->b, + phy_vars_ue->dlsch_ue_MCH[0]->harq_processes[0]->TBS>>3, + eNB_id,// not relevant in eMBMS context + sync_area); + /* for (i=0;i<phy_vars_ue->dlsch_ue_MCH[0]->harq_processes[0]->TBS>>3;i++) + msg("%2x.",phy_vars_ue->dlsch_ue_MCH[0]->harq_processes[0]->b[i]); + msg("\n"); + */ + + if (mcch_active == 1) + phy_vars_ue->dlsch_mcch_received[sync_area][0]++; + else + phy_vars_ue->dlsch_mtch_received[sync_area][0]++; + + + if (phy_vars_ue->dlsch_mch_received_sf[(last_slot>>1)%5][0] == 1 ){ + phy_vars_ue->dlsch_mch_received_sf[(last_slot>>1)%5][0]=0; + } else { + phy_vars_ue->dlsch_mch_received[0]+=1; + phy_vars_ue->dlsch_mch_received_sf[last_slot>>1][0]=1; + } + + } else if (r_type == multicast_relay) { // mcch is not active here + // only 1 harq process exists + // Fix me: this could be a pointer copy + memcpy (phy_vars_rn->dlsch_rn_MCH[last_slot>>1]->harq_processes[0]->b, + phy_vars_ue->dlsch_ue_MCH[0]->harq_processes[0]->b, + phy_vars_ue->dlsch_ue_MCH[0]->harq_processes[0]->TBS>>3); + // keep the tbs + phy_vars_rn->mch_avtive[last_slot>>1] = 1; + phy_vars_rn->sync_area[last_slot>>1] = sync_area; // this could also go the harq data struct + phy_vars_rn->dlsch_rn_MCH[last_slot>>1]->harq_processes[0]->TBS = phy_vars_ue->dlsch_ue_MCH[0]->harq_processes[0]->TBS; + phy_vars_rn->dlsch_rn_MCH[last_slot>>1]->harq_processes[0]->mcs = phy_vars_ue->dlsch_ue_MCH[0]->harq_processes[0]->mcs; + LOG_I(PHY,"[RN/UE %d] Frame %d subframe %d: store the MCH PDU for MBSFN sync area %d (MCS %d, TBS %d)\n", + phy_vars_ue->Mod_id,frame,last_slot>>1,sync_area, + phy_vars_rn->dlsch_rn_MCH[last_slot>>1]->harq_processes[0]->mcs, + phy_vars_rn->dlsch_rn_MCH[last_slot>>1]->harq_processes[0]->TBS>>3); +#ifdef DEBUG_PHY + for (i=0;i<phy_vars_rn->dlsch_rn_MCH[last_slot>>1]->harq_processes[0]->TBS>>3;i++) + msg("%2x.",phy_vars_rn->dlsch_rn_MCH[last_slot>>1]->harq_processes[0]->b[i]); + msg("\n"); +#endif + } else + LOG_W(PHY,"[UE %d] Frame %d: not supported option\n",phy_vars_ue->Mod_id,frame); #endif } } @@ -3018,7 +3088,7 @@ int phy_procedures_UE_RX(u8 last_slot, PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abs } vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT); return (0); -} + } #ifdef Rel10 int phy_procedures_RN_UE_RX(u8 last_slot, u8 next_slot, relaying_type_t r_type) { @@ -3032,7 +3102,7 @@ int phy_procedures_RN_UE_RX(u8 last_slot, u8 next_slot, relaying_type_t r_type) if (last_slot > 12) do_proc = 0; // do nothing else // SF#1, SF#2, SF3, SF#3, SF#4, SF#5, SF#6(do rx slot 12) - do_proc =multicast_relay ; // do PHY procedures UE RX + do_proc = multicast_relay ; // do PHY procedures UE RX break; default: // should'not be here LOG_W(PHY,"Not supported relay type %d, do nothing \n", r_type); @@ -3042,7 +3112,8 @@ int phy_procedures_RN_UE_RX(u8 last_slot, u8 next_slot, relaying_type_t r_type) return do_proc; } #endif - void phy_procedures_UE_lte(u8 last_slot, u8 next_slot, PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,runmode_t mode, relaying_type_t r_type) { + void phy_procedures_UE_lte(u8 last_slot, u8 next_slot, PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,runmode_t mode, + relaying_type_t r_type, PHY_VARS_RN *phy_vars_rn) { #undef DEBUG_PHY_PROC @@ -3073,7 +3144,7 @@ int phy_procedures_RN_UE_RX(u8 last_slot, u8 next_slot, relaying_type_t r_type) #ifdef Rel10 if (phy_procedures_RN_UE_RX(last_slot, next_slot, r_type) != 0 ) #endif - phy_procedures_UE_RX(last_slot,phy_vars_ue,eNB_id,abstraction_flag,mode,r_type); + phy_procedures_UE_RX(last_slot,phy_vars_ue,eNB_id,abstraction_flag,mode,r_type,phy_vars_rn); #ifdef EMOS phy_procedures_emos_UE_RX(phy_vars_ue,last_slot,eNB_id); #endif @@ -3087,7 +3158,7 @@ int phy_procedures_RN_UE_RX(u8 last_slot, u8 next_slot, relaying_type_t r_type) #ifdef Rel10 if (phy_procedures_RN_UE_RX(last_slot, next_slot, r_type) != 0 ) #endif - phy_procedures_UE_RX(last_slot,phy_vars_ue,eNB_id,abstraction_flag,mode, r_type); + phy_procedures_UE_RX(last_slot,phy_vars_ue,eNB_id,abstraction_flag,mode,r_type,phy_vars_rn); } #ifdef OPENAIR2 diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index a70c982778ea798f66b66b8574dad2d505e12cbf..67e3172cee5592834ed17ae1e1aa4ccb4cf6e781 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -201,9 +201,11 @@ int rrc_mac_config_req(u8 Mod_id,u8 eNB_flag,u8 UE_id,u8 eNB_index, if (mbsfn_SubframeConfigList != NULL) { if (eNB_flag == 1) { + LOG_I(MAC,"[eNB %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", Mod_id, mbsfn_SubframeConfigList->list.count); + eNB_mac_inst[Mod_id].num_sf_allocation_pattern= mbsfn_SubframeConfigList->list.count; for (i=0; i<mbsfn_SubframeConfigList->list.count; i++) { eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[i] = mbsfn_SubframeConfigList->list.array[i]; - LOG_I(MAC, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %ld\n", i, + LOG_I(MAC, "[eNB %d][CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", Mod_id, i, eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]); } #ifdef Rel10 @@ -211,8 +213,10 @@ int rrc_mac_config_req(u8 Mod_id,u8 eNB_flag,u8 UE_id,u8 eNB_index, #endif } else { // UE + LOG_I(MAC,"[UE %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", Mod_id, mbsfn_SubframeConfigList->list.count); + UE_mac_inst[Mod_id].num_sf_allocation_pattern= mbsfn_SubframeConfigList->list.count; for (i=0; i<mbsfn_SubframeConfigList->list.count; i++) { - LOG_I(MAC, "[UE %d] Configuring MBSFN_SubframeConfig from received SIB2 \n", Mod_id); + LOG_I(MAC, "[UE %d] Configuring MBSFN_SubframeConfig %d from received SIB2 \n", Mod_id, i); UE_mac_inst[Mod_id].mbsfn_SubframeConfig[i] = mbsfn_SubframeConfigList->list.array[i]; // LOG_I("[UE %d] MBSFN_SubframeConfig[%d] pattern is %ld\n", Mod_id, // UE_mac_inst[Mod_id].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]); @@ -223,19 +227,22 @@ int rrc_mac_config_req(u8 Mod_id,u8 eNB_flag,u8 UE_id,u8 eNB_index, #ifdef Rel10 if (mbsfn_AreaInfoList != NULL) { if (eNB_flag == 1) { - LOG_I(MAC, "[CONFIG] Number of MBSFN Area Info in the list %d\n", mbsfn_AreaInfoList->list.count); + // One eNB could be part of multiple mbsfn syc area, this could change over time so reset each time + LOG_I(MAC,"[eNB %d][CONFIG] Received %d MBSFN Area Info\n", Mod_id, mbsfn_AreaInfoList->list.count); + eNB_mac_inst[Mod_id].num_active_mbsfn_area = mbsfn_AreaInfoList->list.count; for (i =0; i< mbsfn_AreaInfoList->list.count; i++) { eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i] = mbsfn_AreaInfoList->list.array[i]; - LOG_I(MAC, "[CONFIG] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n", i, + LOG_I(MAC,"[eNB %d][CONFIG] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n", Mod_id,i, eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9); mac_xface->phy_config_sib13_eNB(Mod_id,i,eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9); } } else { // UE - LOG_I(MAC, "[UE %d] Configuring mbsfn_AreaInfo from received SIB13 \n", Mod_id); + LOG_I(MAC,"[UE %d][CONFIG] Received %d MBSFN Area Info\n", Mod_id, mbsfn_AreaInfoList->list.count); + UE_mac_inst[Mod_id].num_active_mbsfn_area = mbsfn_AreaInfoList->list.count; for (i =0; i< mbsfn_AreaInfoList->list.count; i++) { UE_mac_inst[Mod_id].mbsfn_AreaInfo[i] = mbsfn_AreaInfoList->list.array[i]; - LOG_I(MAC, "[UE %d] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n",Mod_id, i, + LOG_I(MAC,"[UE %d] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n",Mod_id, i, UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9); mac_xface->phy_config_sib13_ue(Mod_id,eNB_index,i,UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9); } diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index 2d3bff138384595814fed914f9d21ebbcc0f7b07..acfdb62da3ee074377367daa4bf65f871f0f7783 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -297,6 +297,10 @@ typedef struct { s8 payload[SCH_PAYLOAD_SIZE_MAX]; u16 Pdu_size; uint8_t mcs; + uint8_t sync_area; + uint8_t msi_active; + uint8_t mcch_active; + uint8_t mtch_active; } __attribute__ ((__packed__)) MCH_PDU; /*! \brief Uplink SCH PDU Structure @@ -607,21 +611,27 @@ typedef struct{ u8 bcch_active; /// MBSFN SubframeConfig struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; + /// number of subframe allocation pattern available for MBSFN sync area + u8 num_sf_allocation_pattern; #ifdef Rel10 /// MBMS Flag u8 MBMS_flag; /// Outgoing MCCH pdu for PHY MCCH_PDU MCCH_pdu; /// MCCH active flag + u8 msi_active; + /// MCCH active flag u8 mcch_active; + /// MTCH active flag + u8 mtch_active; + /// number of active MBSFN area + u8 num_active_mbsfn_area; /// MBSFN Area Info struct MBSFN_AreaInfo_r9 *mbsfn_AreaInfo[MAX_MBSFN_AREA]; - /// PMCH Config struct PMCH_Config_r9 *pmch_Config[MAX_PMCH_perMBSFN]; /// MBMS session info list struct MBMS_SessionInfoList_r9 *mbms_SessionList[MAX_PMCH_perMBSFN]; - /// Outgoing MCH pdu for PHY MCH_PDU MCH_pdu; #endif @@ -766,8 +776,11 @@ typedef struct{ u8 power_backoff_db[NUMBER_OF_eNB_MAX]; /// MBSFN_Subframe Configuration struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; - + /// number of subframe allocation pattern available for MBSFN sync area + u8 num_sf_allocation_pattern; #ifdef Rel10 + /// number of active MBSFN area + u8 num_active_mbsfn_area; /// MBSFN Area Info struct MBSFN_AreaInfo_r9 *mbsfn_AreaInfo[MAX_MBSFN_AREA]; /// PMCH Config @@ -890,6 +903,20 @@ void schedule_SI(u8 Mod_id,u32 frame,u8 *nprb,unsigned int *nCCE); */ int schedule_MBMS(unsigned char Mod_id,u32 frame, u8 subframe); +/** \brief check the mapping between sf allocation and sync area, Currently only supports 1:1 mapping +@param Mod_id Instance ID of eNB +@param mbsfn_sync_area index of mbsfn sync area +@param[out] index of sf pattern +*/ +s8 get_mbsfn_sf_alloction (unsigned char Mod_id, u8 mbsfn_sync_area); + +/** \brief check the mapping between sf allocation and sync area, Currently only supports 1:1 mapping +@param Mod_id Instance ID of eNB +@param mbsfn_sync_area index of mbsfn sync area +@param eNB_index index of eNB +@param[out] index of sf pattern +*/ +s8 ue_get_mbsfn_sf_alloction (unsigned char Mod_id, u8 mbsfn_sync_area, unsigned char eNB_index); /** \brief top ULSCH Scheduling for TDD (config 1-6). @param Mod_id Instance ID of eNB @@ -1152,15 +1179,19 @@ void ue_send_sdu(u8 Mod_id, u32 frame, u8 *sdu,u16 sdu_len,u8 CH_index); @param sdu Pointer to transport block @param sdu_len Length of transport block @param eNB_index Index of attached eNB +@param sync_area the index of MBSFN sync area */ -void ue_send_mch_sdu(u8 Mod_id,u32 frame,u8 *sdu,u16 sdu_len,u8 eNB_index) ; +void ue_send_mch_sdu(u8 Mod_id,u32 frame,u8 *sdu,u16 sdu_len,u8 eNB_index,u8 sync_area) ; /*\brief Function to check if UE PHY needs to decode MCH for MAC. @param Mod_id Index of protocol instance @param frame Index of frame @param subframe Index of subframe +@param eNB_index index of eNB for this MCH +@param[out] sync_area return the sync area +@param[out] mcch_active flag indicating whether this MCCH is active in this SF */ -int ue_query_mch(uint8_t Mod_id,uint32_t frame,uint32_t subframe); +int ue_query_mch(uint8_t Mod_id,uint32_t frame,uint32_t subframe, uint8_t eNB_index, uint8_t *sync_area, uint8_t *mcch_active); #endif diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index f75227b4c7dd4cb92e2eaa6118d14aad8a58b436..9f6fa95b4bf5a967bb334671d5c6b47b3afed9a6 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -265,7 +265,7 @@ void terminate_ra_proc(u8 Mod_id,u32 frame,u16 rnti,unsigned char *msg3, u16 msg } if (Is_rrc_registered == 1) - mac_rrc_data_ind(Mod_id,frame,CCCH,(char *)payload_ptr,rx_lengths[0],1,Mod_id); + mac_rrc_data_ind(Mod_id,frame,CCCH,(char *)payload_ptr,rx_lengths[0],1,Mod_id,0); // add_user. This is needed to have the rnti for configuring UE (PHY). The UE is removed if RRC // doesn't provide a CCCH SDU @@ -981,7 +981,8 @@ void schedule_SI(unsigned char Mod_id,u32 frame, unsigned char *nprb,unsigned in BCCH,1, (char*)&eNB_mac_inst[Mod_id].BCCH_pdu.payload[0], 1, - Mod_id); + Mod_id, + 0); // not used in this case if (bcch_sdu_length > 0) { LOG_D(MAC,"[eNB %d] Frame %d : BCCH->DLSCH, Received %d bytes \n",Mod_id,frame,bcch_sdu_length); @@ -1069,16 +1070,31 @@ void schedule_SI(unsigned char Mod_id,u32 frame, unsigned char *nprb,unsigned in } eNB_mac_inst[Mod_id].bcch_active=0; *nprb=0; - *nCCE=0; + *nCCE=0; + //LOG_D(MAC,"[eNB %d] Frame %d : BCCH not active \n",Mod_id,frame); + } #ifdef Rel10 +s8 get_mbsfn_sf_alloction (unsigned char Mod_id, u8 mbsfn_sync_area){ + // currently there is one-to-one mapping between sf allocation pattern and sync area + if (mbsfn_sync_area > MAX_MBSFN_AREA){ + LOG_W(MAC,"[eNB %d] MBSFN synchronization area %d out of range\n ", Mod_id, mbsfn_sync_area); + return -1; + } + else if (eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[mbsfn_sync_area] != NULL) + return mbsfn_sync_area; + else { + LOG_W(MAC,"[eNB %d] MBSFN Subframe Config pattern %d not found \n ", Mod_id, mbsfn_sync_area); + return -1; + } +} int schedule_MBMS(unsigned char Mod_id,u32 frame, u8 subframe) { int mcch_flag=0,mtch_flag=0, msi_flag=0; - int mbsfn_period = 1<<(eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->radioframeAllocationPeriod); - int mcch_period = 32<<(eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_RepetitionPeriod_r9); + int mbsfn_period =0;// 1<<(eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->radioframeAllocationPeriod); + int mcch_period = 0;//32<<(eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_RepetitionPeriod_r9); int mch_scheduling_period = 8<<(eNB_mac_inst[Mod_id].pmch_Config[0]->mch_SchedulingPeriod_r9); unsigned char mcch_sdu_length; unsigned char header_len_mcch=0,header_len_msi=0,header_len_mtch=0, header_len_mtch_temp=0, header_len_mcch_temp=0, header_len_msi_temp=0; @@ -1087,179 +1103,206 @@ int schedule_MBMS(unsigned char Mod_id,u32 frame, u8 subframe) { u16 TBS,j,padding=0,post_padding=0; mac_rlc_status_resp_t rlc_status; int num_mtch; - int msi_length,i; + int msi_length,i,k; unsigned char sdu_lcids[11], num_sdus=0, offset=0; u16 sdu_lengths[11], sdu_length_total=0; unsigned char mch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; // check the max value, this is for dlsch only - switch (eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->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; - } + eNB_mac_inst[Mod_id].MCH_pdu.Pdu_size=0; + + for (i=0; + i< eNB_mac_inst[Mod_id].num_active_mbsfn_area; + i++ ){ + // assume, that there is always a mapping + if ((j=get_mbsfn_sf_alloction(Mod_id,i)) == -1) + return 0; + + mbsfn_period = 1<<(eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->radioframeAllocationPeriod); + mcch_period = 32<<(eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9); + msi_pos=0; ii=0; + LOG_D(MAC,"[eNB %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)\n", + Mod_id,frame, subframe,i,eNB_mac_inst[Mod_id].num_active_mbsfn_area, + j,eNB_mac_inst[Mod_id].num_sf_allocation_pattern,mbsfn_period,mcch_period); - // 1st: Check the MBSFN subframes from SIB2 info (SF allocation pattern 0, max 8 patterns exist) - if (frame % mbsfn_period == eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->radioframeAllocationOffset){ // MBSFN frame - if (eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame){// one-frame format + + switch (eNB_mac_inst[Mod_id].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; + } + + // 1st: Check the MBSFN subframes from SIB2 info (SF allocation pattern i, max 8 non-overlapping patterns exist) + if (frame % mbsfn_period == eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->radioframeAllocationOffset){ // MBSFN frame + if (eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame){// one-frame format // Find the first subframe in this MCH to transmit MSI - if (frame % mch_scheduling_period == eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->radioframeAllocationOffset ) { - while (ii == 0) { - ii = eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & (0x80>>msi_pos); - msi_pos++; + if (frame % mch_scheduling_period == eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->radioframeAllocationOffset ) { + while (ii == 0) { + ii = eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & (0x80>>msi_pos); + msi_pos++; + } + //LOG_D(MAC,"[eNB %d] Frame %d subframe %d : sync area %d sf allocation pattern %d sf alloc %x msi pos is %d \n", Mod_id,frame, subframe,i,j,eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0], msi_pos); } - } // Check if the subframe is for MSI, MCCH or MTCHs and Set the correspoding flag to 1 - switch (subframe) { - case 1: - if (mac_xface->lte_frame_parms->frame_type == FDD) { - if ((eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) { - if (msi_pos == 1) - msi_flag = 1; - if ( (frame % mcch_period == eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_Offset_r9) && - ((eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) ) - mcch_flag = 1; - mtch_flag = 1; + switch (subframe) { + case 1: + if (mac_xface->lte_frame_parms->frame_type == FDD) { + if ((eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) { + if (msi_pos == 1) + msi_flag = 1; + if ( (frame % mcch_period == eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && + ((eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) ) + mcch_flag = 1; + mtch_flag = 1; + } } - } - break; + break; - case 2: - if (mac_xface->lte_frame_parms->frame_type == FDD){ - if ((eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) { - if (msi_pos == 2) - msi_flag = 1; - if ( (frame % mcch_period == eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_Offset_r9) && - ((eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) ) - mcch_flag = 1; - mtch_flag = 1; + case 2: + if (mac_xface->lte_frame_parms->frame_type == FDD){ + if ((eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) { + if (msi_pos == 2) + msi_flag = 1; + if ( (frame % mcch_period == eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && + ((eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) ) + mcch_flag = 1; + mtch_flag = 1; + } } - } - break; - - case 3: - if (mac_xface->lte_frame_parms->frame_type == TDD){// TDD - if ((eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) { - if (msi_pos == 1) - msi_flag = 1; - if ( (frame % mcch_period == eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_Offset_r9) && - ((eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) ) - mcch_flag = 1; - mtch_flag = 1; + break; + + case 3: + if (mac_xface->lte_frame_parms->frame_type == TDD){// TDD + if ((eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) { + if (msi_pos == 1) + msi_flag = 1; + if ( (frame % mcch_period == eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && + ((eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) ) + mcch_flag = 1; + mtch_flag = 1; + } } - } - else {// FDD - if ((eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) { - if (msi_pos == 3) - msi_flag = 1; - if ( (frame % mcch_period == eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_Offset_r9) && - ((eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) ) - mcch_flag = 1; - mtch_flag = 1; + else {// FDD + if ((eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) { + if (msi_pos == 3) + msi_flag = 1; + if ( (frame % mcch_period == eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && + ((eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) ) + mcch_flag = 1; + mtch_flag = 1; + } } - } - break; - - case 4: - if (mac_xface->lte_frame_parms->frame_type == TDD){ - if ((eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) { - if (msi_pos == 2) - msi_flag = 1; - if ( (frame % mcch_period == eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_Offset_r9) && - ((eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) ) - mcch_flag = 1; - mtch_flag = 1; + break; + + case 4: + if (mac_xface->lte_frame_parms->frame_type == TDD){ + if ((eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) { + if (msi_pos == 2) + msi_flag = 1; + if ( (frame % mcch_period == eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && + ((eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) ) + mcch_flag = 1; + mtch_flag = 1; + } } - } - break; - - case 6: - if (mac_xface->lte_frame_parms->frame_type == FDD){ - if ((eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) { - if (msi_pos == 4) - msi_flag = 1; - if ( (frame % mcch_period == eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_Offset_r9) && - ((eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) ) - mcch_flag = 1; - mtch_flag = 1; + break; + + case 6: + if (mac_xface->lte_frame_parms->frame_type == FDD){ + if ((eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) { + if (msi_pos == 4) + msi_flag = 1; + if ( (frame % mcch_period == eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && + ((eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) ) + mcch_flag = 1; + mtch_flag = 1; + } } - } break; - case 7: - if (mac_xface->lte_frame_parms->frame_type == TDD){ // TDD - if ((eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) { - if (msi_pos == 3) - msi_flag = 1; - if ( (frame % mcch_period == eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_Offset_r9) && - ((eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) ) - mcch_flag = 1; - mtch_flag = 1; + case 7: + if (mac_xface->lte_frame_parms->frame_type == TDD){ // TDD + if ((eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) { + if (msi_pos == 3) + msi_flag = 1; + if ( (frame % mcch_period == eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && + ((eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) ) + mcch_flag = 1; + mtch_flag = 1; } - } - else {// FDD - if ((eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) { - if (msi_pos == 5) - msi_flag = 1; - if ( (frame % mcch_period == eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_Offset_r9) && - ((eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) ) - mcch_flag = 1; - mtch_flag = 1; } - } - break; - - case 8: - if (mac_xface->lte_frame_parms->frame_type == TDD){ //TDD - if ((eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) { - if (msi_pos == 4) - msi_flag = 1; - if ( (frame % mcch_period == eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_Offset_r9) && - ((eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) ) - mcch_flag = 1; - mtch_flag = 1; + else {// FDD + if ((eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) { + if (msi_pos == 5) + msi_flag = 1; + if ( (frame % mcch_period == eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && + ((eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) ) + mcch_flag = 1; + mtch_flag = 1; + } } - } - else{ // FDD - if ((eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) { - if (msi_pos == 6) - msi_flag = 1; - if ( (frame % mcch_period == eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_Offset_r9) && - ((eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) ) - mcch_flag = 1; - mtch_flag = 1; + break; + + case 8: + if (mac_xface->lte_frame_parms->frame_type == TDD){ //TDD + if ((eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) { + if (msi_pos == 4) + msi_flag = 1; + if ( (frame % mcch_period == eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && + ((eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) ) + mcch_flag = 1; + mtch_flag = 1; + } } - } - break; - - case 9: - if (mac_xface->lte_frame_parms->frame_type == TDD){ - if ((eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) { - if (msi_pos == 5) - msi_flag = 1; - if ( (frame % mcch_period == eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_Offset_r9) && - ((eNB_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) ) - mcch_flag = 1; - mtch_flag = 1; + else{ // FDD + if ((eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) { + if (msi_pos == 6) + msi_flag = 1; + if ( (frame % mcch_period == eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && + ((eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) ) + mcch_flag = 1; + mtch_flag = 1; + } } + break; + + case 9: + if (mac_xface->lte_frame_parms->frame_type == TDD){ + if ((eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) { + if (msi_pos == 5) + msi_flag = 1; + if ( (frame % mcch_period == eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && + ((eNB_mac_inst[Mod_id].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 + // sf allocation is non-overlapping + if ((msi_flag==1) || (mcch_flag==1) || (mtch_flag==1)){ + LOG_D(MAC,"[eNB %d] Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n", + Mod_id, frame, subframe,i,j,msi_flag,mcch_flag,mtch_flag); + break; } - break; - }// end switch - } - else {// four-frame format + } + else {// four-frame format + } } - } - + } // end of for loop + eNB_mac_inst[Mod_id].msi_active=0; + eNB_mac_inst[Mod_id].mcch_active=0; + eNB_mac_inst[Mod_id].mtch_active=0; // Calculate the mcs if ((msi_flag==1) || (mcch_flag==1)) { eNB_mac_inst[Mod_id].MCH_pdu.mcs = mcch_mcs; @@ -1290,8 +1333,8 @@ int schedule_MBMS(unsigned char Mod_id,u32 frame, u8 subframe) { //Header for MTCHs num_mtch = eNB_mac_inst[Mod_id].mbms_SessionList[0]->list.count; - for (i=0;i<num_mtch;i++) { // loop for all session in this MCH (MCH[0]) at this moment - ((MSI_ELEMENT *) msi_ptr)->lcid = eNB_mac_inst[Mod_id].mbms_SessionList[0]->list.array[i]->logicalChannelIdentity_r9;//mtch_lcid; + for (k=0;k<num_mtch;k++) { // loop for all session in this MCH (MCH[0]) at this moment + ((MSI_ELEMENT *) msi_ptr)->lcid = eNB_mac_inst[Mod_id].mbms_SessionList[0]->list.array[k]->logicalChannelIdentity_r9;//mtch_lcid; ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; // last subframe of this mtch (only one mtch now) ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xB; msi_ptr+=sizeof(MSI_ELEMENT); @@ -1316,18 +1359,22 @@ int schedule_MBMS(unsigned char Mod_id,u32 frame, u8 subframe) { sdu_length_total += sdu_lengths[num_sdus]; LOG_I(MAC,"[eNB %d] Create %d bytes for MSI\n",Mod_id,sdu_lengths[num_sdus]); num_sdus++; + eNB_mac_inst[Mod_id].msi_active=1; } // there is MCCH if (mcch_flag == 1) { - LOG_D(MAC,"Scheduler: MCCH MESSAGE is transmitted in this subframe %d \n", subframe); + LOG_D(MAC,"[eNB %d] Frame %d Subframe %d: Schedule MCCH MESSAGE (area %d, sfAlloc %d)\n", + Mod_id,frame, subframe, i, j); mcch_sdu_length = mac_rrc_data_req(Mod_id, frame, MCCH,1, (char*)&eNB_mac_inst[Mod_id].MCCH_pdu.payload[0], 1,// this is eNB - Mod_id); + Mod_id, // index + i); // this is the mbsfn sync area index + if (mcch_sdu_length > 0) { LOG_D(MAC,"[eNB %d] Frame %d subframe %d : MCCH->MCH, Received %d bytes from RRC \n",Mod_id,frame,subframe,mcch_sdu_length); @@ -1358,24 +1405,27 @@ int schedule_MBMS(unsigned char Mod_id,u32 frame, u8 subframe) { sdu_length_total += sdu_lengths[num_sdus]; LOG_D(MAC,"[eNB %d] Got %d bytes for MCCH from RRC \n",Mod_id,sdu_lengths[num_sdus]); num_sdus++; - } - eNB_mac_inst[Mod_id].mcch_active=0; + } } - + TBS = mac_xface->get_TBS_DL(eNB_mac_inst[Mod_id].MCH_pdu.mcs, mac_xface->lte_frame_parms->N_RB_DL); +#ifdef Rel10 + // do not let mcch and mtch multiplexing when relaying is active + // for sync area 1, so not transmit data + //if ((i == 0) && ((eNB_mac_inst[Mod_id].MBMS_flag != multicast_relay) || (eNB_mac_inst[Mod_id].mcch_active==0))) { +#endif // there is MTCHs, loop if there are more than 1 if (mtch_flag == 1) { // Calculate TBS - /* if ((msi_flag==1) || (mcch_flag==1)) { - TBS = mac_xface->get_TBS(mcch_mcs, mac_xface->lte_frame_parms->N_RB_DL); - } - else { // only MTCH in this subframe - TBS = mac_xface->get_TBS(eNB_mac_inst[Mod_id].pmch_Config[0]->dataMCS_r9, mac_xface->lte_frame_parms->N_RB_DL); - } + /* if ((msi_flag==1) || (mcch_flag==1)) { + TBS = mac_xface->get_TBS(mcch_mcs, mac_xface->lte_frame_parms->N_RB_DL); + } + else { // only MTCH in this subframe + TBS = mac_xface->get_TBS(eNB_mac_inst[Mod_id].pmch_Config[0]->dataMCS_r9, mac_xface->lte_frame_parms->N_RB_DL); + } */ - TBS = mac_xface->get_TBS_DL(eNB_mac_inst[Mod_id].MCH_pdu.mcs, mac_xface->lte_frame_parms->N_RB_DL); - // get MTCH data from RLC (like for DTCH) - LOG_D(MAC,"[eNB %d] Frame %d : MTCH data is transmitted on subframe %d\n",Mod_id,frame,subframe); + // get MTCH data from RLC (like for DTCH) + LOG_D(MAC,"[eNB %d] Frame %d subframe %d: Schedule MTCH (area %d, sfAlloc %d)\n",Mod_id,frame,subframe,i,j); header_len_mtch = 3; LOG_D(MAC,"[eNB %d], Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n", @@ -1384,7 +1434,7 @@ int schedule_MBMS(unsigned char Mod_id,u32 frame, u8 subframe) { rlc_status = mac_rlc_status_ind(Mod_id,frame,1,RLC_MBMS_YES,MTCH+ (maxDRB + 3) * MAX_MOBILES_PER_RG, TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch); - printf("frame %d, subframe %d, rlc_status.bytes_in_buffer is %d\n",frame,subframe, rlc_status.bytes_in_buffer); + //printf("frame %d, subframe %d, rlc_status.bytes_in_buffer is %d\n",frame,subframe, rlc_status.bytes_in_buffer); if (rlc_status.bytes_in_buffer >0) { LOG_I(MAC,"[eNB %d][MBMS USER-PLANE], Frame %d, MTCH->MCH, Requesting %d bytes from RLC (header len mtch %d)\n", @@ -1395,6 +1445,7 @@ int schedule_MBMS(unsigned char Mod_id,u32 frame, u8 subframe) { (char*)&mch_buffer[sdu_length_total]); //sdu_lengths[num_sdus] = mac_rlc_data_req(Mod_id,frame, RLC_MBMS_NO, MTCH+(MAX_NUM_RB*(NUMBER_OF_UE_MAX+1)), (char*)&mch_buffer[sdu_length_total]); LOG_I(MAC,"[eNB %d][MBMS USER-PLANE] Got %d bytes for MTCH %d\n",Mod_id,sdu_lengths[num_sdus],MTCH); + eNB_mac_inst[Mod_id].mtch_active=1; sdu_lcids[num_sdus] = MTCH; sdu_length_total += sdu_lengths[num_sdus]; if (sdu_lengths[num_sdus] < 128) @@ -1405,7 +1456,9 @@ int schedule_MBMS(unsigned char Mod_id,u32 frame, u8 subframe) { header_len_mtch = 0; } } - +#ifdef Rel10 + // } +#endif // FINAL STEP: Prepare and multiplexe MSI, MCCH and MTCHs if ((sdu_length_total + header_len_msi + header_len_mcch + header_len_mtch) >0) { // Adjust the last subheader @@ -1450,8 +1503,13 @@ int schedule_MBMS(unsigned char Mod_id,u32 frame, u8 subframe) { padding, post_padding); - LOG_D(MAC," MCS for this sf is %d\n", eNB_mac_inst[Mod_id].MCH_pdu.mcs); - + eNB_mac_inst[Mod_id].MCH_pdu.Pdu_size=TBS; + eNB_mac_inst[Mod_id].MCH_pdu.sync_area=i; + eNB_mac_inst[Mod_id].MCH_pdu.msi_active= eNB_mac_inst[Mod_id].msi_active; + eNB_mac_inst[Mod_id].MCH_pdu.mcch_active= eNB_mac_inst[Mod_id].mcch_active; + eNB_mac_inst[Mod_id].MCH_pdu.mtch_active= eNB_mac_inst[Mod_id].mtch_active; + LOG_D(MAC," MCS for this sf is %d (mcch active %d, mtch active %d)\n", eNB_mac_inst[Mod_id].MCH_pdu.mcs, + eNB_mac_inst[Mod_id].MCH_pdu.mcch_active,eNB_mac_inst[Mod_id].MCH_pdu.mtch_active ); LOG_I(MAC,"[eNB %d][MBMS USER-PLANE ] Generate header : sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,padding %d,post_padding %d (mcs %d, TBS %d), header MTCH %d, header MCCH %d, header MSI %d\n", Mod_id,sdu_length_total,num_sdus,sdu_lengths[0],sdu_lcids[0],offset,padding,post_padding,eNB_mac_inst[Mod_id].MCH_pdu.mcs,TBS,header_len_mtch, header_len_mcch, header_len_msi); // copy SDU to mch_pdu after the MAC Header @@ -1459,7 +1517,7 @@ int schedule_MBMS(unsigned char Mod_id,u32 frame, u8 subframe) { // filling remainder of MCH with random data if necessery for (j=0;j<(TBS-sdu_length_total-offset);j++) eNB_mac_inst[Mod_id].MCH_pdu.payload[offset+sdu_length_total+j] = (char)(taus()&0xff); - + #if defined(USER_MODE) && defined(OAI_EMU) /* Tracing of PDU is done on UE side */ if (oai_emulation.info.opt_enabled) @@ -1476,6 +1534,11 @@ int schedule_MBMS(unsigned char Mod_id,u32 frame, u8 subframe) { return 1; } else { + eNB_mac_inst[Mod_id].MCH_pdu.Pdu_size=0; + eNB_mac_inst[Mod_id].MCH_pdu.sync_area=0; + eNB_mac_inst[Mod_id].MCH_pdu.msi_active=0; + eNB_mac_inst[Mod_id].MCH_pdu.mcch_active=0; + eNB_mac_inst[Mod_id].MCH_pdu.mtch_active=0; // for testing purpose, fill with random data //for (j=0;j<(TBS-sdu_length_total-offset);j++) // eNB_mac_inst[Mod_id].MCH_pdu.payload[offset+sdu_length_total+j] = (char)(taus()&0xff); @@ -1494,7 +1557,7 @@ int schedule_MBMS(unsigned char Mod_id,u32 frame, u8 subframe) { MCH_PDU *get_mch_sdu(uint8_t Mod_id,uint32_t frame, uint32_t subframe) { // eNB_mac_inst[Mod_id].MCH_pdu.mcs=0; - LOG_D(MAC," MCH_pdu.mcs is %d\n", eNB_mac_inst[Mod_id].MCH_pdu.mcs); + //LOG_D(MAC," MCH_pdu.mcs is %d\n", eNB_mac_inst[Mod_id].MCH_pdu.mcs); return(&eNB_mac_inst[Mod_id].MCH_pdu); } @@ -1534,7 +1597,8 @@ void schedule_RA(unsigned char Mod_id,u32 frame, unsigned char subframe,unsigned CCCH,1, (char*)&eNB_mac_inst[Mod_id].CCCH_pdu.payload[0], 1, - Mod_id); + Mod_id, + 0); // not used in this case if (rrc_sdu_length == -1) mac_xface->macphy_exit("[MAC][eNB Scheduler] CCCH not allocated\n"); else { @@ -2585,7 +2649,7 @@ void fill_DLSCH_dci(unsigned char Mod_id,u32 frame, unsigned char subframe,u32 R // printf("BCCH check\n"); if (eNB_mac_inst[Mod_id].bcch_active == 1) { eNB_mac_inst[Mod_id].bcch_active = 0; - + LOG_D(MAC,"[eNB %d] Frame %d subframe %d: BCCH active\n", Mod_id, frame, subframe); // randomize frequency allocation for SI first_rb = (unsigned char)(taus()%(mac_xface->lte_frame_parms->N_RB_DL-4)); if (mac_xface->lte_frame_parms->frame_type == TDD) { diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 8934acb3115faf1fd94f2bab6d1d34f2b7a5b2b5..5bd0d904aca32d23f983e2a49e292e8fe5d181a1 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -354,7 +354,7 @@ void ue_send_sdu(u8 Mod_id,u32 frame,u8 *sdu,u16 sdu_len,u8 eNB_index) { mac_rrc_data_ind(Mod_id, frame, CCCH, - (char *)payload_ptr,rx_lengths[i],0,eNB_index); + (char *)payload_ptr,rx_lengths[i],0,eNB_index,0); } else if (rx_lcids[i] == DCCH) { @@ -418,7 +418,8 @@ void ue_decode_si(u8 Mod_id,u32 frame, u8 eNB_index, void *pdu,u16 len) { (char *)pdu, len, 0, - eNB_index); + eNB_index, + 0); vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_OUT); } @@ -469,24 +470,24 @@ unsigned char *parse_mch_header(unsigned char *mac_header, } // this function is for sending mch_sdu from phy to mac -void ue_send_mch_sdu(u8 Mod_id, u32 frame, u8 *sdu, u16 sdu_len, u8 eNB_index) { +void ue_send_mch_sdu(u8 Mod_id, u32 frame, u8 *sdu, u16 sdu_len, u8 eNB_index, u8 sync_area) { unsigned char num_sdu, i, *payload_ptr; unsigned char rx_lcids[NB_RB_MAX]; unsigned short rx_lengths[NB_RB_MAX]; // vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_MCH_SDU, VCD_FUNCTION_IN); - LOG_I(MAC,"[UE %d] Frame %d : entering ue_send_mch_sdu\n",Mod_id,frame); - LOG_I(MAC,"[UE %d] sdu: %x.%x\n", Mod_id,sdu[0], sdu[1]); - LOG_I(MAC,"[UE %d] parse_mch_header, demultiplex\n",Mod_id); + LOG_D(MAC,"[UE %d] Frame %d : process the mch PDU for sync area %d \n",Mod_id,frame, sync_area); + LOG_D(MAC,"[UE %d] sdu: %x.%x\n", Mod_id,sdu[0], sdu[1]); + LOG_D(MAC,"[UE %d] parse_mch_header, demultiplex\n",Mod_id); payload_ptr = parse_mch_header(sdu, &num_sdu, rx_lcids, rx_lengths, sdu_len); - LOG_I(MAC,"[UE %d] parse_mch_header, found %d sdus\n",Mod_id,num_sdu); + LOG_D(MAC,"[UE %d] parse_mch_header, found %d sdus\n",Mod_id,num_sdu); for (i=0; i<num_sdu; i++) { if (rx_lcids[i] == MCH_SCHDL_INFO) { if (UE_mac_inst[Mod_id].mcch_status==1) { - LOG_I(MAC,"[UE %d] Frame %d : MCH -> MSI (eNB %d, %d bytes)\n",Mod_id,frame, eNB_index, rx_lengths[i]); + LOG_I(MAC,"[UE %d] Frame %d : MCH->MSI for sync area %d (eNB %d, %d bytes)\n",Mod_id,frame, 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 @@ -494,15 +495,15 @@ void ue_send_mch_sdu(u8 Mod_id, u32 frame, u8 *sdu, u16 sdu_len, u8 eNB_index) { } } else if (rx_lcids[i] == MCCH_LCHANID) { - LOG_I(MAC,"[UE %d] Frame %d : MCH -> MCCH, RRC message (eNB %d, %d bytes)\n",Mod_id,frame, eNB_index, rx_lengths[i]); + LOG_I(MAC,"[UE %d] Frame %d : SDU %d MCH->MCCH for sync area %d (eNB %d, %d bytes)\n",Mod_id,frame, i, sync_area, eNB_index, rx_lengths[i]); mac_rrc_data_ind(Mod_id, frame, MCCH, - (char *)payload_ptr, rx_lengths[i], 0, eNB_index); + (char *)payload_ptr, rx_lengths[i], 0, eNB_index, sync_area); } else if (rx_lcids[i] == MTCH) { if (UE_mac_inst[Mod_id].msi_status==1) { - LOG_I(MAC,"[UE %d] Frame %d : MCH -> MTCH (eNB %d, %d bytes)\n",Mod_id,frame, eNB_index, rx_lengths[i]); + LOG_I(MAC,"[UE %d] Frame %d : MCH->MTCH for sync area %d (eNB %d, %d bytes)\n",Mod_id,frame, sync_area, eNB_index, rx_lengths[i]); mac_rlc_data_ind(Mod_id+NB_eNB_INST, // because rlc[module_idP] (to differential between eNB and UE) frame, @@ -515,204 +516,245 @@ void ue_send_mch_sdu(u8 Mod_id, u32 frame, u8 *sdu, u16 sdu_len, u8 eNB_index) { NULL); } + } else { + LOG_W(MAC,"[UE %d] Frame %d : unknown sdu %d mcch status %d eNB %d \n",Mod_id,frame,rx_lengths[i], + UE_mac_inst[Mod_id].mcch_status, eNB_index); } + payload_ptr += rx_lengths[i]; } // vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_MCH_SDU, VCD_FUNCTION_OUT); } -int ue_query_mch(uint8_t Mod_id, uint32_t frame, uint32_t subframe) { +s8 ue_get_mbsfn_sf_alloction (unsigned char Mod_id, u8 mbsfn_sync_area, unsigned char eNB_index){ + // currently there is one-to-one mapping between sf allocation pattern and sync area + if (mbsfn_sync_area > MAX_MBSFN_AREA){ + LOG_W(MAC,"[UE %d] MBSFN synchronization area %d out of range for eNB %d\n ", Mod_id, mbsfn_sync_area, eNB_index); + return -1; + } + else if (UE_mac_inst[Mod_id].mbsfn_SubframeConfig[mbsfn_sync_area] != NULL) + return mbsfn_sync_area; + else { + LOG_W(MAC,"[UE %d] MBSFN Subframe Config pattern %d not found \n ", Mod_id, mbsfn_sync_area); + return -1; + } +} + +int ue_query_mch(uint8_t Mod_id, uint32_t frame, uint32_t subframe, uint8_t eNB_index,uint8_t *sync_area, uint8_t *mcch_active) { - int ii=0, msi_pos=0, mcch_mcs; + int i=0, j=0, ii=0, msi_pos=0, mcch_mcs; int mcch_flag=0, mtch_flag=0, msi_flag=0; - int mbsfn_period = 1<<(UE_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->radioframeAllocationPeriod); - int mcch_period = 32<<(UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_RepetitionPeriod_r9); + int mbsfn_period = 0;// 1<<(UE_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->radioframeAllocationPeriod); + int mcch_period = 0;// 32<<(UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_RepetitionPeriod_r9); int mch_scheduling_period; - LOG_I(MAC,"[UE %d] Frame %d, subframe %d: query mch\n",Mod_id,frame,subframe); - if (UE_mac_inst[Mod_id].pmch_Config[0]) mch_scheduling_period = 8<<(UE_mac_inst[Mod_id].pmch_Config[0]->mch_SchedulingPeriod_r9); - if (frame % mbsfn_period == UE_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->radioframeAllocationOffset){ // MBSFN frame - if (UE_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame){// one-frame format + for (i=0; + i< eNB_mac_inst[Mod_id].num_active_mbsfn_area; + i++ ){ + // assume, that there is always a mapping + if ((j=ue_get_mbsfn_sf_alloction(Mod_id,i,eNB_index)) == -1) + return -1; // continue; + ii=0; + msi_pos=0; + mbsfn_period = 1<<(UE_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->radioframeAllocationPeriod); + mcch_period = 32<<(UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_RepetitionPeriod_r9); + + 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)\n", + Mod_id,frame, subframe,i,UE_mac_inst[Mod_id].num_active_mbsfn_area, + j,UE_mac_inst[Mod_id].num_sf_allocation_pattern,mbsfn_period,mcch_period); + + // get the real MCS value + switch (UE_mac_inst[Mod_id].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; + } + + if (frame % mbsfn_period == UE_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->radioframeAllocationOffset){ // MBSFN frame + if (UE_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame){// one-frame format - if (UE_mac_inst[Mod_id].pmch_Config[0]) { - // Find the first subframe in this MCH to transmit MSI - if (frame % mch_scheduling_period == UE_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->radioframeAllocationOffset ) { - while (ii == 0) { - ii = UE_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & (0x80>>msi_pos); - msi_pos++; + if (UE_mac_inst[Mod_id].pmch_Config[0]) { + // Find the first subframe in this MCH to transmit MSI + if (frame % mch_scheduling_period == UE_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->radioframeAllocationOffset ) { + while (ii == 0) { + ii = UE_mac_inst[Mod_id].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 (mac_xface->lte_frame_parms->frame_type == FDD) { - if ((UE_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) { + switch (subframe) { + case 1: + if (mac_xface->lte_frame_parms->frame_type == FDD) { + if ((UE_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) { if (msi_pos == 1) msi_flag = 1; - if ( (frame % mcch_period == UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_Offset_r9) && - ((UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) ) + if ( (frame % mcch_period == UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && + ((UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) ) mcch_flag = 1; mtch_flag = 1; + } } - } - break; + break; - case 2: - if (mac_xface->lte_frame_parms->frame_type == FDD){ - if ((UE_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) { - if (msi_pos == 2) - msi_flag = 1; - if ( (frame % mcch_period == UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_Offset_r9) && - ((UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) ) - mcch_flag = 1; - mtch_flag = 1; + case 2: + if (mac_xface->lte_frame_parms->frame_type == FDD){ + if ((UE_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) { + if (msi_pos == 2) + msi_flag = 1; + if ( (frame % mcch_period == UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && + ((UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) ) + mcch_flag = 1; + mtch_flag = 1; + } } - } - break; - - case 3: - if (mac_xface->lte_frame_parms->frame_type == TDD){// TDD - if ((UE_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) { - if (msi_pos == 1) - msi_flag = 1; - if ( (frame % mcch_period == UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_Offset_r9) && - ((UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) ) - mcch_flag = 1; - mtch_flag = 1; + break; + + case 3: + if (mac_xface->lte_frame_parms->frame_type == TDD){// TDD + if ((UE_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) { + if (msi_pos == 1) + msi_flag = 1; + if ( (frame % mcch_period == UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && + ((UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) ) + mcch_flag = 1; + mtch_flag = 1; + } } - } - else {// FDD - if ((UE_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) { - if (msi_pos == 3) - msi_flag = 1; - if ( (frame % mcch_period == UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_Offset_r9) && - ((UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) ) - mcch_flag = 1; - mtch_flag = 1; + else {// FDD + if ((UE_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) { + if (msi_pos == 3) + msi_flag = 1; + if ((frame % mcch_period == UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && + ((UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) ) + mcch_flag = 1; + mtch_flag = 1; + } } - } - break; + break; - case 4: - if (mac_xface->lte_frame_parms->frame_type == TDD){ - if ((UE_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) { - if (msi_pos == 2) - msi_flag = 1; - if ( (frame % mcch_period == UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_Offset_r9) && - ((UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) ) - mcch_flag = 1; - mtch_flag = 1; + case 4: + if (mac_xface->lte_frame_parms->frame_type == TDD){ + if ((UE_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) { + if (msi_pos == 2) + msi_flag = 1; + if ((frame % mcch_period == UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && + ((UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) ) + mcch_flag = 1; + mtch_flag = 1; + } } - } - break; + break; - case 6: - if (mac_xface->lte_frame_parms->frame_type == FDD){ - if ((UE_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) { - if (msi_pos == 4) - msi_flag = 1; - if ( (frame % mcch_period == UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_Offset_r9) && - ((UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) ) - mcch_flag = 1; - mtch_flag = 1; + case 6: + if (mac_xface->lte_frame_parms->frame_type == FDD){ + if ((UE_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) { + if (msi_pos == 4) + msi_flag = 1; + if ((frame % mcch_period == UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && + ((UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) ) + mcch_flag = 1; + mtch_flag = 1; + } } - } - break; + break; - case 7: - if (mac_xface->lte_frame_parms->frame_type == TDD){ // TDD - if ((UE_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) { - if (msi_pos == 3) - msi_flag = 1; - if ( (frame % mcch_period == UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_Offset_r9) && - ((UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) ) - mcch_flag = 1; - mtch_flag = 1; + case 7: + if (mac_xface->lte_frame_parms->frame_type == TDD){ // TDD + if ((UE_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) { + if (msi_pos == 3) + msi_flag = 1; + if ((frame % mcch_period == UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && + ((UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) ) + mcch_flag = 1; + mtch_flag = 1; + } } - } - else {// FDD - if ((UE_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) { - if (msi_pos == 5) - msi_flag = 1; - if ( (frame % mcch_period == UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_Offset_r9) && - ((UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) ) - mcch_flag = 1; - mtch_flag = 1; + else {// FDD + if ((UE_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) { + if (msi_pos == 5) + msi_flag = 1; + if ((frame % mcch_period == UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && + ((UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) ) + mcch_flag = 1; + mtch_flag = 1; + } } - } break; - case 8: - if (mac_xface->lte_frame_parms->frame_type == TDD){ //TDD - if ((UE_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) { - if (msi_pos == 4) - msi_flag = 1; - if ( (frame % mcch_period == UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_Offset_r9) && - ((UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) ) - mcch_flag = 1; - mtch_flag = 1; + case 8: + if (mac_xface->lte_frame_parms->frame_type == TDD){ //TDD + if ((UE_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) { + if (msi_pos == 4) + msi_flag = 1; + if ( (frame % mcch_period == UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && + ((UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) ) + mcch_flag = 1; + mtch_flag = 1; + } } - } - else{ // FDD - if ((UE_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) { - if (msi_pos == 6) - msi_flag = 1; - if ( (frame % mcch_period == UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_Offset_r9) && - ((UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->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[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) { + if (msi_pos == 6) + msi_flag = 1; + if ((frame % mcch_period == UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && + ((UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) ) + mcch_flag = 1; + mtch_flag = 1; + } } - } - break; + break; - case 9: - if (mac_xface->lte_frame_parms->frame_type == TDD){ - if ((UE_mac_inst[Mod_id].mbsfn_SubframeConfig[0]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) { - if (msi_pos == 5) - msi_flag = 1; - if ( (frame % mcch_period == UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_Offset_r9) && - ((UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) ) - mcch_flag = 1; - mtch_flag = 1; + case 9: + if (mac_xface->lte_frame_parms->frame_type == TDD){ + if ((UE_mac_inst[Mod_id].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) { + if (msi_pos == 5) + msi_flag = 1; + if ((frame % mcch_period == UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && + ((UE_mac_inst[Mod_id].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 + // 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", + Mod_id, frame, subframe,i,j,msi_flag,mcch_flag,mtch_flag); + + *sync_area=i; + break; } - break; - }// end switch - } - else {// four-frame format + } + else {// four-frame format + } } - } - - // get the real MCS value - switch (UE_mac_inst[Mod_id].mbsfn_AreaInfo[0]->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; - } + } // end of for - if ( (mcch_flag==1) || - ((msi_flag==1) && (UE_mac_inst[Mod_id].mcch_status==1)) ) + if ( (mcch_flag==1))// || (msi_flag==1)) + *mcch_active=1; + + if ( (mcch_flag==1) || ((msi_flag==1) && (UE_mac_inst[Mod_id].mcch_status==1)) ){ return mcch_mcs; - else if ((mtch_flag==1) && (UE_mac_inst[Mod_id].msi_status==1)) + } else if ((mtch_flag==1) && (UE_mac_inst[Mod_id].msi_status==1)) return UE_mac_inst[Mod_id].pmch_Config[0]->dataMCS_r9; 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 635418ed8d018da3a67752fdd9d883e462491980..00e86dc2b754e31a58810e47f1072df7a3ae220a 100755 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -859,10 +859,10 @@ BOOL pdcp_config_req_asn1 (module_id_t module_id, u32 frame, u8_t eNB_flag, u16 break; case ACTION_MBMS_ADD: case ACTION_MBMS_MODIFY: - pdcp_mbms_array[module_id][lc_id].instanciated_instance = module_id + 1 ; - pdcp_mbms_array[module_id][lc_id].service_id = mch_id; - pdcp_mbms_array[module_id][lc_id].session_id = lc_id; - pdcp_mbms_array[module_id][lc_id].rb_id = rb_id; + pdcp_mbms_array[module_id][rb_id].instanciated_instance = module_id + 1 ; + pdcp_mbms_array[module_id][rb_id].service_id = mch_id; + pdcp_mbms_array[module_id][rb_id].session_id = lc_id; + pdcp_mbms_array[module_id][rb_id].rb_id = rb_id; LOG_I(PDCP,"[%s %d] Config request : ACTION_MBMS_ADD: Frame %d service_id/mch index %d, session_id/lcid %d, rbid %d configured\n", (eNB_flag == 1) ? "eNB" : "UE", module_id, frame, mch_id, lc_id, rb_id); break; diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 09d187082de26df2791da28e524ec22e3dbd6884..a938813f16022d19da226d6b232accf499f327b7 100755 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -597,7 +597,7 @@ int LOG_E(PDCP, "Received packet for non-instanciated instance %u with rb_id %u\n", pdcp_read_header.inst, pdcp_read_header.rb_id); } - } else if (eNB_flag) { + } else if (eNB_flag) { // rb_id =0, thus interpreated as broadcast and transported as multiple unicast // is a broadcast packet, we have to send this packet on all default RABS of all connected UEs #warning CODE TO BE REVIEWED, ONLY WORK FOR SIMPLE TOPOLOGY CASES for (rab_id = DEFAULT_RAB_ID; rab_id < MAX_RB; rab_id = rab_id + NB_RB_MAX) { @@ -636,7 +636,7 @@ void pdcp_fifo_read_input_sdus_from_otg (u32_t frame, u8_t eNB_flag, u8 UE_index int src_id, module_id; // src for otg int dst_id, rb_id; // dst for otg int pkt_size=0, pkt_cnt=0; - u8 pdcp_mode; + u8 pdcp_mode, is_ue=0; Packet_otg_elt * otg_pkt_info; // we need to add conditions to avoid transmitting data when the UE is not RRC connected. @@ -644,50 +644,39 @@ void pdcp_fifo_read_input_sdus_from_otg (u32_t frame, u8_t eNB_flag, u8 UE_index if (oai_emulation.info.otg_enabled ==1 ){ module_id = (eNB_flag == 1) ? eNB_index : NB_eNB_INST + UE_index ; //rb_id = (eNB_flag == 1) ? eNB_index * MAX_NUM_RB + DTCH : (NB_eNB_INST + UE_index -1 ) * MAX_NUM_RB + DTCH ; - if (eNB_flag == 1) { // search for DL traffic - //for (dst_id = NB_eNB_INST; dst_id < NB_UE_INST + NB_eNB_INST; dst_id++) { - while ((otg_pkt_info = pkt_list_remove_head(&(otg_pdcp_buffer[module_id]))) != NULL) { - LOG_I(EMU,"HEAD of otg_pdcp_buffer[%d] is %p but Nb elts = %d\n", module_id, pkt_list_get_head(&(otg_pdcp_buffer[module_id])), otg_pdcp_buffer[module_id].nb_elements); - //otg_pkt_info = pkt_list_remove_head(&(otg_pdcp_buffer[module_id])); - dst_id = (otg_pkt_info->otg_pkt).dst_id; - module_id = (otg_pkt_info->otg_pkt).module_id; - rb_id = (otg_pkt_info->otg_pkt).rb_id; - pdcp_mode = (otg_pkt_info->otg_pkt).mode; - // LOG_I(PDCP,"pdcp_fifo, pdcp mode is= %d\n",pdcp_mode); + + while ((otg_pkt_info = pkt_list_remove_head(&(otg_pdcp_buffer[module_id]))) != NULL) { + LOG_I(OTG,"Mod_id %d Frame %d Got a packet (%p), HEAD of otg_pdcp_buffer[%d] is %p and Nb elements is %d\n", + module_id,frame, otg_pkt_info, module_id, pkt_list_get_head(&(otg_pdcp_buffer[module_id])), otg_pdcp_buffer[module_id].nb_elements); + //otg_pkt_info = pkt_list_remove_head(&(otg_pdcp_buffer[module_id])); + dst_id = (otg_pkt_info->otg_pkt).dst_id; + module_id = (otg_pkt_info->otg_pkt).module_id; + rb_id = (otg_pkt_info->otg_pkt).rb_id; + is_ue = (otg_pkt_info->otg_pkt).is_ue; + pdcp_mode = (otg_pkt_info->otg_pkt).mode; + // LOG_I(PDCP,"pdcp_fifo, pdcp mode is= %d\n",pdcp_mode); - // generate traffic if the ue is rrc reconfigured state - // if (mac_get_rrc_status(module_id, eNB_flag, dst_id ) > 2 /*RRC_CONNECTED*/) { // not needed: this test is already done in update_otg_enb - otg_pkt = (u8*) (otg_pkt_info->otg_pkt).sdu_buffer; - pkt_size = (otg_pkt_info->otg_pkt).sdu_buffer_size; - if (otg_pkt != NULL) { + // generate traffic if the ue is rrc reconfigured state + // if (mac_get_rrc_status(module_id, eNB_flag, dst_id ) > 2 /*RRC_CONNECTED*/) { // not needed: this test is already done in update_otg_enb + otg_pkt = (u8*) (otg_pkt_info->otg_pkt).sdu_buffer; + pkt_size = (otg_pkt_info->otg_pkt).sdu_buffer_size; + if (otg_pkt != NULL) { + if (is_ue == 0 ) { //rb_id = (/*NB_eNB_INST +*/ dst_id -1 ) * MAX_NUM_RB + DTCH; - LOG_D(OTG,"[eNB %d] Frame %d sending packet %d from module %d on rab id %d (src %d, dst %d) pkt size %d for pdcp mode %d\n", eNB_index, frame, pkt_cnt++, module_id, rb_id, module_id, dst_id, pkt_size, pdcp_mode); + LOG_D(OTG,"[eNB %d] Frame %d sending packet %d from module %d on rab id %d (src %d, dst %d) pkt size %d for pdcp mode %d\n", + eNB_index, frame, pkt_cnt++, module_id, rb_id, module_id, dst_id, pkt_size, pdcp_mode); pdcp_data_req(module_id, frame, eNB_flag, rb_id, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, pkt_size, otg_pkt,pdcp_mode); - free(otg_pkt); } - // } //else LOG_D(OTG,"frame %d enb %d-> ue %d link not yet established state %d \n", frame, eNB_index,dst_id - NB_eNB_INST, mac_get_rrc_status(module_id, eNB_flag, dst_id - NB_eNB_INST)); - - } - } - else { - while ((otg_pkt_info = pkt_list_remove_head(&(otg_pdcp_buffer[module_id]))) != NULL) { - //otg_pkt_info = pkt_list_remove_head(&(otg_pdcp_buffer[module_id])); - dst_id = (otg_pkt_info->otg_pkt).dst_id; - module_id = (otg_pkt_info->otg_pkt).module_id; - rb_id = (otg_pkt_info->otg_pkt).rb_id; - src_id = module_id; - - // if (mac_get_rrc_status(module_id, eNB_flag, eNB_index ) > 2 /*RRC_CONNECTED*/) { // not needed: this test is already done in update_otg_ue - otg_pkt = (u8*) (otg_pkt_info->otg_pkt).sdu_buffer; - pkt_size = (otg_pkt_info->otg_pkt).sdu_buffer_size; - if (otg_pkt != NULL){ + else { //rb_id= eNB_index * MAX_NUM_RB + DTCH; - LOG_D(OTG,"[UE %d] sending packet from module %d on rab id %d (src %d, dst %d) pkt size %d\n", UE_index, src_id, rb_id, src_id, dst_id, pkt_size); + LOG_D(OTG,"[UE %d] sending packet from module %d on rab id %d (src %d, dst %d) pkt size %d\n", + UE_index, src_id, rb_id, src_id, dst_id, pkt_size); pdcp_data_req(src_id, frame, eNB_flag, rb_id, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO,pkt_size, otg_pkt, PDCP_DATA_PDU); - free(otg_pkt); } - //} //else LOG_D(OTG,"frame %d ue %d-> enb %d link not yet established state %d \n", frame, UE_index, eNB_index, mac_get_rrc_status(module_id, eNB_flag, eNB_index )); + free(otg_pkt); } + // } //else LOG_D(OTG,"frame %d enb %d-> ue %d link not yet established state %d \n", frame, eNB_index,dst_id - NB_eNB_INST, mac_get_rrc_status(module_id, eNB_flag, dst_id - NB_eNB_INST)); + } } #else diff --git a/openair2/PHY_INTERFACE/defs.h b/openair2/PHY_INTERFACE/defs.h index 69377b19cfc0b58be024ae2c37d69fabd54217d1..968192dfc4df3978263bfcc8c12c78048994946a 100755 --- a/openair2/PHY_INTERFACE/defs.h +++ b/openair2/PHY_INTERFACE/defs.h @@ -137,11 +137,11 @@ typedef struct #ifdef Rel10 /// Send a received MCH sdu to MAC - void (*ue_send_mch_sdu)(u8 Mod_id,u32 frame,u8 *sdu,u16 sdu_len,u8 CH_index); + void (*ue_send_mch_sdu)(u8 Mod_id,u32 frame,u8 *sdu,u16 sdu_len,u8 eNB_index,u8 sync_area); /// Function to check if UE PHY needs to decode MCH for MAC - /// Return MCS value if need to decode, otherwise -1 - int (*ue_query_mch)(uint8_t Mod_id,uint32_t frame,uint32_t subframe); + /// get the sync area id, and teturn MCS value if need to decode, otherwise -1 + int (*ue_query_mch)(uint8_t Mod_id,uint32_t frame,uint32_t subframe,uint8_t eNB_index,uint8_t *sync_area, uint8_t *mcch_active); #endif /// Retrieve ULSCH sdu from MAC diff --git a/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.c b/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.c index 792497739440c95fb1914430e8da539698faffaf..314acf7a8a8893cec4ba5840cb35a007034944b8 100644 --- a/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.c +++ b/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.c @@ -1,9 +1,40 @@ -/*________________________openair_rrc_L2_interface.c________________________ +/******************************************************************************* - Authors : Hicham Anouar - Company : EURECOM - Emails : anouar@eurecom.fr -________________________________________________________________*/ + Eurecom OpenAirInterface 2 + Copyright(c) 1999 - 2010 Eurecom + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information + Openair Admin: openair_admin@eurecom.fr + Openair Tech : openair_tech@eurecom.fr + Forums : http://forums.eurecom.fsr/openairinterface + Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France + +*******************************************************************************/ + +/*! \file l2_interface.c +* \brief layer 2 interface +* \author Raymond Knopp and Navid Nikaein +* \date 2011 +* \version 1.0 +* \company Eurecom +* \email: navid.nikaein@eurecom.fr +*/ #ifdef USER_MODE #include <fcntl.h> @@ -56,22 +87,20 @@ ________________________________________________________________*/ #include "openair_rrc_L2_interface.h" /********************************************************************************************************************/ -s8 mac_rrc_data_req(u8 Mod_id, u32 frame, u16 Srb_id, u8 Nb_tb,char *Buffer,u8 eNB_flag,u8 eNB_index){ +s8 mac_rrc_data_req(u8 Mod_id, u32 frame, u16 Srb_id, u8 Nb_tb,char *Buffer,u8 eNB_flag,u8 eNB_index, u8 mbsfn_sync_area){ /********************************************************************************************************************/ #ifdef CELLULAR return(rrc_L2_data_req_rx(Mod_id,Srb_id,Nb_tb,Buffer,eNB_index)); #else - return(mac_rrc_lite_data_req(Mod_id,frame,Srb_id,Nb_tb,Buffer,eNB_flag,eNB_index)); + return(mac_rrc_lite_data_req(Mod_id,frame,Srb_id,Nb_tb,Buffer,eNB_flag,eNB_index,mbsfn_sync_area)); #endif //CELLULAR } -/********************************************************************************************************************/ -s8 mac_rrc_data_ind(u8 Mod_id, u32 frame, u16 Srb_id, char *Sdu,u16 Sdu_len,u8 eNB_flag, u8 eNB_index ){ -/********************************************************************************************************************/ +s8 mac_rrc_data_ind(u8 Mod_id, u32 frame, u16 Srb_id, char *Sdu,u16 Sdu_len,u8 eNB_flag, u8 eNB_index,u8 mbsfn_sync_area){ #ifdef CELLULAR return(rrc_L2_mac_data_ind_rx(Mod_id, Srb_id, Sdu, Sdu_len, eNB_index)); #else - return(mac_rrc_lite_data_ind(Mod_id,frame,Srb_id,Sdu,Sdu_len,eNB_flag,eNB_index)); + return(mac_rrc_lite_data_ind(Mod_id,frame,Srb_id,Sdu,Sdu_len,eNB_flag,eNB_index,mbsfn_sync_area)); #endif //CELLULAR } diff --git a/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.h b/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.h index 62762dd4f1b3845c7d982ab398cd17fd11b19a9a..f51c846cfdc53a496bbd82d154be4c87116d4a72 100644 --- a/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.h +++ b/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.h @@ -1,17 +1,47 @@ -/*________________________openair_rrc_L2_interface.h________________________ +/******************************************************************************* - Authors : Hicham Anouar - Company : EURECOM - Emails : anouar@eurecom.fr -________________________________________________________________*/ + Eurecom OpenAirInterface 2 + Copyright(c) 1999 - 2010 Eurecom + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information + Openair Admin: openair_admin@eurecom.fr + Openair Tech : openair_tech@eurecom.fr + Forums : http://forums.eurecom.fsr/openairinterface + Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France + +*******************************************************************************/ + +/*! \file l2_interface.c +* \brief layer 2 interface +* \author Raymond Knopp and Navid Nikaein +* \date 2011 +* \version 1.0 +* \company Eurecom +* \email: raymond.knopp@eurecom.fr +*/ #ifndef __OPENAIR_RRC_L2_INTERFACE_H__ #define __OPENAIR_RRC_L2_INTERFACE_H__ #include "COMMON/mac_rrc_primitives.h" -s8 mac_rrc_data_req( u8 Mod_id, u32 frame, u16 Srb_id, u8 Nb_tb,char *Buffer,u8,u8); -s8 mac_rrc_data_ind( u8 Mod_id, u32 frame, u16 Srb_id, char *Sdu, u16 Sdu_len,u8,u8 Mui); +s8 mac_rrc_data_req( u8 Mod_id, u32 frame, u16 Srb_id, u8 Nb_tb,char *Buffer,u8 eNB_flag,u8 eNB_index, u8 mbsfn_sync_area); +s8 mac_rrc_data_ind( u8 Mod_id, u32 frame, u16 Srb_id, char *Sdu, u16 Sdu_len,u8 eNB_flag, u8 eNB_index,u8 mbsfn_sync_area); void mac_lite_sync_ind( u8 Mod_id, u8 status); void mac_rrc_meas_ind(u8,MAC_MEAS_REQ_ENTRY*); void rlcrrc_data_ind( u8 Mod_id, u32 frame, u8 eNB_flag,unsigned int Rb_id, u32 sdu_size,u8 *Buffer); diff --git a/openair2/RRC/LITE/L2_interface.c b/openair2/RRC/LITE/L2_interface.c index 1b1951f642788a16f85364e46137d1201ca738ad..1b4049d59556738df9f6088f1ce81f423b285612 100644 --- a/openair2/RRC/LITE/L2_interface.c +++ b/openair2/RRC/LITE/L2_interface.c @@ -29,7 +29,7 @@ /*! \file l2_interface.c * \brief layer 2 interface -* \author Raymond Knopp +* \author Raymond Knopp and Navid Nikaein * \date 2011 * \version 1.0 * \company Eurecom @@ -53,10 +53,9 @@ extern UE_MAC_INST *UE_mac_inst; #endif //#define RRC_DATA_REQ_DEBUG -//#define DEBUG_RRC +#define DEBUG_RRC u32 mui=0; -//---------------------------------------------------------------------------------------------// s8 mac_rrc_lite_data_req( u8 Mod_id, u32 frame, @@ -64,16 +63,15 @@ s8 mac_rrc_lite_data_req( u8 Mod_id, u8 Nb_tb, char *Buffer, u8 eNB_flag, - u8 eNB_index){ - //------------------------------------------------------------------------------------------------------------------// - + u8 eNB_index, + u8 mbsfn_sync_area){ SRB_INFO *Srb_info; u8 Sdu_size=0; #ifdef DEBUG_RRC int i; - LOG_T(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_id,Srb_id); + LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_id,Srb_id); #endif if( eNB_flag == 1){ @@ -134,21 +132,24 @@ s8 mac_rrc_lite_data_req( u8 Mod_id, #ifdef Rel10 if((Srb_id & RAB_OFFSET) == MCCH){ - if(eNB_rrc_inst[Mod_id].MCCH_MESS.Active==0) return 0; // this parameter is set in function init_mcch in rrc_eNB.c - if (eNB_rrc_inst[Mod_id].sizeof_MCCH_MESSAGE == 255) { + if(eNB_rrc_inst[Mod_id].MCCH_MESS[mbsfn_sync_area].Active==0) return 0; // this parameter is set in function init_mcch in rrc_eNB.c + // this part not needed as it is done in init_mcch + /* if (eNB_rrc_inst[Mod_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area] == 255) { LOG_E(RRC,"[eNB %d] MAC Request for MCCH MESSAGE and MCCH MESSAGE is not initialized\n",Mod_id); mac_xface->macphy_exit(""); - } - memcpy(&Buffer[0],eNB_rrc_inst[Mod_id].MCCH_MESSAGE,eNB_rrc_inst[Mod_id].sizeof_MCCH_MESSAGE); + }*/ + memcpy(&Buffer[0], + eNB_rrc_inst[Mod_id].MCCH_MESSAGE[mbsfn_sync_area], + eNB_rrc_inst[Mod_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]); #ifdef DEBUG_RRC LOG_D(RRC,"[eNB %d] Frame %d : MCCH request => MCCH_MESSAGE \n",Mod_id,frame); - for (i=0;i<eNB_rrc_inst[Mod_id].sizeof_MCCH_MESSAGE;i++) + for (i=0;i<eNB_rrc_inst[Mod_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area];i++) LOG_T(RRC,"%x.",Buffer[i]); LOG_T(RRC,"\n"); #endif - return (eNB_rrc_inst[Mod_id].sizeof_MCCH_MESSAGE); + return (eNB_rrc_inst[Mod_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]); // } //else //return(0); @@ -177,9 +178,7 @@ s8 mac_rrc_lite_data_req( u8 Mod_id, return(0); } -//--------------------------------------------------------------------------------------------// -s8 mac_rrc_lite_data_ind(u8 Mod_id, u32 frame, u16 Srb_id, char *Sdu, u16 Sdu_len,u8 eNB_flag,u8 eNB_index ){ - //------------------------------------------------------------------------------------------// +s8 mac_rrc_lite_data_ind(u8 Mod_id, u32 frame, u16 Srb_id, char *Sdu, u16 Sdu_len,u8 eNB_flag,u8 eNB_index,u8 mbsfn_sync_area){ SRB_INFO *Srb_info; int si_window; @@ -246,8 +245,9 @@ s8 mac_rrc_lite_data_ind(u8 Mod_id, u32 frame, u16 Srb_id, char *Sdu, u16 Sdu_le #ifdef Rel10 if ((Srb_id & RAB_OFFSET) == MCCH) { - LOG_T(RRC,"[UE %d] Received SDU for MCCH on SRB %d from eNB %d\n",Mod_id,Srb_id & RAB_OFFSET,eNB_index); - decode_MCCH_Message(Mod_id, frame, eNB_index, Sdu, Sdu_len); + LOG_T(RRC,"[UE %d] Frame %d: Received SDU on MBSFN sync area %d for MCCH on SRB %d from eNB %d\n", + Mod_id,frame, mbsfn_sync_area, Srb_id & RAB_OFFSET,eNB_index); + decode_MCCH_Message(Mod_id, frame, eNB_index, Sdu, Sdu_len,mbsfn_sync_area); } #endif // Rel10 diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c index 35f32b4104c14df1199d7180e07821bcf64f4fe8..80e30c0d3b4c82ee4cea5d879abbd1a6251794dd 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c @@ -723,7 +723,7 @@ uint8_t do_SIB23(uint8_t Mod_id, #ifdef Rel10 if (MBMS_flag > 0) { - LOG_I(RRC,"Adding MBSFN Configuration to SIB2\n"); + LOG_I(RRC,"Adding MBSFN subframe Configuration 1 to SIB2\n"); MBSFN_SubframeConfig_t *sib2_mbsfn_SubframeConfig1; (*sib2)->mbsfn_SubframeConfigList = CALLOC(1,sizeof(struct MBSFN_SubframeConfigList)); MBSFNSubframeConfigList = (*sib2)->mbsfn_SubframeConfigList; @@ -737,13 +737,34 @@ uint8_t do_SIB23(uint8_t Mod_id, sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(1); sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 1; sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 2; - if (frame_parms->frame_type == TDD) {// pattern 001110 for TDD + if (frame_parms->frame_type == TDD) { sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=0x08<<2;// shift 2 cuz 2last bits are unused. } - else { // pattern 101010 for FDD) - sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=0x30<<2; + else {/// 111000 + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=0x38<<2; } ASN_SEQUENCE_ADD(&MBSFNSubframeConfigList->list,sib2_mbsfn_SubframeConfig1); + + if (MBMS_flag == 4 ) { + LOG_I(RRC,"Adding MBSFN subframe Configuration 2 to SIB2\n"); + MBSFN_SubframeConfig_t *sib2_mbsfn_SubframeConfig2; + sib2_mbsfn_SubframeConfig2= CALLOC(1,sizeof(*sib2_mbsfn_SubframeConfig2)); + memset((void*)sib2_mbsfn_SubframeConfig2,0,sizeof(*sib2_mbsfn_SubframeConfig2)); + + sib2_mbsfn_SubframeConfig2->radioframeAllocationPeriod= MBSFN_SubframeConfig__radioframeAllocationPeriod_n4; + sib2_mbsfn_SubframeConfig2->radioframeAllocationOffset= 1; + sib2_mbsfn_SubframeConfig2->subframeAllocation.present= MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame; + sib2_mbsfn_SubframeConfig2->subframeAllocation.choice.oneFrame.buf= MALLOC(1); + sib2_mbsfn_SubframeConfig2->subframeAllocation.choice.oneFrame.size= 1; + sib2_mbsfn_SubframeConfig2->subframeAllocation.choice.oneFrame.bits_unused= 2; + if (frame_parms->frame_type == TDD) { + sib2_mbsfn_SubframeConfig2->subframeAllocation.choice.oneFrame.buf[0]=0x08<<2;// shift 2 cuz 2last bits are unused. + } + else { ///000111 + sib2_mbsfn_SubframeConfig2->subframeAllocation.choice.oneFrame.buf[0]=0x07<<2; + } + ASN_SEQUENCE_ADD(&MBSFNSubframeConfigList->list,sib2_mbsfn_SubframeConfig2); + } } #else // no MBMS transmission (*sib2)->mbsfn_SubframeConfigList = NULL; @@ -813,7 +834,7 @@ uint8_t do_SIB23(uint8_t Mod_id, } MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.bits_unused= 2; - MBSFN_Area1->mcch_Config_r9.signallingMCS_r9= MBSFN_AreaInfo_r9__mcch_Config_r9__signallingMCS_r9_n13; + MBSFN_Area1->mcch_Config_r9.signallingMCS_r9= MBSFN_AreaInfo_r9__mcch_Config_r9__signallingMCS_r9_n7; ASN_SEQUENCE_ADD(&MBSFNArea_list->list,MBSFN_Area1); @@ -836,7 +857,7 @@ uint8_t do_SIB23(uint8_t Mod_id, else { MBSFN_Area2->mcch_Config_r9.sf_AllocInfo_r9.buf[0]=0x04<<2; // FDD: SF6 } - MBSFN_Area2->mcch_Config_r9.signallingMCS_r9= MBSFN_AreaInfo_r9__mcch_Config_r9__signallingMCS_r9_n2; + MBSFN_Area2->mcch_Config_r9.signallingMCS_r9= MBSFN_AreaInfo_r9__mcch_Config_r9__signallingMCS_r9_n7; ASN_SEQUENCE_ADD(&MBSFNArea_list->list,MBSFN_Area2); } @@ -1488,6 +1509,7 @@ uint8_t TMGI[5] = {4,3,2,1,0};//TMGI is a string of octet, ref. TS 24.008 fig. 1 #ifdef Rel10 uint8_t do_MBSFNAreaConfig(LTE_DL_FRAME_PARMS *frame_parms, + uint8_t sync_area, uint8_t *buffer, MCCH_Message_t *mcch_message, MBSFNAreaConfiguration_r9_t **mbsfnAreaConfiguration) { @@ -1513,11 +1535,25 @@ uint8_t do_MBSFNAreaConfig(LTE_DL_FRAME_PARMS *frame_parms, mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(1); mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 1; mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 2; - if (frame_parms->frame_type == TDD) {// pattern 001110 for TDD - mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=0x08<<2;// shift 2bits cuz 2last bits are unused. - } - else { // pattern 101010 for FDD) - mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=0x30<<2; + // CURRENTLY WE ARE SUPPORITNG ONLY ONE sf ALLOCATION + switch (sync_area) { + case 0: + if (frame_parms->frame_type == TDD) {// pattern 001110 for TDD + mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=0x08<<2;// shift 2bits cuz 2last bits are unused. + } + else { //111000 + mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=0x38<<2; + } + break; + case 1: + if (frame_parms->frame_type == TDD) { + mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=0x08<<2;// shift 2bits cuz 2last bits are unused. + } + else { // 000111 + mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=0x07<<2; + } + default : + break; } ASN_SEQUENCE_ADD(&(*mbsfnAreaConfiguration)->commonSF_Alloc_r9.list,mbsfn_SubframeConfig1); @@ -1530,7 +1566,7 @@ uint8_t do_MBSFNAreaConfig(LTE_DL_FRAME_PARMS *frame_parms, memset((void*)pmch_Info_1,0,sizeof(PMCH_Info_r9_t)); pmch_Info_1->pmch_Config_r9.sf_AllocEnd_r9= 3;//take the value of last mbsfn subframe in this CSA period because there is only one PMCH in this mbsfn area - pmch_Info_1->pmch_Config_r9.dataMCS_r9= 13; + pmch_Info_1->pmch_Config_r9.dataMCS_r9= 17; pmch_Info_1->pmch_Config_r9.mch_SchedulingPeriod_r9= PMCH_Config_r9__mch_SchedulingPeriod_r9_rf16; // MBMSs-SessionInfoList-r9 diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.h b/openair2/RRC/LITE/MESSAGES/asn1_msg.h index 9741077b2e5556c2fd25de3e5f41ba7195d2d593..4ddd83fa1b085cc3790122f90e40911608006704 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.h @@ -127,11 +127,25 @@ uint8_t do_RRCConnectionReconfiguration(uint8_t Mod_id uint8_t *nas_pdu, uint32_t nas_length); -/** -\brief Generate an MCCH-Message (eNB). This routine configures MBSFNAreaConfiguration (PMCH-InfoList and Subframe Allocation for MBMS data) -@param buffer Pointer to PER-encoded ASN.1 description of MCCH-Message PDU -@returns Size of encoded bit stream in bytes*/ +/*** + * \brief Generate an MCCH-Message (eNB). This routine configures MBSFNAreaConfiguration (PMCH-InfoList and Subframe Allocation for MBMS data) + * @param buffer Pointer to PER-encoded ASN.1 description of MCCH-Message PDU + * @returns Size of encoded bit stream in bytes +*/ uint8_t do_MCCHMessage(uint8_t *buffer); +#ifdef Rel10 +/*** + * \brief Generate an MCCH-Message (eNB). This routine configures MBSFNAreaConfiguration (PMCH-InfoList and Subframe Allocation for MBMS data) + * @param buffer Pointer to PER-encoded ASN.1 description of MCCH-Message PDU + * @returns Size of encoded bit stream in bytes +*/ +uint8_t do_MBSFNAreaConfig(LTE_DL_FRAME_PARMS *frame_parms, + uint8_t sync_area, + uint8_t *buffer, + MCCH_Message_t *mcch_message, + MBSFNAreaConfiguration_r9_t **mbsfnAreaConfiguration); +#endif + OAI_UECapability_t *fill_ue_capability(); diff --git a/openair2/RRC/LITE/defs.h b/openair2/RRC/LITE/defs.h index a609f414ec6ee97c3e341dc7930f866b0533e8a2..b908b0a5716a160b53808a79714532ee0591eb55 100644 --- a/openair2/RRC/LITE/defs.h +++ b/openair2/RRC/LITE/defs.h @@ -123,7 +123,7 @@ typedef struct{ u8 SIB1Status; u8 SIStatus; #ifdef Rel10 - u8 MCCH_MESSAGEStatus; + u8 MCCHStatus[8]; // MAX_MBSFN_AREA #endif u8 SIwindowsize; u16 SIperiod; @@ -214,11 +214,12 @@ typedef struct{ #ifdef Rel10 SystemInformationBlockType13_r9_t *sib13; uint8_t MBMS_flag; - uint8_t *MCCH_MESSAGE; - uint8_t sizeof_MCCH_MESSAGE; + uint8_t num_mbsfn_sync_area; + uint8_t **MCCH_MESSAGE; // MAX_MBSFN_AREA + uint8_t sizeof_MCCH_MESSAGE[8];// MAX_MBSFN_AREA MCCH_Message_t mcch; MBSFNAreaConfiguration_r9_t *mcch_message; - SRB_INFO MCCH_MESS; + SRB_INFO MCCH_MESS[8];// MAX_MBSFN_AREA #endif #ifdef CBA uint8_t num_active_cba_groups; @@ -460,12 +461,15 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(u8 Mod_id, u32 frame, //L2_interface.c -s8 mac_rrc_lite_data_req( u8 Mod_id, u32 frame, unsigned short Srb_id, u8 Nb_tb,char *Buffer,u8 eNB_flag,u8 eNB_index); -s8 mac_rrc_lite_data_ind( u8 Mod_id, u32 frame, unsigned short Srb_id, char *Sdu, unsigned short Sdu_len,u8 eNB_flag,u8 Mui); +s8 mac_rrc_lite_data_req( u8 Mod_id, u32 frame, unsigned short Srb_id, u8 Nb_tb,char *Buffer,u8 eNB_flag, u8 eNB_index, u8 mbsfn_sync_area); +s8 mac_rrc_lite_data_ind( u8 Mod_id, u32 frame, unsigned short Srb_id, char *Sdu, unsigned short Sdu_len,u8 eNB_flag,u8 eNB_index, u8 mbsfn_sync_area); void mac_sync_ind( u8 Mod_id, u8 status); void rrc_lite_data_ind( u8 Mod_id, u32 frame, u8 eNB_flag, u32 Rb_id, u32 sdu_size,u8 *Buffer); void rrc_lite_out_of_sync_ind(u8 Mod_id, u32 frame, unsigned short eNB_index); +int decode_MCCH_Message(u8 Mod_id, u32 frame, u8 eNB_index, u8 *Sdu, u8 Sdu_len,u8 mbsfn_sync_area); +void decode_MBSFNAreaConfiguration(u8 Mod_id, u8 eNB_index, u32 frame,u8 mbsfn_sync_area); + int decode_SIB1(u8 Mod_id,u8 CH_index); int decode_SI(u8 Mod_id,u32 frame,u8 CH_index,u8 si_window); diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c index 2b66aef667375462620ea6f307a0125cdee257f9..a137b77fb8dd9ccce8bcdcd16b76aa5271c7eed5 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LITE/rrc_UE.c @@ -110,11 +110,12 @@ void init_SI_UE(u8 Mod_id,u8 eNB_index) { #ifdef Rel10 void init_MCCH_UE(u8 Mod_id, u8 eNB_index) { - + int i; UE_rrc_inst[Mod_id].sizeof_MCCH_MESSAGE[eNB_index] = 0; UE_rrc_inst[Mod_id].MCCH_MESSAGE[eNB_index] = (u8 *)malloc16(32); UE_rrc_inst[Mod_id].mcch_message[eNB_index] = (MBSFNAreaConfiguration_r9_t *)malloc16(sizeof(MBSFNAreaConfiguration_r9_t)); - UE_rrc_inst[Mod_id].Info[eNB_index].MCCH_MESSAGEStatus = 0; + for (i=0; i<8;i++) // MAX MBSFN Area + UE_rrc_inst[Mod_id].Info[eNB_index].MCCHStatus[i] = 0; } #endif @@ -1450,9 +1451,9 @@ void dump_sib2(SystemInformationBlockType2_t *sib2) { LOG_D(RRC,"ue_TimersAndConstants.n311 : %ld\n", sib2->ue_TimersAndConstants.n311); LOG_D(RRC,"freqInfo.additionalSpectrumEmission : %ld\n",sib2->freqInfo.additionalSpectrumEmission); - LOG_D(RRC,"freqInfo.ul_CarrierFreq : %ld\n", sib2->freqInfo.ul_CarrierFreq); - LOG_D(RRC,"freqInfo.ul_Bandwidth : %ld\n", sib2->freqInfo.ul_Bandwidth); - LOG_D(RRC,"mbsfn_SubframeConfigList : %ld\n", sib2->mbsfn_SubframeConfigList); + LOG_D(RRC,"freqInfo.ul_CarrierFreq : %p\n", sib2->freqInfo.ul_CarrierFreq); + LOG_D(RRC,"freqInfo.ul_Bandwidth : %p\n", sib2->freqInfo.ul_Bandwidth); + LOG_D(RRC,"mbsfn_SubframeConfigList : %p\n", sib2->mbsfn_SubframeConfigList); LOG_D(RRC,"timeAlignmentTimerCommon : %ld\n", sib2->timeAlignmentTimerCommon); @@ -1636,14 +1637,15 @@ int decode_SI(u8 Mod_id,u32 frame,u8 eNB_index,u8 si_window) { } #ifdef Rel10 -int decode_MCCH_Message(u8 Mod_id, u32 frame, u8 eNB_index, u8 *Sdu, u8 Sdu_len) { +int decode_MCCH_Message(u8 Mod_id, u32 frame, u8 eNB_index, u8 *Sdu, u8 Sdu_len,u8 mbsfn_sync_area) { MCCH_Message_t *mcch=NULL; MBSFNAreaConfiguration_r9_t **mcch_message=&UE_rrc_inst[Mod_id].mcch_message[eNB_index]; asn_dec_rval_t dec_rval; - if (UE_rrc_inst[Mod_id].Info[eNB_index].MCCH_MESSAGEStatus == 1) { - LOG_D(RRC,"MCCH MESSAGE has been already received!\n"); + if (UE_rrc_inst[Mod_id].Info[eNB_index].MCCHStatus[mbsfn_sync_area] == 1) { + LOG_D(RRC,"[UE %d] Frame %d: MCCH MESSAGE for MBSFN sync area %d has been already received!\n", + Mod_id, frame, mbsfn_sync_area); return 0; // avoid decoding to prevent memory bloating } else { @@ -1671,7 +1673,7 @@ int decode_MCCH_Message(u8 Mod_id, u32 frame, u8 eNB_index, u8 *Sdu, u8 Sdu_len) sizeof(MBSFNAreaConfiguration_r9_t)); */ *mcch_message = &mcch->message.choice.c1.choice.mbsfnAreaConfiguration_r9; LOG_I(RRC,"[UE %d] Frame %d : Found MBSFNAreaConfiguration from eNB %d \n",Mod_id, frame, eNB_index); - decode_MBSFNAreaConfiguration(Mod_id,eNB_index,frame); + decode_MBSFNAreaConfiguration(Mod_id,eNB_index,frame, mbsfn_sync_area); } } @@ -1679,8 +1681,9 @@ int decode_MCCH_Message(u8 Mod_id, u32 frame, u8 eNB_index, u8 *Sdu, u8 Sdu_len) return 0; } -void decode_MBSFNAreaConfiguration(u8 Mod_id, u8 eNB_index, u32 frame) { - LOG_D(RRC,"[UE %d] Number of MCH(s) in this MBSFN Area is %d\n", Mod_id, UE_rrc_inst[Mod_id].mcch_message[eNB_index]->pmch_InfoList_r9.list.count); +void decode_MBSFNAreaConfiguration(u8 Mod_id, u8 eNB_index, u32 frame,u8 mbsfn_sync_area) { + LOG_D(RRC,"[UE %d] Frame %d : Number of MCH(s) in the MBSFN Sync Area %d is %d\n", + Mod_id, frame, mbsfn_sync_area, UE_rrc_inst[Mod_id].mcch_message[eNB_index]->pmch_InfoList_r9.list.count); // store to MAC/PHY necessary parameters for receiving MTCHs rrc_mac_config_req(Mod_id,0,0,eNB_index, (RadioResourceConfigCommonSIB_t *)NULL, @@ -1710,15 +1713,19 @@ void decode_MBSFNAreaConfiguration(u8 Mod_id, u8 eNB_index, u32 frame) { #endif ); - UE_rrc_inst[Mod_id].Info[eNB_index].MCCH_MESSAGEStatus = 1; - + UE_rrc_inst[Mod_id].Info[eNB_index].MCCHStatus[mbsfn_sync_area] = 1; + // Config Radio Bearer for MBMS user data (similar way to configure for eNB side in init_MBMS function) - rrc_pdcp_config_asn1_req(NB_eNB_INST+Mod_id,frame, + rrc_pdcp_config_asn1_req(NB_eNB_INST+Mod_id,frame, 0,// eNB_flag eNB_index,// 0,// index NULL, // SRB_ToAddModList NULL, // DRB_ToAddModList - (DRB_ToReleaseList_t*)NULL + (DRB_ToReleaseList_t*)NULL, + 0, // security mode + NULL, // key rrc encryption + NULL, // key rrc integrity + NULL // key encryption #ifdef Rel10 , &(UE_rrc_inst[Mod_id].mcch_message[eNB_index]->pmch_InfoList_r9) diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index 969acf6a5174a55a6f7cd78634393f65440e5833..45457e19878e1b54d7e1436561033aa99b65d009 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -85,11 +85,11 @@ extern void *bigphys_malloc (int); extern inline unsigned int taus (void); void -init_SI (u8 Mod_id) -{ +init_SI (u8 Mod_id) { u8 SIwindowsize = 1; u16 SIperiod = 8; + int i; /* uint32_t mib=0; int i; @@ -170,8 +170,7 @@ init_SI (u8 Mod_id) mac_xface->macphy_exit (""); eNB_rrc_inst[Mod_id].SIB23 = (u8 *) malloc16 (64); - if (eNB_rrc_inst[Mod_id].SIB23) - { + if (eNB_rrc_inst[Mod_id].SIB23) { eNB_rrc_inst[Mod_id].sizeof_SIB23 = do_SIB23 (Mod_id, mac_xface-> @@ -233,34 +232,37 @@ init_SI (u8 Mod_id) #ifdef Rel10 - if (eNB_rrc_inst[Mod_id].MBMS_flag > 0) - { - + if (eNB_rrc_inst[Mod_id].MBMS_flag > 0) { + + for (i=0; + i< eNB_rrc_inst[Mod_id].sib2->mbsfn_SubframeConfigList->list.count; + i++){ + // SIB 2 // LOG_D(RRC, "[eNB %d] mbsfn_SubframeConfigList.list.count = %ld\n", Mod_id, eNB_rrc_inst[Mod_id].sib2->mbsfn_SubframeConfigList->list.count); - LOG_D (RRC, "[eNB %d] mbsfn_Subframe_pattern is = %ld\n", Mod_id, - eNB_rrc_inst[Mod_id].sib2->mbsfn_SubframeConfigList->list. - array[0]->subframeAllocation.choice.oneFrame.buf[0]); - LOG_D (RRC, "[eNB %d] radioframe_allocation_period = %ld (just index number, not the real value)\n", Mod_id, eNB_rrc_inst[Mod_id].sib2->mbsfn_SubframeConfigList->list.array[0]->radioframeAllocationPeriod); // need to display the real value, using array of char (like in dumping SIB2) + LOG_D (RRC, "[eNB %d] SIB13 contents for MBSFN subframe allocation %d/%d(partial)\n", + Mod_id,i,eNB_rrc_inst[Mod_id].sib2->mbsfn_SubframeConfigList->list.count); + LOG_D (RRC, "[eNB %d] mbsfn_Subframe_pattern is = %x\n", Mod_id, + eNB_rrc_inst[Mod_id].sib2->mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]>>0); + LOG_D (RRC, "[eNB %d] radioframe_allocation_period = %ld (just index number, not the real value)\n", Mod_id, eNB_rrc_inst[Mod_id].sib2->mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod); // need to display the real value, using array of char (like in dumping SIB2) LOG_D (RRC, "[eNB %d] radioframe_allocation_offset = %ld\n", Mod_id, - eNB_rrc_inst[Mod_id].sib2->mbsfn_SubframeConfigList->list. - array[0]->radioframeAllocationOffset); + eNB_rrc_inst[Mod_id].sib2->mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset); + } // SIB13 - LOG_D (RRC, "[eNB %d] SIB13 contents (partial)\n", Mod_id); - LOG_D (RRC, "[eNB %d] Number of MBSFN Area: %ld\n", Mod_id, - eNB_rrc_inst[Mod_id].sib13->mbsfn_AreaInfoList_r9.list. - count); - LOG_D (RRC, "[eNB %d] MCCH Info of first MBSFN Area(partial)\n", - Mod_id); - LOG_D (RRC, - "[eNB %d] MCCH Repetition Period: %d (just index number, not real value)\n", + for (i=0; + i< eNB_rrc_inst[Mod_id].sib13->mbsfn_AreaInfoList_r9.list.count; + i++){ + LOG_D (RRC,"[eNB %d] SIB13 contents for MBSFN sync area %d/2 (partial)\n", + Mod_id, i, + eNB_rrc_inst[Mod_id].sib13->mbsfn_AreaInfoList_r9.list.count); + LOG_D (RRC,"[eNB %d] MCCH Repetition Period: %d (just index number, not real value)\n", Mod_id, - eNB_rrc_inst[Mod_id].sib13->mbsfn_AreaInfoList_r9.list. - array[0]->mcch_Config_r9.mcch_RepetitionPeriod_r9); + eNB_rrc_inst[Mod_id].sib13->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9); LOG_D (RRC, "[eNB %d] MCCH Offset: %d\n", Mod_id, - eNB_rrc_inst[Mod_id].sib13->mbsfn_AreaInfoList_r9.list. - array[0]->mcch_Config_r9.mcch_Offset_r9); - } + eNB_rrc_inst[Mod_id].sib13->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_Offset_r9); + + } + } #endif LOG_D (RRC, @@ -306,46 +308,50 @@ init_SI (u8 Mod_id) #ifdef Rel10 void -init_MCCH (u8 Mod_id) -{ +init_MCCH (u8 Mod_id) { + int sync_area=0; // initialize RRC_eNB_INST MCCH entry - eNB_rrc_inst[Mod_id].sizeof_MCCH_MESSAGE = 0; - eNB_rrc_inst[Mod_id].MCCH_MESSAGE = (u8 *) malloc16 (32); - if (eNB_rrc_inst[Mod_id].MCCH_MESSAGE) - { - eNB_rrc_inst[Mod_id].sizeof_MCCH_MESSAGE = - do_MBSFNAreaConfig (mac_xface->lte_frame_parms, - (uint8_t *) eNB_rrc_inst[Mod_id].MCCH_MESSAGE, - &eNB_rrc_inst[Mod_id].mcch, - &eNB_rrc_inst[Mod_id].mcch_message); - - LOG_D (RRC, "[eNB %d] MCCH_MESSAGE contents (partial)\n", Mod_id); + eNB_rrc_inst[Mod_id].MCCH_MESSAGE=malloc(eNB_rrc_inst[Mod_id].num_mbsfn_sync_area*sizeof(uint32_t*)); + for (sync_area = 0; + sync_area < eNB_rrc_inst[Mod_id].num_mbsfn_sync_area; + sync_area++){ + + eNB_rrc_inst[Mod_id].sizeof_MCCH_MESSAGE[sync_area] = 0; + eNB_rrc_inst[Mod_id].MCCH_MESSAGE[sync_area] = (u8 *) malloc16 (32); + + if (eNB_rrc_inst[Mod_id].MCCH_MESSAGE[sync_area] == NULL) { + LOG_E(RRC,"[eNB %d][MAIN] init_MCCH: FATAL, no memory for MCCH MESSAGE allocated \n", Mod_id); + mac_xface->macphy_exit("[RRC][init_MCCH] not enough memory\n"); + } else { + eNB_rrc_inst[Mod_id].sizeof_MCCH_MESSAGE[sync_area] = do_MBSFNAreaConfig (mac_xface->lte_frame_parms, + sync_area, + (uint8_t *) eNB_rrc_inst[Mod_id].MCCH_MESSAGE[sync_area], + &eNB_rrc_inst[Mod_id].mcch, + &eNB_rrc_inst[Mod_id].mcch_message); + + LOG_I(RRC,"mcch message pointer %p for sync area %d \n", eNB_rrc_inst[Mod_id].MCCH_MESSAGE[sync_area],sync_area); + LOG_D (RRC, "[eNB %d] MCCH_MESSAGE contents for Sync Area %d (partial)\n", Mod_id,sync_area); LOG_D (RRC, "[eNB %d] CommonSF_AllocPeriod_r9 %d\n", Mod_id, eNB_rrc_inst[Mod_id].mcch_message->commonSF_AllocPeriod_r9); LOG_D (RRC, "[eNB %d] CommonSF_Alloc_r9.list.count (number of MBSFN Subframe Pattern) %d\n", Mod_id, eNB_rrc_inst[Mod_id].mcch_message->commonSF_Alloc_r9.list.count); - LOG_D (RRC, "[eNB %d] First MBSFN Subframe Pattern: %02x (in hex)\n", + LOG_D (RRC, "[eNB %d] MBSFN Subframe Pattern: %02x (in hex)\n", Mod_id, eNB_rrc_inst[Mod_id].mcch_message->commonSF_Alloc_r9.list. array[0]->subframeAllocation.choice.oneFrame.buf[0]); + if (eNB_rrc_inst[Mod_id].sizeof_MCCH_MESSAGE[sync_area] == 255) + mac_xface->macphy_exit (""); + else + eNB_rrc_inst[Mod_id].MCCH_MESS[sync_area].Active = 1; } - else - { - LOG_E (RRC, - "[eNB] init_MCCH: FATAL, no memory for MCCH MESSAGE allocated\n"); - mac_xface->macphy_exit (""); - } - - if (eNB_rrc_inst[Mod_id].sizeof_MCCH_MESSAGE == 255) - mac_xface->macphy_exit (""); - + } //Set the eNB_rrc_inst[Mod_id].MCCH_MESS.Active to 1 (allow to transfer MCCH message RRC->MAC in function mac_rrc_data_req) - eNB_rrc_inst[Mod_id].MCCH_MESS.Active = 1; + // ??Configure MCCH logical channel // call mac_config_req with appropriate structure from ASN.1 description @@ -368,9 +374,7 @@ init_MCCH (u8 Mod_id) , 0, (MBSFN_AreaInfoList_r9_t *) NULL, - (PMCH_InfoList_r9_t *) & (eNB_rrc_inst[Mod_id]. - mcch_message-> - pmch_InfoList_r9) + (PMCH_InfoList_r9_t *) & (eNB_rrc_inst[Mod_id].mcch_message->pmch_InfoList_r9) #endif #ifdef CBA , 0, 0 @@ -382,23 +386,25 @@ init_MCCH (u8 Mod_id) } void -init_MBMS (u8 Mod_id, u32 frame) -{ // init the configuration for MTCH +init_MBMS (u8 Mod_id, u32 frame) { + // init the configuration for MTCH - if (eNB_rrc_inst[Mod_id].MBMS_flag > 0) - { + if (eNB_rrc_inst[Mod_id].MBMS_flag > 0) { - // LOG_I(RRC,"[eNB %d] Frame %d : Configuring Radio Bearer for MBMS service in MCH[%d]\n", Mod_id, frame,i); //check the lcid + LOG_D(RRC,"[eNB %d] Frame %d : Radio Bearer config request for MBMS\n", Mod_id, frame); //check the lcid // Configuring PDCP and RLC for MBMS Radio Bearer rrc_pdcp_config_asn1_req (Mod_id, frame, 1, 0, NULL, // SRB_ToAddModList NULL, // DRB_ToAddModList - (DRB_ToReleaseList_t *) NULL + (DRB_ToReleaseList_t *) NULL, + 0, // security mode + NULL, // key rrc encryption + NULL, // key rrc integrity + NULL // key encryption #ifdef Rel10 , - &(eNB_rrc_inst[Mod_id].mcch_message-> - pmch_InfoList_r9) + &(eNB_rrc_inst[Mod_id].mcch_message->pmch_InfoList_r9) #endif ); @@ -507,13 +513,29 @@ openair_rrc_lite_eNB_init (u8 Mod_id) init_SI (Mod_id); #ifdef Rel10 - if (eNB_rrc_inst[Mod_id].MBMS_flag > 0) - { - /// MCCH INIT - init_MCCH (Mod_id); - /// MTCH data bearer init - init_MBMS (Mod_id, 0); - } + switch (eNB_rrc_inst[Mod_id].MBMS_flag) { + case 1: + case 2: + case 3: + LOG_I(RRC,"[eNB %d] Configuring 1 MBSFN sync area\n", Mod_id); + eNB_rrc_inst[Mod_id].num_mbsfn_sync_area=1; + break; + case 4: + LOG_I(RRC,"[eNB %d] Configuring 2 MBSFN sync area\n", Mod_id); + eNB_rrc_inst[Mod_id].num_mbsfn_sync_area=2; + break; + default: + eNB_rrc_inst[Mod_id].num_mbsfn_sync_area=0; + break; + } + // if we are here the eNB_rrc_inst[Mod_id].MBMS_flag > 0, + /// MCCH INIT + if (eNB_rrc_inst[Mod_id].MBMS_flag > 0 ) { + init_MCCH (Mod_id); + /// MTCH data bearer init + init_MBMS (Mod_id, 0); + } + #endif #ifdef NO_RRM //init ch SRB0, SRB1 & BDTCH diff --git a/openair2/UTIL/FIFO/types.h b/openair2/UTIL/FIFO/types.h index 5b093147103b693abc02c8f53d22fc85f9244beb..0c630d4c22ae0883ce9e6f3ad47cad32de4a043b 100644 --- a/openair2/UTIL/FIFO/types.h +++ b/openair2/UTIL/FIFO/types.h @@ -32,12 +32,13 @@ typedef struct Signal_buffers { // (s = transmit, r,r0 = receive) /*!\brief sybframe type : DL, UL, SF, */ typedef struct Packet_otg { - unsigned int sdu_buffer_size; - unsigned char *sdu_buffer; - int module_id; - int rb_id; - int dst_id; - u8 mode; + unsigned int sdu_buffer_size; + unsigned char *sdu_buffer; + int module_id; + int rb_id; + int dst_id; + u8 is_ue; + u8 mode; } Packet_otg; typedef struct Event { diff --git a/openair2/UTIL/OCG/OCG.h b/openair2/UTIL/OCG/OCG.h index 05eb1d55e13f87b04aaf08bee64e00b39219a856..2f2f4efbd3512370f53b8e31af640b059830a25e 100644 --- a/openair2/UTIL/OCG/OCG.h +++ b/openair2/UTIL/OCG/OCG.h @@ -662,6 +662,7 @@ The following diagram is based on graphviz (http://www.graphviz.org/), you need unsigned char cba_group_active; char * otg_traffic; unsigned char otg_bg_traffic_enabled; + unsigned char omg_model_rn; unsigned char omg_model_enb; unsigned char omg_model_ue; unsigned char omg_model_ue_current; // when mixed mbility is used diff --git a/openair2/UTIL/OMG/omg.c b/openair2/UTIL/OMG/omg.c index b34e7fb26c9a1ef8778bed7ac8b40de4ad6618df..edbe24bbd7a055a81dd8fbf208b9e7e2c0579bb1 100644 --- a/openair2/UTIL/OMG/omg.c +++ b/openair2/UTIL/OMG/omg.c @@ -147,13 +147,13 @@ void update_nodes(double cur_time){ //LOG_D(OMG, "UPDATE NODES" ); int i = 0; for (i=(STATIC+1); i<MAX_NUM_MOB_TYPES; i++){ - if (Node_Vector[i] != NULL){ - //printf(" Mob model to update is: %d \n ", i); - LOG_I(OMG, " Mob model to update is: %d \n ", i); - update_node_vector(i, cur_time); - } - } - + if (Node_Vector[i] != NULL){ + //printf(" Mob model to update is: %d \n ", i); + LOG_I(OMG, " Mob model to update is: %d \n ", i); + update_node_vector(i, cur_time); + } + } + } @@ -186,7 +186,7 @@ Node_list get_current_positions(int mobility_type, int node_type, double cur_tim switch (mobility_type) { case STATIC: Vector = (Node_list)Node_Vector[STATIC]; - LOG_I(OMG,"static vector %p is \n",Vector); + LOG_T(OMG,"static vector %p is \n",Vector); break; case RWP: get_rwp_positions_updated(cur_time); diff --git a/openair2/UTIL/OMG/omg_constants.h b/openair2/UTIL/OMG/omg_constants.h index c60f365744977be011415e90122a6fe4a95ce8f1..63eb751d837d4fa5a11c16ab773809ec44199535 100644 --- a/openair2/UTIL/OMG/omg_constants.h +++ b/openair2/UTIL/OMG/omg_constants.h @@ -52,7 +52,7 @@ MAX_NUM_MOB_TYPES /*!< The maximum number of mobility models. Used to adjust the typedef enum { eNB=0, /*!< enhanced Node B */ UE, /*!< User Equipement */ -ALL, /*!< All the types. Used to perform the same operations to all the types of nodes */ +ALL /*!< All the types. Used to perform the same operations to all the types of nodes */ }node_types; diff --git a/openair2/UTIL/OMG/trace.c b/openair2/UTIL/OMG/trace.c index d49f7b41e9246f347a08f9b977a5d4b0361b129c..6f5b63fa9d620d314f198d353ef36b8c44a10371 100644 --- a/openair2/UTIL/OMG/trace.c +++ b/openair2/UTIL/OMG/trace.c @@ -166,7 +166,7 @@ void place_trace_node(NodePtr node) { LOG_D(OMG,"--------INITIALIZE TRACE NODE-------- \n "); - LOG_I(OMG,"Initial position of node ID: %d type: %d (X = %.2f, Y = %.2f) speed = 0.0\n ", node->ID, node->type, node->X_pos, node->Y_pos); + LOG_I(OMG,"Initial position of node ID: %d type: %d (X = %.2f, Y = %.2f) speed = %d\n ", node->ID, node->type, node->X_pos, node->Y_pos, node->mob->speed); Node_Vector[TRACE] = (Node_list) add_entry(node, Node_Vector[TRACE]); Node_Vector_len[TRACE]++; diff --git a/openair2/UTIL/OTG/otg_defs.h b/openair2/UTIL/OTG/otg_defs.h index e397a7b94e0dcac6a76c4daf4585b0d28b7f7501..f2c9e29bb9964a3a99f1912d3509b91328f63513 100644 --- a/openair2/UTIL/OTG/otg_defs.h +++ b/openair2/UTIL/OTG/otg_defs.h @@ -62,7 +62,11 @@ typedef enum { NO_PREDEFINED_MULTICAST_TRAFFIC =0, MSCBR, MMCBR, - MBCBR + MBCBR, + MSVBR, + MMVBR, + MBVBR, + MVIDEO_VBR_4MBPS }Multicast_Application; /** @@ -329,7 +333,6 @@ typedef struct { int size_min[NUMBER_OF_eNB_MAX + NUMBER_OF_SERVICE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_SERVICE_MAX][MAX_NUM_APPLICATION]; /*!\brief Min Payload size, for uniform distrib */ int size_max[NUMBER_OF_eNB_MAX + NUMBER_OF_SERVICE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_SERVICE_MAX][MAX_NUM_APPLICATION]; /*!\brief payload, Max Inter Departure Time, for uniform distrib */ - }otg_multicast_t; @@ -483,6 +486,10 @@ typedef struct { unsigned int rx_total_bytes_dl; + /*TARMA parameteres*/ + tarmaStream_t *mtarma_stream[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; + tarmaVideo_t *mtarma_video[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; + }otg_multicast_info_t; diff --git a/openair2/UTIL/OTG/otg_tx.c b/openair2/UTIL/OTG/otg_tx.c index 7e7058a83c105409adcde350c3cd11668588a62d..0f7cbff3612938175a1b1633b777a10ba761b663 100644 --- a/openair2/UTIL/OTG/otg_tx.c +++ b/openair2/UTIL/OTG/otg_tx.c @@ -435,7 +435,7 @@ int check_data_transmit(int src,int dst, int app, int ctime){ otg_info->ptime[src][dst][app]=ctime; if (state==PE_STATE) //compute the IDT only for PE STATE - tarmaUpdateInputSample(otg_info->tarma_stream[src][dst][app]); + tarmaUpdateInputSample(otg_info->tarma_stream[src][dst][app]); otg_info->idt[src][dst][app]=time_dist(src, dst, app,state); otg_info->gen_pkts=1; header_size_gen(src,dst, app); @@ -662,27 +662,134 @@ unsigned char * serialize_buffer(char* header, char* payload, unsigned int buffe void init_predef_multicast_traffic() { int i, j, k; -for (i=0; i<1; i++){ // src //maxServiceCount - for (j=1; j<2; j++){ // dst // maxSessionPerPMCH +for (i=0; i<2; i++){ // src //maxServiceCount + for (j=1; j<3; j++){ // dst // maxSessionPerPMCH for (k=0; k<1/*MAX_NUM_APPLICATION*/; k++){ switch(g_otg_multicast->application_type[i][j][k]){ - case MSCBR : - //LOG_D(OTG, "configure MSCBR for MBMS (service %d, session %d, app %d)\n", i, j, k); - g_otg_multicast->trans_proto[i][j][k]= UDP; - g_otg_multicast->ip_v[i][j][k]= IPV4; - - g_otg_multicast->idt_dist[i][j][k]= UNIFORM; - g_otg_multicast->idt_min[i][j][k]= 20;// can modify here to increase the frequency of generate data - g_otg_multicast->idt_max[i][j][k]= 50; - - g_otg_multicast->size_dist[i][j][k]= UNIFORM; - g_otg_multicast->size_min[i][j][k]= 768; - g_otg_multicast->size_max[i][j][k]= 1024 ;//can not be greater than 1500 which is max_ip_packet_size in pdcp.c - - - g_otg_multicast->duration[i][j][k] = 1000; // the packet will be generated after duration - header_size_gen_multicast(i,j,k); - break; + case MSCBR : + LOG_D(OTG, "configure MSCBR for eMBMS (service %d, session %d, app %d)\n", i, j, k); + g_otg_multicast->trans_proto[i][j][k]= UDP; + g_otg_multicast->ip_v[i][j][k]= IPV4; + + g_otg_multicast->idt_dist[i][j][k]= FIXED; + g_otg_multicast->idt_min[i][j][k]= 40;// can modify here to increase the frequency of generate data + g_otg_multicast->idt_max[i][j][k]= 40; + + g_otg_multicast->size_dist[i][j][k]= FIXED; + g_otg_multicast->size_min[i][j][k]= 256; + g_otg_multicast->size_max[i][j][k]= 256;//can not be greater than 1500 which is max_ip_packet_size in pdcp.c + + + g_otg_multicast->duration[i][j][k] = 1000; // the packet will be generated after duration + header_size_gen_multicast(i,j,k); + break; + case MMCBR : + LOG_D(OTG, "configure MSCBR for eMBMS (service %d, session %d, app %d)\n", i, j, k); + g_otg_multicast->trans_proto[i][j][k]= UDP; + g_otg_multicast->ip_v[i][j][k]= IPV4; + + g_otg_multicast->idt_dist[i][j][k]= FIXED; + g_otg_multicast->idt_min[i][j][k]= 30;// can modify here to increase the frequency of generate data + g_otg_multicast->idt_max[i][j][k]= 40; + + g_otg_multicast->size_dist[i][j][k]= FIXED; + g_otg_multicast->size_min[i][j][k]= 768; + g_otg_multicast->size_max[i][j][k]= 768 ;//can not be greater than 1500 which is max_ip_packet_size in pdcp.c + + + g_otg_multicast->duration[i][j][k] = 1000; // the packet will be generated after duration + header_size_gen_multicast(i,j,k); + break; + case MBCBR : + LOG_D(OTG, "configure MSCBR for eMBMS (service %d, session %d, app %d)\n", i, j, k); + g_otg_multicast->trans_proto[i][j][k]= UDP; + g_otg_multicast->ip_v[i][j][k]= IPV4; + + g_otg_multicast->idt_dist[i][j][k]=FIXED; + g_otg_multicast->idt_min[i][j][k]= 20;// can modify here to increase the frequency of generate data + g_otg_multicast->idt_max[i][j][k]= 20; + + g_otg_multicast->size_dist[i][j][k]= FIXED; + g_otg_multicast->size_min[i][j][k]= 1400; + g_otg_multicast->size_max[i][j][k]= 1400 ;//can not be greater than 1500 which is max_ip_packet_size in pdcp.c + + + g_otg_multicast->duration[i][j][k] = 1000; // the packet will be generated after duration + header_size_gen_multicast(i,j,k); + break; + + case MSVBR: + LOG_D(OTG, "configure MSCBR for eMBMS (service %d, session %d, app %d)\n", i, j, k); + g_otg_multicast->trans_proto[i][j][k]= UDP; + g_otg_multicast->ip_v[i][j][k]= IPV4; + + g_otg_multicast->idt_dist[i][j][k]=UNIFORM; + g_otg_multicast->idt_min[i][j][k]= 20;// can modify here to increase the frequency of generate data + g_otg_multicast->idt_max[i][j][k]= 40; + + g_otg_multicast->size_dist[i][j][k]= UNIFORM; + g_otg_multicast->size_min[i][j][k]= 64; + g_otg_multicast->size_max[i][j][k]= 512 ;//can not be greater than 1500 which is max_ip_packet_size in pdcp.c + + + g_otg_multicast->duration[i][j][k] = 1000; // the packet will be generated after duration + header_size_gen_multicast(i,j,k); + break; + + case MMVBR: + LOG_D(OTG, "configure MSCBR for eMBMS (service %d, session %d, app %d)\n", i, j, k); + g_otg_multicast->trans_proto[i][j][k]= UDP; + g_otg_multicast->ip_v[i][j][k]= IPV4; + + g_otg_multicast->idt_dist[i][j][k]=UNIFORM; + g_otg_multicast->idt_min[i][j][k]= 15;// can modify here to increase the frequency of generate data + g_otg_multicast->idt_max[i][j][k]= 30; + + g_otg_multicast->size_dist[i][j][k]= UNIFORM; + g_otg_multicast->size_min[i][j][k]= 512; + g_otg_multicast->size_max[i][j][k]= 1024 ;//can not be greater than 1500 which is max_ip_packet_size in pdcp.c + + + g_otg_multicast->duration[i][j][k] = 1000; // the packet will be generated after duration + header_size_gen_multicast(i,j,k); + break; + + case MBVBR: + LOG_D(OTG, "configure MSCBR for eMBMS (service %d, session %d, app %d)\n", i, j, k); + g_otg_multicast->trans_proto[i][j][k]= UDP; + g_otg_multicast->ip_v[i][j][k]= IPV4; + + g_otg_multicast->idt_dist[i][j][k]=UNIFORM; + g_otg_multicast->idt_min[i][j][k]= 5;// can modify here to increase the frequency of generate data + g_otg_multicast->idt_max[i][j][k]= 15; + + g_otg_multicast->size_dist[i][j][k]= UNIFORM; + g_otg_multicast->size_min[i][j][k]= 1024; + g_otg_multicast->size_max[i][j][k]= 1400 ;//can not be greater than 1500 which is max_ip_packet_size in pdcp.c + + + g_otg_multicast->duration[i][j][k] = 1000; // the packet will be generated after duration + header_size_gen_multicast(i,j,k); + break; + + case MVIDEO_VBR_4MBPS : + + LOG_D(OTG,"Configure MSCBR for eMBMS (service %d, session %d, app %d)\n", i, j, k); + g_otg_multicast->trans_proto[i][j][k]= UDP; + g_otg_multicast->ip_v[i][j][k]= IPV4; + + g_otg_multicast->idt_dist[i][j][k]= FIXED; + g_otg_multicast->idt_min[i][j][k]= 40;// can modify here to increase the frequency of generate data + g_otg_multicast->idt_max[i][j][k]= 40; + + /*the tarma initialization*/ + otg_multicast_info->mtarma_video[i][j][k]=tarmaInitVideo(0); + tarmaSetupVideoGop12(otg_multicast_info->mtarma_video[i][j][k],2.5); + LOG_I(OTG,"[CONFIG] Multicast Video VBR 4MBPS, src = %d, dst = %d, dist IDT = %d\n", i, j, g_otg_multicast->idt_dist[i][j][k]); + + //g_otg_multicast->duration[i][j][k] = 1000; // the packet will be generated after duration + header_size_gen_multicast(i,j,k); + break; default : LOG_W(OTG, "not supported model for multicast traffic\n"); diff --git a/targets/RTAI/USER/lte-softmodem.c b/targets/RTAI/USER/lte-softmodem.c index 1727f4c7692c92571eb37afefd7dd30d35ae8b0b..547bf955aab74810d5a7cd96499a3437ba918e5b 100644 --- a/targets/RTAI/USER/lte-softmodem.c +++ b/targets/RTAI/USER/lte-softmodem.c @@ -559,7 +559,7 @@ static void *eNB_thread(void *arg) if (fs4_test==0) { - phy_procedures_eNB_lte (last_slot, next_slot, PHY_vars_eNB_g[0], 0, 0); + phy_procedures_eNB_lte (last_slot, next_slot, PHY_vars_eNB_g[0], 0, 0,NULL); #ifndef IFFT_FPGA slot_offset_F = (next_slot)* (PHY_vars_eNB_g[0]->lte_frame_parms.ofdm_symbol_size)* @@ -781,7 +781,7 @@ static void *UE_thread(void *arg) */ in = rt_get_time_ns(); - phy_procedures_UE_lte (last_slot, next_slot, PHY_vars_UE_g[0], 0, 0,mode,0); + phy_procedures_UE_lte (last_slot, next_slot, PHY_vars_UE_g[0], 0, 0,mode,0,NULL); out = rt_get_time_ns(); diff = out-in; diff --git a/targets/SIMU/EXAMPLES/OSD/WEBXML/template_43.xml b/targets/SIMU/EXAMPLES/OSD/WEBXML/template_43.xml new file mode 100644 index 0000000000000000000000000000000000000000..f4a95c2a2ae1fd342e745fe6f204fbcb787215e3 --- /dev/null +++ b/targets/SIMU/EXAMPLES/OSD/WEBXML/template_43.xml @@ -0,0 +1,70 @@ +<OAI_EMULATION> +- + <ENVIRONMENT_SYSTEM_CONFIG> + <FADING> + <LARGE_SCALE>urban</LARGE_SCALE> + <FREE_SPACE_MODEL_PARAMETERS> + <PATHLOSS_EXPONENT>3.67</PATHLOSS_EXPONENT> + <PATHLOSS_0_dB>-111</PATHLOSS_0_dB> + </FREE_SPACE_MODEL_PARAMETERS> + <SMALL_SCALE>Rayleigh1</SMALL_SCALE> + </FADING> + <SYSTEM_BANDWIDTH_MB>7.68</SYSTEM_BANDWIDTH_MB> + <SYSTEM_FREQUENCY_GHz>1.9</SYSTEM_FREQUENCY_GHz> + <TRANSMISSION_MODE>1</TRANSMISSION_MODE> + <ANTENNA> + <eNB_ANTENNA> + <RX_NOISE_LEVEL_dB>0</RX_NOISE_LEVEL_dB> + <NUMBER_OF_SECTORS>1</NUMBER_OF_SECTORS> + <BEAM_WIDTH_dB>0</BEAM_WIDTH_dB> + <ANTENNA_GAIN_dBi>0</ANTENNA_GAIN_dBi> + <TX_POWER_dBm>15</TX_POWER_dBm> + </eNB_ANTENNA> + <UE_ANTENNA> + <RX_NOISE_LEVEL_dB>0</RX_NOISE_LEVEL_dB> + <ANTENNA_GAIN_dBi>0</ANTENNA_GAIN_dBi> + <TX_POWER_dBm>20</TX_POWER_dBm> + </UE_ANTENNA> + </ANTENNA> + </ENVIRONMENT_SYSTEM_CONFIG> + + <TOPOLOGY_CONFIG> + <AREA> + <X_m>800</X_m> + <Y_m>800</Y_m> + </AREA> + <MOBILITY> + <UE_MOBILITY> + <UE_INITIAL_DISTRIBUTION>random</UE_INITIAL_DISTRIBUTION> + <RANDOM_UE_DISTRIBUTION> + <NUMBER_OF_NODES>1</NUMBER_OF_NODES> + </RANDOM_UE_DISTRIBUTION> + <UE_MOBILITY_TYPE>TRACE</UE_MOBILITY_TYPE> + <TRACE_MOBILITY_FILE>static_1ue.tr</TRACE_MOBILITY_FILE> + </UE_MOBILITY> + <eNB_MOBILITY> + <eNB_INITIAL_DISTRIBUTION>random</eNB_INITIAL_DISTRIBUTION> + <RANDOM_eNB_DISTRIBUTION> + <NUMBER_OF_CELLS>1</NUMBER_OF_CELLS> + </RANDOM_eNB_DISTRIBUTION> + <eNB_MOBILITY_TYPE>STATIC</eNB_MOBILITY_TYPE> + </eNB_MOBILITY> + </MOBILITY> + </TOPOLOGY_CONFIG> + + + <EMULATION_CONFIG> + <EMULATION_TIME_ms>1200</EMULATION_TIME_ms> + <CURVE>disable</CURVE> + + <LOG> <!-- set the global log level --> + <LEVEL>info</LEVEL> + <VERBOSITY>low</VERBOSITY> <!-- low, medium, high, full --> + <INTERVAL>1</INTERVAL> + </LOG> + <SEED_VALUE>69</SEED_VALUE> <!-- value 0 means randomly generated by OAI --> + + </EMULATION_CONFIG> + + <PROFILE>eMBMS_OMG_REF_1</PROFILE> +</OAI_EMULATION> diff --git a/targets/SIMU/USER/channel_sim.c b/targets/SIMU/USER/channel_sim.c index 888a7a3cfd6e557ec2e686e43f36d474519984fb..1323a67929d27a0320e3264ab3cbca53dae0606a 100644 --- a/targets/SIMU/USER/channel_sim.c +++ b/targets/SIMU/USER/channel_sim.c @@ -59,7 +59,7 @@ void do_OFDM_mod(mod_sym_t **txdataF, s32 **txdata, uint32_t frame,u16 next_slot for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) { if (is_pmch_subframe(frame,next_slot>>1,frame_parms)) { if ((next_slot%2)==0) { - printf("MBSFN eNB sim: Frame %d, subframe %d: Doing MBSFN modulation (slot_offset %d)\n",frame,next_slot>>1,slot_offset); + LOG_D(OCM,"Frame %d, subframe %d: Doing MBSFN modulation (slot_offset %d)\n",frame,next_slot>>1,slot_offset); PHY_ofdm_mod(&txdataF[aa][slot_offset_F], // input &txdata[aa][slot_offset], // output frame_parms->log2_symbol_size, // log2_fft_size @@ -79,7 +79,7 @@ void do_OFDM_mod(mod_sym_t **txdataF, s32 **txdata, uint32_t frame,u16 next_slot frame_parms->rev, // bit-reversal permutation CYCLIC_PREFIX); else { - printf("MBSFN eNB sim: Frame %d, subframe %d: Doing PDCCH modulation\n",frame,next_slot>>1); + LOG_D(OCM,"Frame %d, subframe %d: Doing PDCCH modulation\n",frame,next_slot>>1); normal_prefix_mod(&txdataF[aa][slot_offset_F], &txdata[aa][slot_offset], 2, diff --git a/targets/SIMU/USER/init_lte.c b/targets/SIMU/USER/init_lte.c index e983681ae5c139f9aa9772a970bf1bf191de94e1..cbea8a60df94f78d3e9d03fb16b703009f3221b7 100644 --- a/targets/SIMU/USER/init_lte.c +++ b/targets/SIMU/USER/init_lte.c @@ -59,9 +59,7 @@ PHY_VARS_eNB* init_lte_eNB(LTE_DL_FRAME_PARMS *frame_parms, exit(-1); } - PHY_vars_eNB->dlsch_eNB_MCH = new_eNB_dlsch(1,NUMBER_OF_HARQ_PID_MAX,frame_parms->N_RB_DL, 0); - - // this is the transmission mode for the signalling channels + // this is the transmission mode for the signalling channels // this will be overwritten with the real transmission mode by the RRC once the UE is connected PHY_vars_eNB->transmission_mode[i] = transmission_mode; @@ -78,7 +76,10 @@ PHY_VARS_eNB* init_lte_eNB(LTE_DL_FRAME_PARMS *frame_parms, LOG_D(PHY,"eNB %d : SI %p\n",eNB_id,PHY_vars_eNB->dlsch_eNB_SI); PHY_vars_eNB->dlsch_eNB_ra = new_eNB_dlsch(1,1,frame_parms->N_RB_DL, abstraction_flag); LOG_D(PHY,"eNB %d : RA %p\n",eNB_id,PHY_vars_eNB->dlsch_eNB_ra); - + PHY_vars_eNB->dlsch_eNB_MCH = new_eNB_dlsch(1,NUMBER_OF_HARQ_PID_MAX,frame_parms->N_RB_DL, 0); + LOG_D(PHY,"eNB %d : MCH %p\n",eNB_id,PHY_vars_eNB->dlsch_eNB_MCH); + + PHY_vars_eNB->rx_total_gain_eNB_dB=140; for(i=0;i<NUMBER_OF_UE_MAX;i++) @@ -138,7 +139,26 @@ PHY_VARS_UE* init_lte_UE(LTE_DL_FRAME_PARMS *frame_parms, return (PHY_vars_UE); } - +PHY_VARS_RN* init_lte_RN(LTE_DL_FRAME_PARMS *frame_parms, + u8 RN_id, + u8 eMBMS_active_state) { + + int i; + PHY_VARS_RN* PHY_vars_RN = malloc(sizeof(PHY_VARS_RN)); + memset(PHY_vars_RN,0,sizeof(PHY_VARS_RN)); + PHY_vars_RN->Mod_id=RN_id; + + if (eMBMS_active_state == multicast_relay) { + for (i=0; i < 10 ; i++){ // num SF in a frame + PHY_vars_RN->dlsch_rn_MCH[i] = new_ue_dlsch(1,1,MAX_TURBO_ITERATIONS_MBSFN,frame_parms->N_RB_DL, 0); + LOG_D(PHY,"eNB %d : MCH[%d] %p\n",RN_id,i,PHY_vars_RN->dlsch_rn_MCH[i]); + } + } else { + PHY_vars_RN->dlsch_rn_MCH[0] = new_ue_dlsch(1,1,MAX_TURBO_ITERATIONS,frame_parms->N_RB_DL, 0); + LOG_D(PHY,"eNB %d : MCH[0] %p\n",RN_id,PHY_vars_RN->dlsch_rn_MCH[0]); + } + return (PHY_vars_RN); +} void init_lte_vars(LTE_DL_FRAME_PARMS **frame_parms, u8 frame_type, u8 tdd_config, @@ -147,9 +167,9 @@ void init_lte_vars(LTE_DL_FRAME_PARMS **frame_parms, u8 N_RB_DL, u16 Nid_cell, u8 cooperation_flag,u8 transmission_mode,u8 abstraction_flag, - int nb_antennas_rx) { + int nb_antennas_rx, u8 eMBMS_active_state) { - u8 eNB_id,UE_id; + u8 eNB_id,UE_id,RN_id; mac_xface = malloc(sizeof(MAC_xface)); @@ -192,9 +212,15 @@ void init_lte_vars(LTE_DL_FRAME_PARMS **frame_parms, (*frame_parms)->nb_antennas_rx = nb_antennas_rx; PHY_vars_UE_g = malloc(NB_UE_INST*sizeof(PHY_VARS_UE*)); - for (UE_id=0; UE_id<NB_UE_INST;UE_id++){ // begin navid + for (UE_id=0; UE_id<NB_UE_INST;UE_id++){ PHY_vars_UE_g[UE_id] = init_lte_UE(*frame_parms, UE_id,abstraction_flag,transmission_mode); - } + if (NB_RN_INST > 0) { + PHY_vars_RN_g = malloc(NB_RN_INST*sizeof(PHY_VARS_RN*)); + for (RN_id=0; RN_id<NB_RN_INST;RN_id++){ + PHY_vars_RN_g[RN_id] = init_lte_RN(*frame_parms,RN_id,eMBMS_active_state); + } + } + } diff --git a/targets/SIMU/USER/init_lte.h b/targets/SIMU/USER/init_lte.h index 17b583e2e872799699a12dc2c64468b90043742c..9920ba17455b6345eb88f66c49eef51caa3c7fcd 100644 --- a/targets/SIMU/USER/init_lte.h +++ b/targets/SIMU/USER/init_lte.h @@ -13,6 +13,9 @@ PHY_VARS_UE* init_lte_UE(LTE_DL_FRAME_PARMS *frame_parms, u8 abstraction_flag, u8 transmission_mode); +PHY_VARS_RN* init_lte_RN(LTE_DL_FRAME_PARMS *frame_parms, + u8 RN_id, + u8 eMBMS_active_state); void init_lte_vars(LTE_DL_FRAME_PARMS **frame_parms, u8 frame_type, @@ -24,4 +27,5 @@ void init_lte_vars(LTE_DL_FRAME_PARMS **frame_parms, u8 cooperation_flag, u8 transmission_mode, u8 abstraction_flag, - int nb_antennas_rx); + int nb_antennas_rx, + u8 eMBMS_active_state); diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index 728868633c68baa5fae57036c832a578ee1769fd..5438d461380987c09ed2ce5c578b159ff61f0661 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -329,7 +329,7 @@ int omv_write (int pfd, Node_list enb_node_list, Node_list ue_node_list, Data_F } } } - + LOG_E(OMG,"pfd %d \n", pfd); if( write( pfd, &omv_data, sizeof(struct Data_Flow_Unit) ) == -1 ) perror( "write omv failed" ); return 1; @@ -343,16 +343,16 @@ void omv_end (int pfd, Data_Flow_Unit omv_data) { #endif Packet_OTG_List *otg_pdcp_buffer; +#ifdef OPENAIR2 + int pfd[2]; // fd for omv : fixme: this could be a local var +#endif + +int main (int argc, char **argv) { -int - main (int argc, char **argv) -{ s32 i; // pointers signal buffers (s = transmit, r,r0 = receive) - clock_t t; - // Framing variables s32 slot, last_slot, next_slot; @@ -373,9 +373,7 @@ int lte_subframe_t direction; -#ifdef OPENAIR2 - int pfd[2]; // fd for omv : fixme: this could be a local var -#endif + char fname[64],vname[64]; // u8 awgn_flag = 0; @@ -420,8 +418,8 @@ int //Default values if not changed by the user in get_simulation_options(); pdcp_period = 1; - omg_period = 10; - // start thread for log gen + omg_period = 1; + // start thread for log gen log_thread_init(); init_oai_emulation(); // to initialize everything !!! @@ -448,14 +446,20 @@ int // configure oaisim with OCG oaisim_config(); // config OMG and OCG, OPT, OTG, OLG + if (ue_connection_test == 1) { + snr_direction = -snr_step; + snr_dB=20; + sinr_dB=-20; + } + #ifdef OPENAIR2 init_omv(); -#endif + #endif //Before this call, NB_UE_INST and NB_eNB_INST are not set correctly + check_and_adjust_params(); - - init_otg_pdcp_buffer(); - + + #ifdef PRINT_STATS for (UE_id=0;UE_id<NB_UE_INST;UE_id++) { sprintf(UE_stats_filename,"UE_stats%d.txt",UE_id); @@ -487,31 +491,11 @@ int #endif #endif - - if (NB_RN_INST > 0 ) { - LOG_N(EMU,"Total number of RN %d (local %d, remote %d) mobility (the same as eNB) %s \n", NB_RN_INST,oai_emulation.info.nb_rn_local,oai_emulation.info.nb_rn_remote, oai_emulation.topology_config.mobility.eNB_mobility.eNB_mobility_type.selected_option); - - LOG_N(EMU,"Adjust the number of eNB inst (%d->%d) and UE inst (%d->%d)\n ", - NB_eNB_INST, NB_eNB_INST+NB_RN_INST, - NB_UE_INST, NB_UE_INST+NB_RN_INST); - NB_eNB_INST+=NB_RN_INST; - NB_UE_INST+=NB_RN_INST; - } - LOG_I(EMU,"Total number of UE %d (local %d, remote %d, relay %d) mobility %s \n", - NB_UE_INST,oai_emulation.info.nb_ue_local,oai_emulation.info.nb_ue_remote, - NB_RN_INST, - oai_emulation.topology_config.mobility.eNB_mobility.eNB_mobility_type.selected_option); - - LOG_I(EMU,"Total number of eNB %d (local %d, remote %d, relay %d) mobility %s \n", - NB_eNB_INST,oai_emulation.info.nb_enb_local,oai_emulation.info.nb_enb_remote, - NB_RN_INST, - oai_emulation.topology_config.mobility.UE_mobility.UE_mobility_type.selected_option); - - LOG_I(OCM,"Running with frame_type %d, Nid_cell %d, N_RB_DL %d, EP %d, mode %d, target dl_mcs %d, rate adaptation %d, nframes %d, abstraction %d, channel %s\n", - oai_emulation.info.frame_type, Nid_cell, oai_emulation.info.N_RB_DL, oai_emulation.info.extended_prefix_flag, oai_emulation.info.transmission_mode,target_dl_mcs,rate_adaptation_flag,oai_emulation.info.n_frames,abstraction_flag,oai_emulation.environment_system_config.fading.small_scale.selected_option); set_seed = oai_emulation.emulation_config.seed.value; + init_otg_pdcp_buffer(); + init_seed(set_seed); init_openair1(); @@ -551,23 +535,13 @@ int init_time(); - LOG_I(EMU,">>>>>>>>>>>>>>>>>>>>>>>>>>> OAIEMU initialization done <<<<<<<<<<<<<<<<<<<<<<<<<<\n\n"); - LOG_I (EMU,"after init: Nid_cell %d\n", PHY_vars_eNB_g[0]->lte_frame_parms.Nid_cell); - LOG_I(EMU,"after init: frame_type %d,tdd_config %d\n", - PHY_vars_eNB_g[0]->lte_frame_parms.frame_type, - PHY_vars_eNB_g[0]->lte_frame_parms.tdd_config); - - - if (ue_connection_test == 1) { - snr_direction = -snr_step; - snr_dB=20; - sinr_dB=-20; - } - init_slot_isr(); - + t = clock(); + LOG_N(EMU,"\n\n>>>>>>>>>>>>>>>>>>>>>>>>>>> OAIEMU initialization done <<<<<<<<<<<<<<<<<<<<<<<<<<\n\n"); + + for (frame=0; frame<oai_emulation.info.n_frames; frame++) { /* // Handling the cooperation Flag @@ -658,7 +632,8 @@ int pdcp_run(frame, 1, 0, eNB_id);//PHY_vars_eNB_g[eNB_id]->Mod_id // PHY_vars_eNB_g[eNB_id]->frame = frame; - phy_procedures_eNB_lte (last_slot, next_slot, PHY_vars_eNB_g[eNB_id], abstraction_flag, no_relay); + phy_procedures_eNB_lte (last_slot, next_slot, PHY_vars_eNB_g[eNB_id], abstraction_flag, + no_relay,NULL); #ifdef PRINT_STATS if(last_slot==9 && frame%10==0) @@ -704,7 +679,8 @@ int //Access layer pdcp_run(frame, 0, UE_id, 0); - phy_procedures_UE_lte (last_slot, next_slot, PHY_vars_UE_g[UE_id], 0, abstraction_flag,normal_txrx, no_relay); + phy_procedures_UE_lte (last_slot, next_slot, PHY_vars_UE_g[UE_id], 0, abstraction_flag,normal_txrx, + no_relay,NULL); ue_data[UE_id]->tx_power_dBm = PHY_vars_UE_g[UE_id]->tx_power_dBm; } } @@ -759,6 +735,7 @@ int LOG_E(EMU,"Not supported eMBMS option when relaying is enabled %d\n", r_type); exit(-1); } + PHY_vars_RN_g[RN_id]->frame = frame; if ( oai_emulation.info.frame_type == 0) { // RN == UE if (frame>0) { @@ -766,17 +743,17 @@ int LOG_D(EMU,"[RN %d] PHY procedures UE %d for frame %d, slot %d (subframe TX %d, RX %d)\n", RN_id, UE_id, frame, slot, next_slot >> 1,last_slot>>1); PHY_vars_UE_g[UE_id]->frame = frame; - phy_procedures_UE_lte (last_slot, next_slot, PHY_vars_UE_g[UE_id], 0, abstraction_flag,normal_txrx, r_type); + phy_procedures_UE_lte (last_slot, next_slot, PHY_vars_UE_g[UE_id], 0, abstraction_flag,normal_txrx, + r_type, PHY_vars_RN_g[RN_id]); } else if (last_slot == (LTE_SLOTS_PER_FRAME-2)) { initial_sync(PHY_vars_UE_g[UE_id],normal_txrx); } } - // RN == eNB LOG_D(EMU,"[RN %d] PHY procedures eNB %d for frame %d, slot %d (subframe TX %d, RX %d)\n", RN_id, eNB_id, frame, slot, next_slot >> 1,last_slot>>1); - phy_procedures_eNB_lte (last_slot, next_slot, PHY_vars_eNB_g[eNB_id], abstraction_flag, r_type); - + phy_procedures_eNB_lte (last_slot, next_slot, PHY_vars_eNB_g[eNB_id], abstraction_flag, + r_type, PHY_vars_RN_g[RN_id]); } else{ LOG_E(EMU,"TDD is not supported for multicast relaying %d\n", r_type); diff --git a/targets/SIMU/USER/oaisim_config.c b/targets/SIMU/USER/oaisim_config.c index c9c124aad2f57714c550268c89a6e33179b3b54d..0e3b410876c98da50eec1c53b8ed1a1e14127af0 100644 --- a/targets/SIMU/USER/oaisim_config.c +++ b/targets/SIMU/USER/oaisim_config.c @@ -50,6 +50,12 @@ mapping omg_model_names[] = mapping otg_multicast_app_type_names[] = { {"no_predefined_multicast_traffic", 0}, {"mscbr", 1}, + {"mmcbr", 2}, + {"mbcbr", 3}, + {"msvbr", 4}, + {"mmvbr", 5}, + {"mbvbr", 6}, + {"mvideo_vbr_4mbps", 7}, {NULL, -1} } ; @@ -150,8 +156,8 @@ void init_oai_emulation() { int i; oai_emulation.environment_system_config.fading.large_scale.selected_option = "free_space"; - oai_emulation.environment_system_config.fading.free_space_model_parameters.pathloss_exponent = 2.0; - oai_emulation.environment_system_config.fading.free_space_model_parameters.pathloss_0_dB = -50; + oai_emulation.environment_system_config.fading.free_space_model_parameters.pathloss_exponent = 3.00; + oai_emulation.environment_system_config.fading.free_space_model_parameters.pathloss_0_dB = -100; oai_emulation.environment_system_config.fading.small_scale.selected_option = "AWGN"; oai_emulation.environment_system_config.fading.ricean_8tap.rice_factor_dB = 0; oai_emulation.environment_system_config.fading.shadowing.decorrelation_distance_m = 0; @@ -163,14 +169,14 @@ void init_oai_emulation() { oai_emulation.environment_system_config.antenna.eNB_antenna.alpha_rad[2] = 0; oai_emulation.environment_system_config.antenna.eNB_antenna.alpha_rad[3] = 0; oai_emulation.environment_system_config.antenna.eNB_antenna.antenna_gain_dBi = 0; - oai_emulation.environment_system_config.antenna.eNB_antenna.tx_power_dBm = 43; + oai_emulation.environment_system_config.antenna.eNB_antenna.tx_power_dBm = 15; oai_emulation.environment_system_config.antenna.eNB_antenna.rx_noise_level_dB = 0; oai_emulation.environment_system_config.antenna.eNB_antenna.antenna_orientation_degree[1] = 0; oai_emulation.environment_system_config.antenna.eNB_antenna.antenna_orientation_degree[2] = 0; oai_emulation.environment_system_config.antenna.eNB_antenna.antenna_orientation_degree[3] = 0; oai_emulation.environment_system_config.antenna.UE_antenna.antenna_gain_dBi = 0; oai_emulation.environment_system_config.antenna.UE_antenna.tx_power_dBm = 20; - oai_emulation.environment_system_config.antenna.UE_antenna.rx_noise_level_dB = 0; + oai_emulation.environment_system_config.antenna.UE_antenna.rx_noise_level_dB = 0; // noise figure oai_emulation.environment_system_config.wall_penetration_loss_dB = 5; oai_emulation.environment_system_config.system_bandwidth_MB = 7.68; oai_emulation.environment_system_config.system_frequency_GHz = 1.9; @@ -320,9 +326,9 @@ void init_oai_emulation() { oai_emulation.info.cba_group_active=0; oai_emulation.info.eMBMS_active_state=0; oai_emulation.info.omg_model_enb=STATIC; //default to static mobility model + oai_emulation.info.omg_model_rn=STATIC; //default to static mobility model oai_emulation.info.omg_model_ue=STATIC; //default to static mobility model oai_emulation.info.omg_model_ue_current=STATIC; //default to static mobility model - oai_emulation.info.otg_enabled=0;// T flag with arg oai_emulation.info.otg_bg_traffic_enabled = 0; // G flag oai_emulation.info.frame = 0; // frame counter of emulation oai_emulation.info.time_s = 0; // time of emulation @@ -490,7 +496,7 @@ int ocg_config_topo() { // init OMG for eNBs if ((oai_emulation.info.omg_model_enb = map_str_to_int(omg_model_names, oai_emulation.topology_config.mobility.eNB_mobility.eNB_mobility_type.selected_option))== -1) - oai_emulation.info.omg_model_ue = STATIC; + oai_emulation.info.omg_model_enb = STATIC; LOG_I(OMG,"eNB mobility model is (%s, %d)\n", oai_emulation.topology_config.mobility.eNB_mobility.eNB_mobility_type.selected_option, oai_emulation.info.omg_model_enb); @@ -506,14 +512,15 @@ int ocg_config_topo() { } omg_param_list.mobility_type = oai_emulation.info.omg_model_enb; - omg_param_list.nodes_type = eNB; //eNB - omg_param_list.nodes = oai_emulation.info.nb_enb_local; + omg_param_list.nodes_type = eNB; //eNB or eNB + RN + omg_param_list.nodes = oai_emulation.info.nb_enb_local + oai_emulation.info.nb_rn_local; omg_param_list.seed = oai_emulation.info.seed; // specific seed for enb and ue to avoid node overlapping // at this moment, we use the above moving dynamics for mobile eNB if (omg_param_list.nodes >0 ) init_mobility_generator(omg_param_list); + // init OMG for UE // input of OMG: STATIC: 0, RWP: 1, RWALK 2, or TRACE 3, or SUMO if ((oai_emulation.info.omg_model_ue = map_str_to_int(omg_model_names, oai_emulation.topology_config.mobility.UE_mobility.UE_mobility_type.selected_option))== -1) @@ -523,7 +530,7 @@ int ocg_config_topo() { oai_emulation.info.omg_model_ue); omg_param_list.mobility_type = oai_emulation.info.omg_model_ue; omg_param_list.nodes_type = UE;//UE - omg_param_list.nodes = oai_emulation.info.nb_ue_local; + omg_param_list.nodes = oai_emulation.info.nb_ue_local+ oai_emulation.info.nb_rn_local; omg_param_list.seed = oai_emulation.info.seed + oai_emulation.info.nb_ue_local; //fixme: specific seed for enb and ue to avoid node overlapping omg_param_list.min_speed = (oai_emulation.topology_config.mobility.UE_mobility.UE_moving_dynamics.min_speed_mps == 0) ? 0.1 : oai_emulation.topology_config.mobility.UE_mobility.UE_moving_dynamics.min_speed_mps; @@ -955,7 +962,8 @@ g_otg->application_idx[source_id_index][destination_id_index]+=1; } } - } else { // OCG not used, but -T option is used, so config here + } + if ( oai_emulation.info.otg_enabled==1){ // OCG not used, but -T option is used, so config here LOG_I(OTG,"configure OTG through options %s\n", oai_emulation.info.otg_traffic); for (i=0; i<g_otg->num_nodes; i++){ for (j=0; j<g_otg->num_nodes; j++){ @@ -978,7 +986,7 @@ g_otg->application_idx[source_id_index][destination_id_index]+=1; } } init_predef_multicast_traffic(); - LOG_I(OTG,"initilizae multicast traffic \n"); + LOG_I(OTG,"initilizae multicast traffic %s\n",oai_emulation.info.otg_traffic); } return 1; diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index aaa1f3c6f66fb4b49cb35bdcbf7e3452cee2af08..7354c2d2746e8bdd61260e277c10a3b38a26a747 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -74,7 +74,7 @@ int td, td_avg, sleep_time_us; // omv related info //pid_t omv_pid; char full_name[200]; -int pfd[2]; // fd for omv : fixme: this could be a local var +extern int pfd[2]; // fd for omv : fixme: this could be a local var char fdstr[10]; char frames[10]; char num_enb[10]; @@ -110,7 +110,7 @@ void get_simulation_options(int argc, char *argv[]) { {NULL, 0, NULL, 0} }; - while ((c = getopt_long (argc, argv, "aA:b:B:c:C:D:d:eE:f:FGg:hi:IJ:k:L:l:m:M:n:N:oO:p:P:Q:rR:s:S:t:T:u:U:vVx:y:w:W:X:z:Z:", long_options, &option_index)) != -1) { + while ((c = getopt_long (argc, argv, "aA:b:B:c:C:D:d:eE:f:FGg:hi:IJ:j:k:L:l:m:M:n:N:oO:p:P:Q:rR:s:S:t:T:u:U:vVx:y:w:W:X:z:Z:", long_options, &option_index)) != -1) { switch (c) { case 0: if (! strcmp(long_options[option_index].name, "pdcp_period")) { @@ -376,13 +376,13 @@ void check_and_adjust_params() { s32 ret; int i,j; - if (oai_emulation.info.nb_ue_local > NUMBER_OF_UE_MAX) { - LOG_E(EMU,"Enter fewer than %d UEs for the moment or change the NUMBER_OF_UE_MAX\n", NUMBER_OF_UE_MAX); + if (oai_emulation.info.nb_ue_local + oai_emulation.info.nb_rn_local > NUMBER_OF_UE_MAX) { + LOG_E(EMU,"Enter fewer than %d UEs/RNs for the moment or change the NUMBER_OF_UE_MAX\n", NUMBER_OF_UE_MAX); exit(EXIT_FAILURE); } - if (oai_emulation.info.nb_enb_local > NUMBER_OF_eNB_MAX) { - LOG_E(EMU,"Enter fewer than %d eNBs for the moment or change the NUMBER_OF_UE_MAX\n", NUMBER_OF_eNB_MAX); + if (oai_emulation.info.nb_enb_local + oai_emulation.info.nb_rn_local > NUMBER_OF_eNB_MAX) { + LOG_E(EMU,"Enter fewer than %d eNBs/RNs for the moment or change the NUMBER_OF_UE_MAX\n", NUMBER_OF_eNB_MAX); exit(EXIT_FAILURE); } @@ -405,11 +405,12 @@ void check_and_adjust_params() { if (ret < 0) LOG_E(EMU,"[INIT] Netlink not available, careful ...\n"); - + if (ethernet_flag == 1) { - oai_emulation.info.master[oai_emulation.info.master_id].nb_ue = oai_emulation.info.nb_ue_local; - oai_emulation.info.master[oai_emulation.info.master_id].nb_enb = oai_emulation.info.nb_enb_local; - + oai_emulation.info.master[oai_emulation.info.master_id].nb_ue = oai_emulation.info.nb_ue_local + oai_emulation.info.nb_rn_local; + oai_emulation.info.master[oai_emulation.info.master_id].nb_enb = oai_emulation.info.nb_enb_local + oai_emulation.info.nb_rn_local; + if (oai_emulation.info.nb_rn_local>0) + LOG_N(EMU,"Ethernet emulation is not yet tested with the relay nodes\n"); if (!oai_emulation.info.master_id) oai_emulation.info.is_primary_master = 1; j = 1; @@ -428,11 +429,30 @@ void check_and_adjust_params() { } } // ethernet flag - + // NB_UE_INST = oai_emulation.info.nb_ue_local + oai_emulation.info.nb_ue_remote; NB_eNB_INST = oai_emulation.info.nb_enb_local + oai_emulation.info.nb_enb_remote; NB_RN_INST = oai_emulation.info.nb_rn_local + oai_emulation.info.nb_rn_remote; + if (NB_RN_INST > 0 ) { + LOG_N(EMU,"Total number of RN %d (local %d, remote %d) mobility (the same as eNB) %s \n", NB_RN_INST,oai_emulation.info.nb_rn_local,oai_emulation.info.nb_rn_remote, oai_emulation.topology_config.mobility.eNB_mobility.eNB_mobility_type.selected_option); + + LOG_N(EMU,"Adjust the number of eNB inst (%d->%d) and UE inst (%d->%d)\n ", + NB_eNB_INST, NB_eNB_INST+NB_RN_INST, + NB_UE_INST, NB_UE_INST+NB_RN_INST); + NB_eNB_INST+=NB_RN_INST; + NB_UE_INST+=NB_RN_INST; + } + LOG_I(EMU,"Total number of UE %d (local %d, remote %d, relay %d) mobility %s \n", + NB_UE_INST,oai_emulation.info.nb_ue_local,oai_emulation.info.nb_ue_remote, + NB_RN_INST, + oai_emulation.topology_config.mobility.UE_mobility.UE_mobility_type.selected_option); + + LOG_I(EMU,"Total number of eNB %d (local %d, remote %d, relay %d) mobility %s \n", + NB_eNB_INST,oai_emulation.info.nb_enb_local,oai_emulation.info.nb_enb_remote, + NB_RN_INST, + oai_emulation.topology_config.mobility.eNB_mobility.eNB_mobility_type.selected_option); + } void init_omv() { @@ -448,9 +468,9 @@ void init_omv() { case -1 : perror("fork failed \n"); break; - case 0 : /* child is going to be the omv, it is the reader */ - if(close(pfd[1]) == -1 ) /* we close the write desc. */ - perror("close on write\n" ); + case 0 : // child is going to be the omv, it is the reader + if(close(pfd[1]) == -1 ) // we close the write desc. + perror("close on write\n" ); sprintf(fdstr, "%d", pfd[0] ); sprintf(num_enb, "%d", NB_eNB_INST); sprintf(num_ue, "%d", NB_UE_INST); @@ -461,12 +481,12 @@ void init_omv() { sprintf(nb_antenna, "%d", 4); sprintf(frame_type, "%s", (oai_emulation.info.frame_type == 0) ? "FDD" : "TDD"); sprintf(tdd_config, "%d", oai_emulation.info.tdd_config); - /* execl is used to launch the visualisor */ +// execl is used to launch the visualisor execl(full_name,"OMV", fdstr, frames, num_enb, num_ue, x_area, y_area, z_area, nb_antenna, frame_type, tdd_config,NULL ); perror( "error in execl the OMV" ); } //parent - if(close( pfd[0] ) == -1 ) /* we close the write desc. */ +if(close( pfd[0] ) == -1 ) // we close the write desc. perror("close on read\n" ); } } @@ -488,7 +508,7 @@ void init_openair1() { s32 UE_id, eNB_id; // change the nb_connected_eNB - init_lte_vars (&frame_parms, oai_emulation.info.frame_type, oai_emulation.info.tdd_config, oai_emulation.info.tdd_config_S,oai_emulation.info.extended_prefix_flag,oai_emulation.info.N_RB_DL, Nid_cell, cooperation_flag, oai_emulation.info.transmission_mode, abstraction_flag,nb_antennas_rx); + init_lte_vars (&frame_parms, oai_emulation.info.frame_type, oai_emulation.info.tdd_config, oai_emulation.info.tdd_config_S,oai_emulation.info.extended_prefix_flag,oai_emulation.info.N_RB_DL, Nid_cell, cooperation_flag, oai_emulation.info.transmission_mode, abstraction_flag,nb_antennas_rx, oai_emulation.info.eMBMS_active_state); for (eNB_id=0; eNB_id<NB_eNB_INST;eNB_id++){ for (UE_id=0; UE_id<NB_UE_INST;UE_id++){ @@ -566,7 +586,9 @@ void init_openair2() { void init_ocm() { s32 UE_id, eNB_id; /* Added for PHY abstraction */ - if (abstraction_flag) { + LOG_I(OCM,"Running with frame_type %d, Nid_cell %d, N_RB_DL %d, EP %d, mode %d, target dl_mcs %d, rate adaptation %d, nframes %d, abstraction %d, channel %s\n", oai_emulation.info.frame_type, Nid_cell, oai_emulation.info.N_RB_DL, oai_emulation.info.extended_prefix_flag, oai_emulation.info.transmission_mode,target_dl_mcs,rate_adaptation_flag,oai_emulation.info.n_frames,abstraction_flag,oai_emulation.environment_system_config.fading.small_scale.selected_option); + + if (abstraction_flag) { get_beta_map(); #ifdef PHY_ABSTRACTION_UL @@ -706,16 +728,21 @@ void update_ocm() { if ((oai_emulation.info.ocm_enabled == 1)&& (ethernet_flag == 0 )) { //LOG_D(OMG," extracting position of eNb...\n"); extract_position(enb_node_list, enb_data, NB_eNB_INST); + //extract_position_fixed_enb(enb_data, NB_eNB_INST,frame); //LOG_D(OMG," extracting position of UE...\n"); // if (oai_emulation.info.omg_model_ue == TRACE) extract_position(ue_node_list, ue_data, NB_UE_INST); - + + /* if (frame % 50 == 0) + LOG_N(OCM,"Path loss for TTI %d : \n", frame); + */ for (eNB_id = 0; eNB_id < NB_eNB_INST; eNB_id++) { for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) { calc_path_loss (enb_data[eNB_id], ue_data[UE_id], eNB2UE[eNB_id][UE_id], oai_emulation.environment_system_config,ShaF); //calc_path_loss (enb_data[eNB_id], ue_data[UE_id], eNB2UE[eNB_id][UE_id], oai_emulation.environment_system_config,0); UE2eNB[UE_id][eNB_id]->path_loss_dB = eNB2UE[eNB_id][UE_id]->path_loss_dB; - LOG_I(OCM,"Path loss between eNB %d at (%f,%f) and UE %d at (%f,%f) is %f, angle %f\n", + // if (frame % 50 == 0) + LOG_I(OCM,"Path loss between eNB %d at (%f,%f) and UE %d at (%f,%f) is %f, angle %f\n", eNB_id,enb_data[eNB_id]->x,enb_data[eNB_id]->y,UE_id,ue_data[UE_id]->x,ue_data[UE_id]->y, eNB2UE[eNB_id][UE_id]->path_loss_dB, eNB2UE[eNB_id][UE_id]->aoa); } @@ -735,7 +762,7 @@ void update_ocm() { eNB2UE[eNB_id][UE_id]->path_loss_dB = -105 + sinr_dB - PHY_vars_eNB_g[eNB_id]->lte_frame_parms.pdsch_config_common.referenceSignalPower; UE2eNB[UE_id][eNB_id]->path_loss_dB = -105 + sinr_dB - PHY_vars_eNB_g[eNB_id]->lte_frame_parms.pdsch_config_common.referenceSignalPower; } - LOG_I(OCM,"Path loss from eNB %d to UE %d => %f dB (eNB TX %d)\n",eNB_id,UE_id,eNB2UE[eNB_id][UE_id]->path_loss_dB, + LOG_I(OCM,"Path loss from eNB %d to UE %d => %f dB (eNB TX %d)\n",eNB_id,UE_id,eNB2UE[eNB_id][UE_id]->path_loss_dB, PHY_vars_eNB_g[eNB_id]->lte_frame_parms.pdsch_config_common.referenceSignalPower); // printf("[SIM] Path loss from UE %d to eNB %d => %f dB\n",UE_id,eNB_id,UE2eNB[UE_id][eNB_id]->path_loss_dB); } @@ -767,6 +794,7 @@ void update_otg_eNB(int module_id, unsigned int ctime) { (otg_pkt->otg_pkt).rb_id = dst_id * NB_RB_MAX + DTCH; // app could be binded to a given DRB (otg_pkt->otg_pkt).module_id = module_id; (otg_pkt->otg_pkt).dst_id = dst_id; + (otg_pkt->otg_pkt).is_ue = 0; (otg_pkt->otg_pkt).mode = PDCP_DATA_PDU; //Adding the packet to the OTG-PDCP buffer pkt_list_add_tail_eurecom(otg_pkt, &(otg_pdcp_buffer[module_id])); @@ -787,7 +815,7 @@ void update_otg_eNB(int module_id, unsigned int ctime) { #ifdef Rel10 int service_id, session_id, rb_id; // MBSM multicast traffic - // if (frame >= 46) {// only generate when UE can receive MTCH (need to control this value) + // if (frame >= 50) {// only generate when UE can receive MTCH (need to control this value) for (service_id = 0; service_id < 2 ; service_id++) { //maxServiceCount for (session_id = 0; session_id < 2; session_id++) { // maxSessionPerPMCH // LOG_I(OTG,"DUY:frame %d, pdcp_mbms_array[module_id][rb_id].instanciated_instance is %d\n",frame,pdcp_mbms_array[module_id][service_id*maxSessionPerPMCH + session_id].instanciated_instance); @@ -801,10 +829,12 @@ void update_otg_eNB(int module_id, unsigned int ctime) { (otg_pkt->otg_pkt).rb_id = rb_id; (otg_pkt->otg_pkt).module_id = module_id; (otg_pkt->otg_pkt).dst_id = session_id; + (otg_pkt->otg_pkt).is_ue = 0; //Adding the packet to the OTG-PDCP buffer (otg_pkt->otg_pkt).mode = PDCP_TM; pkt_list_add_tail_eurecom(otg_pkt, &(otg_pdcp_buffer[module_id])); - LOG_I(EMU, "[eNB %d] ADD packet multicast to OTG buffer for dst %d on rb_id %d\n", (otg_pkt->otg_pkt).module_id, (otg_pkt->otg_pkt).dst_id,(otg_pkt->otg_pkt).rb_id); + LOG_I(EMU, "[eNB %d] ADD packet (%p) multicast to OTG buffer for dst %d on rb_id %d\n", + (otg_pkt->otg_pkt).module_id, otg_pkt, (otg_pkt->otg_pkt).dst_id,(otg_pkt->otg_pkt).rb_id); } else { //LOG_I(EMU, "OTG returns null \n"); free(otg_pkt); @@ -861,7 +891,8 @@ void update_otg_eNB(int module_id, unsigned int ctime) { rb_id = dst_id * NB_RB_MAX + DTCH; (otg_pkt->otg_pkt).rb_id = rb_id; (otg_pkt->otg_pkt).module_id = module_id; - (otg_pkt->otg_pkt).mode = PDCP_DATA_PDU; + (otg_pkt->otg_pkt).is_ue = 0; + (otg_pkt->otg_pkt).mode = PDCP_DATA_PDU; //Adding the packet to the OTG-PDCP buffer pkt_list_add_tail_eurecom(otg_pkt, &(otg_pdcp_buffer[module_id])); LOG_I(EMU, "[eNB %d] ADD pkt to OTG buffer for dst %d on rb_id %d\n", (otg_pkt->otg_pkt).module_id, (otg_pkt->otg_pkt).dst_id,(otg_pkt->otg_pkt).rb_id); @@ -891,24 +922,27 @@ void update_otg_UE(int UE_id, unsigned int ctime) { src_id = module_id; for (dst_id=0;dst_id<NUMBER_OF_eNB_MAX;dst_id++) { - if (mac_get_rrc_status(UE_id, 0/*eNB_flag*/, dst_id ) > 2 /*RRC_CONNECTED*/) { - Packet_otg_elt *otg_pkt = malloc (sizeof(Packet_otg_elt)); - // Manage to add this packet to the tail of your list - (otg_pkt->otg_pkt).sdu_buffer = (u8*) packet_gen(src_id, dst_id, ctime, &((otg_pkt->otg_pkt).sdu_buffer_size)); - - if ((otg_pkt->otg_pkt).sdu_buffer != NULL) { - (otg_pkt->otg_pkt).rb_id = dst_id * NB_RB_MAX + DTCH; - (otg_pkt->otg_pkt).module_id = module_id; - (otg_pkt->otg_pkt).dst_id = dst_id; - //Adding the packet to the OTG-PDCP buffer - (otg_pkt->otg_pkt).mode = PDCP_DATA_PDU; - pkt_list_add_tail_eurecom(otg_pkt, &(otg_pdcp_buffer[module_id])); - } else { - free(otg_pkt); - otg_pkt=NULL; + if (mac_get_rrc_status(UE_id, 0/*eNB_flag*/, dst_id ) > 2 /*RRC_CONNECTED*/) { + Packet_otg_elt *otg_pkt = malloc (sizeof(Packet_otg_elt)); + // Manage to add this packet to the tail of your list + (otg_pkt->otg_pkt).sdu_buffer = (u8*) packet_gen(src_id, dst_id, ctime, &((otg_pkt->otg_pkt).sdu_buffer_size)); + + if ((otg_pkt->otg_pkt).sdu_buffer != NULL) { + (otg_pkt->otg_pkt).rb_id = dst_id * NB_RB_MAX + DTCH; + (otg_pkt->otg_pkt).module_id = module_id; + (otg_pkt->otg_pkt).dst_id = dst_id; + (otg_pkt->otg_pkt).is_ue = 1; + //Adding the packet to the OTG-PDCP buffer + (otg_pkt->otg_pkt).mode = PDCP_DATA_PDU; + pkt_list_add_tail_eurecom(otg_pkt, &(otg_pdcp_buffer[module_id])); + LOG_I(EMU, "[UE %d] ADD pkt to OTG buffer with size %d for dst %d on rb_id %d \n", + (otg_pkt->otg_pkt).module_id, otg_pkt->otg_pkt.sdu_buffer_size, (otg_pkt->otg_pkt).dst_id,(otg_pkt->otg_pkt).rb_id); + } else { + free(otg_pkt); + otg_pkt=NULL; + } } } - } } #endif } diff --git a/targets/SIMU/USER/sinr_sim.c b/targets/SIMU/USER/sinr_sim.c index 8b41e3f2390e69e218d4e6c3d93cddc75b294cae..719112709a850a783755f2a62fd67d4ec0af646a 100644 --- a/targets/SIMU/USER/sinr_sim.c +++ b/targets/SIMU/USER/sinr_sim.c @@ -69,21 +69,39 @@ void extract_position (Node_list input_node_list, node_desc_t **node_data, int n } } } +void extract_position_fixed_enb (node_desc_t **node_data, int nb_nodes, u32 frame){ + int i; + + for (i=0;i<nb_nodes;i++) { + if (i==0) { + node_data[i]->x = 0; + node_data[i]->y = 500; + } + else if (i == 1 ){ + node_data[i]->x = 866;// + node_data[i]->y = 1000; + } + else if (i == 2 ){ + node_data[i]->x = 866; + node_data[i]->y = 0; + } + } +} void extract_position_fixed_ue (node_desc_t **node_data, int nb_nodes, u32 frame){ int i; if(frame<50) - for (i=0;i<nb_nodes;i++) { - if (i==0) { - node_data[i]->x = 2050; - node_data[i]->y = 1500; - } - else { - node_data[i]->x = 2150; - node_data[i]->y = 1500; - } - } - else + for (i=0;i<nb_nodes;i++) { + if (i==0) { + node_data[i]->x = 2050; + node_data[i]->y = 1500; + } + else { + node_data[i]->x = 2150; + node_data[i]->y = 1500; + } + } + else { for (i=0;i<nb_nodes;i++) { if (i==0) { @@ -200,7 +218,7 @@ void init_snr(channel_desc_t* eNB2UE, node_desc_t *enb_data, node_desc_t *ue_dat //for (aarx=0; aarx<eNB2UE->nb_rx; aarx++) *N0 = thermal_noise + ue_data->rx_noise_level;//? all the element have the same noise level????? - LOG_D(OCM,"Path loss %lf, noise %lf, signal %lf, snr %lf\n", + LOG_D(OCM,"Path loss %lf, noise (N0) %lf, signal %lf, snr %lf\n", eNB2UE->path_loss_dB, thermal_noise + ue_data->rx_noise_level, enb_data->tx_power_dBm + eNB2UE->path_loss_dB, diff --git a/targets/TEST/OAI/case02.py b/targets/TEST/OAI/case02.py index b0bf4a3f2536b1dbc70495df61f434b58811e760..79b3fe5e5df8162060e28181ead2a1d06aa47d4e 100644 --- a/targets/TEST/OAI/case02.py +++ b/targets/TEST/OAI/case02.py @@ -109,6 +109,8 @@ def execute(oai, user, pw, logfile): else : oai.send_nowait('echo '+pw+ ' | sudo -S pkill oaisim ;') oai.send_nowait('echo '+pw+ ' | sudo -S pkill oaisim.rel8.nas;') + time.sleep(1) + oai.send_nowait('echo '+pw+ ' | sudo -S pkill oaisim.rel8.nas;') except log.err, e: log.fail(case, test, name, conf, e.value, diag, logfile) diff --git a/targets/TEST/OAI/case03.py b/targets/TEST/OAI/case03.py index 4dbc719ea46c6c372dc33716bce8b381959cf117..9f41cdf156e744a031cb18ec3ecb5b2268102a31 100644 --- a/targets/TEST/OAI/case03.py +++ b/targets/TEST/OAI/case03.py @@ -154,3 +154,13 @@ def execute(oai, user, pw, logfile): else: log.ok(case, test, name, conf, 'Note: check the packet loss from the OTG stats', logfile) + # try: + # test = '08' + # name = 'Run oai.rel10.phy.eMBMS.Relay.OTG.fdd' + # diag = 'eMBMS multicast/broadcast DF relaying is not working properly in fdd mode, make sure that the SIB13/MCCH/MTCH have been correclty received by UEs' + # conf = '-c43 -F -T mbvbr -Q4 -j1 -n120' + # oai.send_expect('./oaisim.rel10 ' + conf, ' MTCH for sync area 1', 100) + # except log.err, e: + # log.fail(case, test, name, conf, e.value, diag, logfile) + # else: + # log.ok(case, test, name, conf, 'Note: check the packet loss from the OTG stats', logfile)