* 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
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
+245
-181
@@ -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;
|
||||
|
||||
// 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
|
||||
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);
|
||||
|
||||
|
||||
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;
|
||||
|
||||
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[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[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[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[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 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 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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
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_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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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 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 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;
|
||||
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 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;
|
||||
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;
|
||||
}
|
||||
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[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 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;
|
||||
}
|
||||
}
|
||||
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) {
|
||||
|
||||
+215
-173
@@ -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 ii=0, msi_pos=0, mcch_mcs;
|
||||
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 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;
|
||||
|
||||
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[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[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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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[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 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 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
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;
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
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
|
||||
|
||||
@@ -1,9 +1,40 @@
|
||||
/*________________________openair_rrc_L2_interface.c________________________
|
||||
/*******************************************************************************
|
||||
|
||||
Authors : Hicham Anouar
|
||||
Company : EURECOM
|
||||
Emails : anouar@eurecom.fr
|
||||
________________________________________________________________*/
|
||||
Eurecom OpenAirInterface 2
|
||||
Copyright(c) 1999 - 2010 Eurecom
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
version 2, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
The full GNU General Public License is included in this distribution in
|
||||
the file called "COPYING".
|
||||
|
||||
Contact Information
|
||||
Openair Admin: openair_admin@eurecom.fr
|
||||
Openair Tech : openair_tech@eurecom.fr
|
||||
Forums : http://forums.eurecom.fsr/openairinterface
|
||||
Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
/*! \file l2_interface.c
|
||||
* \brief layer 2 interface
|
||||
* \author Raymond Knopp and Navid Nikaein
|
||||
* \date 2011
|
||||
* \version 1.0
|
||||
* \company Eurecom
|
||||
* \email: navid.nikaein@eurecom.fr
|
||||
*/
|
||||
|
||||
#ifdef USER_MODE
|
||||
#include <fcntl.h>
|
||||
@@ -56,22 +87,20 @@ ________________________________________________________________*/
|
||||
#include "openair_rrc_L2_interface.h"
|
||||
|
||||
/********************************************************************************************************************/
|
||||
s8 mac_rrc_data_req(u8 Mod_id, u32 frame, u16 Srb_id, u8 Nb_tb,char *Buffer,u8 eNB_flag,u8 eNB_index){
|
||||
s8 mac_rrc_data_req(u8 Mod_id, u32 frame, u16 Srb_id, u8 Nb_tb,char *Buffer,u8 eNB_flag,u8 eNB_index, u8 mbsfn_sync_area){
|
||||
/********************************************************************************************************************/
|
||||
#ifdef CELLULAR
|
||||
return(rrc_L2_data_req_rx(Mod_id,Srb_id,Nb_tb,Buffer,eNB_index));
|
||||
#else
|
||||
return(mac_rrc_lite_data_req(Mod_id,frame,Srb_id,Nb_tb,Buffer,eNB_flag,eNB_index));
|
||||
return(mac_rrc_lite_data_req(Mod_id,frame,Srb_id,Nb_tb,Buffer,eNB_flag,eNB_index,mbsfn_sync_area));
|
||||
#endif //CELLULAR
|
||||
}
|
||||
|
||||
/********************************************************************************************************************/
|
||||
s8 mac_rrc_data_ind(u8 Mod_id, u32 frame, u16 Srb_id, char *Sdu,u16 Sdu_len,u8 eNB_flag, u8 eNB_index ){
|
||||
/********************************************************************************************************************/
|
||||
s8 mac_rrc_data_ind(u8 Mod_id, u32 frame, u16 Srb_id, char *Sdu,u16 Sdu_len,u8 eNB_flag, u8 eNB_index,u8 mbsfn_sync_area){
|
||||
#ifdef CELLULAR
|
||||
return(rrc_L2_mac_data_ind_rx(Mod_id, Srb_id, Sdu, Sdu_len, eNB_index));
|
||||
#else
|
||||
return(mac_rrc_lite_data_ind(Mod_id,frame,Srb_id,Sdu,Sdu_len,eNB_flag,eNB_index));
|
||||
return(mac_rrc_lite_data_ind(Mod_id,frame,Srb_id,Sdu,Sdu_len,eNB_flag,eNB_index,mbsfn_sync_area));
|
||||
#endif //CELLULAR
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,47 @@
|
||||
/*________________________openair_rrc_L2_interface.h________________________
|
||||
/*******************************************************************************
|
||||
|
||||
Authors : Hicham Anouar
|
||||
Company : EURECOM
|
||||
Emails : anouar@eurecom.fr
|
||||
________________________________________________________________*/
|
||||
Eurecom OpenAirInterface 2
|
||||
Copyright(c) 1999 - 2010 Eurecom
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
version 2, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
The full GNU General Public License is included in this distribution in
|
||||
the file called "COPYING".
|
||||
|
||||
Contact Information
|
||||
Openair Admin: openair_admin@eurecom.fr
|
||||
Openair Tech : openair_tech@eurecom.fr
|
||||
Forums : http://forums.eurecom.fsr/openairinterface
|
||||
Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
/*! \file l2_interface.c
|
||||
* \brief layer 2 interface
|
||||
* \author Raymond Knopp and Navid Nikaein
|
||||
* \date 2011
|
||||
* \version 1.0
|
||||
* \company Eurecom
|
||||
* \email: raymond.knopp@eurecom.fr
|
||||
*/
|
||||
#ifndef __OPENAIR_RRC_L2_INTERFACE_H__
|
||||
#define __OPENAIR_RRC_L2_INTERFACE_H__
|
||||
|
||||
#include "COMMON/mac_rrc_primitives.h"
|
||||
|
||||
s8 mac_rrc_data_req( u8 Mod_id, u32 frame, u16 Srb_id, u8 Nb_tb,char *Buffer,u8,u8);
|
||||
s8 mac_rrc_data_ind( u8 Mod_id, u32 frame, u16 Srb_id, char *Sdu, u16 Sdu_len,u8,u8 Mui);
|
||||
s8 mac_rrc_data_req( u8 Mod_id, u32 frame, u16 Srb_id, u8 Nb_tb,char *Buffer,u8 eNB_flag,u8 eNB_index, u8 mbsfn_sync_area);
|
||||
s8 mac_rrc_data_ind( u8 Mod_id, u32 frame, u16 Srb_id, char *Sdu, u16 Sdu_len,u8 eNB_flag, u8 eNB_index,u8 mbsfn_sync_area);
|
||||
void mac_lite_sync_ind( u8 Mod_id, u8 status);
|
||||
void mac_rrc_meas_ind(u8,MAC_MEAS_REQ_ENTRY*);
|
||||
void rlcrrc_data_ind( u8 Mod_id, u32 frame, u8 eNB_flag,unsigned int Rb_id, u32 sdu_size,u8 *Buffer);
|
||||
|
||||
@@ -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);
|
||||
|
||||
+22
-15
@@ -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)
|
||||
|
||||
+90
-68
@@ -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);
|
||||
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_D (RRC, "[eNB %d] MCCH_MESSAGE contents (partial)\n", Mod_id);
|
||||
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;
|
||||
|
||||
|
||||
|
||||
+124
-17
@@ -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;
|
||||
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;
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
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
|
||||
|
||||
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;
|
||||
|
||||
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");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user