Commit 58610853 authored by Navid Nikaein's avatar Navid Nikaein

* Add relay node types and its eNB/UE procedures

* update the L2 interface
* update eMBMS MAC/PHY to support more than one MBSFN sync area
* update OTG to support different multicast traffic for eMBMS
* pre-ci test passed (100%)
 


git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4170 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 51bdba77
......@@ -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);
......
......@@ -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;
}
......
......@@ -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));
......
......@@ -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"
......
......@@ -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;
......
......@@ -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;
......
......@@ -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.
......
......@@ -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)){
......
......@@ -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
......
......@@ -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);
}
......
......@@ -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
......
......@@ -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) {
......
......@@ -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
......
......@@ -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;
......
......@@ -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
......
......@@ -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
......
/*________________________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
}
......
/*________________________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);
......
......@@ -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
......
......@@ -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
......
......@@ -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();
......
......@@ -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);
......
......@@ -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)
......
......@@ -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
......
......@@ -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 {
......
......@@ -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
......
......@@ -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);
......
......@@ -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;
......
......@@ -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]++;
......
......@@ -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;
......
......@@ -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");
......
......@@ -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;
......
<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>
......@@ -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,
......
......@@ -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);
}
}
}
......@@ -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);
......@@ -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);
......
......@@ -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;
......
......@@ -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
}
......
......@@ -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,
......
......@@ -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)
......
......@@ -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)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment