diff --git a/openair1/PHY/INIT/defs.h b/openair1/PHY/INIT/defs.h index 32f6366ef8b50d087c28e882459e350d6f964791..85f89860640fc55ff26d080d4bd4dcff5867ce65 100644 --- a/openair1/PHY/INIT/defs.h +++ b/openair1/PHY/INIT/defs.h @@ -9,6 +9,7 @@ #include "RadioResourceConfigDedicated.h" #include "TDD-Config.h" #include "MBSFN-SubframeConfigList.h" +#include "MobilityControlInfo.h" #else /** @@ -121,6 +122,17 @@ void phy_config_sib2_ue(u8 Mod_id,u8 CH_index, AdditionalSpectrumEmission_t *additionalSpectrumEmission, struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList); + +/*! + \fn phy_config_afterHO_ue + \brief Configure Common PHY parameters from mobilityControlInfo + @param Mod_id + @param eNB_index + @param mobilityControlInfo pointer to the mobility control information for handover + @param ho_failed flag to indicated whether the ho was successful or not + */ +void phy_config_afterHO_ue(u8 Mod_id,u8 eNB_index, + MobilityControlInfo_t *mobilityControlInfo,u8 ho_failed); /*! \fn void phy_config_sib2_eNB(u8 Mod_id, RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index 3679ccacf55bc02ece4691fc7d5a900aea56a259..2b8f57920b58250e09ee9148c54052e01d60555b 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -428,6 +428,118 @@ void phy_config_dedicated_eNB_step2(PHY_VARS_eNB *phy_vars_eNB) { } } +/* + * Configures UE MAC and PHY with radioResourceCommon received in mobilityControlInfo IE during Handover + */ +void phy_config_afterHO_ue(u8 Mod_id,u8 eNB_id, MobilityControlInfo_t *mobilityControlInfo, u8 ho_failed) { + + if(mobilityControlInfo!=NULL) { + RadioResourceConfigCommon_t *radioResourceConfigCommon = &mobilityControlInfo->radioResourceConfigCommon; + LOG_I(PHY,"radioResourceConfigCommon %p\n", radioResourceConfigCommon); + memcpy((void *)&PHY_vars_UE_g[Mod_id]->lte_frame_parms_before_ho, + (void *)&PHY_vars_UE_g[Mod_id]->lte_frame_parms, + sizeof(LTE_DL_FRAME_PARMS)); + PHY_vars_UE_g[Mod_id]->ho_triggered = 1; + //PHY_vars_UE_g[UE_id]->UE_mode[0] = PRACH; + + LTE_DL_FRAME_PARMS *lte_frame_parms = &PHY_vars_UE_g[Mod_id]->lte_frame_parms; + int N_ZC; + u8 prach_fmt; + int u; + + LOG_I(PHY,"[UE%d] Frame %d: Handover triggered: Applying radioResourceConfigCommon from eNB %d\n", + Mod_id,PHY_vars_UE_g[Mod_id]->frame,eNB_id); + + lte_frame_parms->prach_config_common.rootSequenceIndex =radioResourceConfigCommon->prach_Config.rootSequenceIndex; + lte_frame_parms->prach_config_common.prach_Config_enabled=1; + lte_frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_ConfigIndex; + lte_frame_parms->prach_config_common.prach_ConfigInfo.highSpeedFlag =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->highSpeedFlag; + lte_frame_parms->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->zeroCorrelationZoneConfig; + lte_frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_FreqOffset; + + prach_fmt = get_prach_fmt(radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_ConfigIndex,lte_frame_parms->frame_type); + N_ZC = (prach_fmt <4)?839:139; + u = (prach_fmt < 4) ? prach_root_sequence_map0_3[lte_frame_parms->prach_config_common.rootSequenceIndex] : + prach_root_sequence_map4[lte_frame_parms->prach_config_common.rootSequenceIndex]; + + //compute_prach_seq(u,N_ZC, PHY_vars_UE_g[Mod_id]->X_u); + compute_prach_seq(&PHY_vars_UE_g[Mod_id]->lte_frame_parms.prach_config_common, + lte_frame_parms->frame_type, + PHY_vars_UE_g[Mod_id]->X_u); + + + lte_frame_parms->pucch_config_common.deltaPUCCH_Shift = 1+radioResourceConfigCommon->pucch_ConfigCommon->deltaPUCCH_Shift; + lte_frame_parms->pucch_config_common.nRB_CQI = radioResourceConfigCommon->pucch_ConfigCommon->nRB_CQI; + lte_frame_parms->pucch_config_common.nCS_AN = radioResourceConfigCommon->pucch_ConfigCommon->nCS_AN; + lte_frame_parms->pucch_config_common.n1PUCCH_AN = radioResourceConfigCommon->pucch_ConfigCommon->n1PUCCH_AN; + lte_frame_parms->pdsch_config_common.referenceSignalPower = radioResourceConfigCommon->pdsch_ConfigCommon->referenceSignalPower; + lte_frame_parms->pdsch_config_common.p_b = radioResourceConfigCommon->pdsch_ConfigCommon->p_b; + + + lte_frame_parms->pusch_config_common.n_SB = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.n_SB; + lte_frame_parms->pusch_config_common.hoppingMode = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode; + lte_frame_parms->pusch_config_common.pusch_HoppingOffset = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset; + lte_frame_parms->pusch_config_common.enable64QAM = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM; + lte_frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled; + lte_frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH; + lte_frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled; + lte_frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift; + + init_ul_hopping(lte_frame_parms); + lte_frame_parms->soundingrs_ul_config_common.enabled_flag = 0; + if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon->present==SoundingRS_UL_ConfigCommon_PR_setup) { + lte_frame_parms->soundingrs_ul_config_common.enabled_flag = 1; + lte_frame_parms->soundingrs_ul_config_common.srs_BandwidthConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon->choice.setup.srs_BandwidthConfig; + lte_frame_parms->soundingrs_ul_config_common.srs_SubframeConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon->choice.setup.srs_SubframeConfig; + lte_frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission = radioResourceConfigCommon->soundingRS_UL_ConfigCommon->choice.setup.ackNackSRS_SimultaneousTransmission; + if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon->choice.setup.srs_MaxUpPts) + lte_frame_parms->soundingrs_ul_config_common.srs_MaxUpPts = 1; + else + lte_frame_parms->soundingrs_ul_config_common.srs_MaxUpPts = 0; + } + + lte_frame_parms->ul_power_control_config_common.p0_NominalPUSCH = radioResourceConfigCommon->uplinkPowerControlCommon->p0_NominalPUSCH; + lte_frame_parms->ul_power_control_config_common.alpha = radioResourceConfigCommon->uplinkPowerControlCommon->alpha; + lte_frame_parms->ul_power_control_config_common.p0_NominalPUCCH = radioResourceConfigCommon->uplinkPowerControlCommon->p0_NominalPUCCH; + lte_frame_parms->ul_power_control_config_common.deltaPreambleMsg3 = radioResourceConfigCommon->uplinkPowerControlCommon->deltaPreambleMsg3; + lte_frame_parms->ul_power_control_config_common.deltaF_PUCCH_Format1 = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format1; + lte_frame_parms->ul_power_control_config_common.deltaF_PUCCH_Format1b = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format1b; + lte_frame_parms->ul_power_control_config_common.deltaF_PUCCH_Format2 = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format2; + lte_frame_parms->ul_power_control_config_common.deltaF_PUCCH_Format2a = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format2a; + lte_frame_parms->ul_power_control_config_common.deltaF_PUCCH_Format2b = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format2b; + + lte_frame_parms->maxHARQ_Msg3Tx = radioResourceConfigCommon->rach_ConfigCommon->maxHARQ_Msg3Tx; + + // Now configure some of the Physical Channels + if (radioResourceConfigCommon->antennaInfoCommon) + lte_frame_parms->nb_antennas_tx = (1<<radioResourceConfigCommon->antennaInfoCommon->antennaPortsCount); + else + lte_frame_parms->nb_antennas_tx = 1; + //PHICH + if (radioResourceConfigCommon->antennaInfoCommon) { + lte_frame_parms->phich_config_common.phich_resource = radioResourceConfigCommon->phich_Config->phich_Resource; + lte_frame_parms->phich_config_common.phich_duration = radioResourceConfigCommon->phich_Config->phich_Duration; + } + //Target CellId + lte_frame_parms->Nid_cell = mobilityControlInfo->targetPhysCellId; + lte_frame_parms->nushift = lte_frame_parms->Nid_cell%6; + + // PUCCH + init_ncs_cell(lte_frame_parms,PHY_vars_UE_g[Mod_id]->ncs_cell); + + init_ul_hopping(lte_frame_parms); + + // RNTI + + PHY_vars_UE_g[Mod_id]->lte_ue_pdcch_vars[eNB_id]->crnti = mobilityControlInfo->newUE_Identity.buf[0]|(mobilityControlInfo->newUE_Identity.buf[1]<<8); + + } + if(ho_failed) { + LOG_D(PHY,"[UE%d] Handover failed, triggering RACH procedure\n",Mod_id); + memcpy((void *)&PHY_vars_UE_g[Mod_id]->lte_frame_parms,(void *)&PHY_vars_UE_g[Mod_id]->lte_frame_parms_before_ho, sizeof(LTE_DL_FRAME_PARMS)); + PHY_vars_UE_g[Mod_id]->UE_mode[eNB_id] = PRACH; + } +} void phy_config_meas_ue(u8 Mod_id,u8 eNB_index,u8 n_adj_cells,unsigned int *adj_cell_id) { diff --git a/openair1/PHY/LTE_ESTIMATION/defs.h b/openair1/PHY/LTE_ESTIMATION/defs.h index 1106480876f7493f90be827dbeb26a9d1a76ac08..bba8c614f275cfa4606d03473e69974f1f522ace 100644 --- a/openair1/PHY/LTE_ESTIMATION/defs.h +++ b/openair1/PHY/LTE_ESTIMATION/defs.h @@ -151,6 +151,13 @@ void lte_ue_measurements_emul(PHY_VARS_UE *phy_vars_ue,u8 last_slot,u8 eNB_id); @returns Path loss in dB */ s16 get_PL(u8 Mod_id,u8 eNB_index); +u8 get_RSRP(u8 Mod_id,u8 eNB_index); +u8 get_RSRQ(u8 Mod_id,u8 eNB_index); +u8 get_n_adj_cells(u8 Mod_id); +s8 get_rx_total_gain_dB(u8 Mod_id); +s8 get_RSSI(u8 Mod_id); +s8 set_RSRP_filtered(u8 Mod_id,u8 eNB_index,float rsrp); +s8 set_RSRQ_filtered(u8 Mod_id,u8 eNB_index,float rstq); //! Automatic gain control void phy_adjust_gain (PHY_VARS_UE *phy_vars_ue, diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c index 1567ab2e00ec774335e69d48a9af8f089a9aba1b..db809ceff7a2fe4ed8591d1c0c8d1cf9024f52a8 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c @@ -68,6 +68,70 @@ s16 get_PL(u8 Mod_id,u8 eNB_index) { phy_vars_ue->lte_frame_parms.pdsch_config_common.referenceSignalPower)); } + +u8 get_n_adj_cells (u8 Mod_id){ + + PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id]; + if (phy_vars_ue) + return phy_vars_ue->PHY_measurements.n_adj_cells; + else + return 0; +} + +s8 get_rx_total_gain_dB (u8 Mod_id){ + + PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id]; + if (phy_vars_ue) + return phy_vars_ue->rx_total_gain_dB; + else + return -1; +} +s8 get_RSSI (u8 Mod_id){ + + PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id]; + if (phy_vars_ue) + return phy_vars_ue->PHY_measurements.rssi; + else + return -1; +} +u8 get_RSRP(u8 Mod_id,u8 eNB_index) { + + PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id]; + if (phy_vars_ue) + return phy_vars_ue->PHY_measurements.rsrp[eNB_index]; + return 0; +} + +u8 get_RSRQ(u8 Mod_id,u8 eNB_index) { + + PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id]; + if (phy_vars_ue) + return phy_vars_ue->PHY_measurements.rsrq[eNB_index]; + return 0; +} + +s8 set_RSRP_filtered(u8 Mod_id,u8 eNB_index,float rsrp) { + + PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id]; + if (phy_vars_ue){ + phy_vars_ue->PHY_measurements.rsrp_filtered[eNB_index]=rsrp; + return 0; + } + LOG_W(PHY,"[UE%d] could not set the rsrp\n",Mod_id); + return -1; +} + +s8 set_RSRQ_filtered(u8 Mod_id,u8 eNB_index,float rsrq) { + + PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id]; + if (phy_vars_ue){ + phy_vars_ue->PHY_measurements.rsrq_filtered[eNB_index]=rsrq; + return 0; + } + LOG_W(PHY,"[UE%d] could not set the rsrq\n",Mod_id); + return -1; + +} void ue_rrc_measurements(PHY_VARS_UE *phy_vars_ue, u8 slot, @@ -202,21 +266,24 @@ void ue_rrc_measurements(PHY_VARS_UE *phy_vars_ue, } else { // Do abstraction of RSRP and RSRQ phy_vars_ue->PHY_measurements.rssi = phy_vars_ue->PHY_measurements.rx_power_avg[0]; + // dummay value for the moment + phy_vars_ue->PHY_measurements.rsrp[eNB_offset] = -93 ; + phy_vars_ue->PHY_measurements.rsrq[eNB_offset] = 3; } if (((phy_vars_ue->frame %10) == 0) && (slot == 1)) { #ifdef DEBUG_MEAS - if (eNB_offset == 0) + if (eNB_offset == 0) LOG_D(PHY,"[UE %d] Frame %d, slot %d RRC Measurements => rssi %3.1f dBm (digital: %3.1f dB)\n",phy_vars_ue->Mod_id, phy_vars_ue->frame,slot,10*log10(phy_vars_ue->PHY_measurements.rssi)-phy_vars_ue->rx_total_gain_dB, 10*log10(phy_vars_ue->PHY_measurements.rssi)); - LOG_D(PHY,"[UE %d] Frame %d, slot %d RRC Measurements (idx %d, Cell id %d) => rsrp: %3.1f (%3.1f) dBm, rsrq: %3.1f dB\n", - phy_vars_ue->Mod_id, - phy_vars_ue->frame,slot,eNB_offset, - (eNB_offset>0) ? phy_vars_ue->PHY_measurements.adj_cell_id[eNB_offset-1] : phy_vars_ue->lte_frame_parms.Nid_cell, - (dB_fixed_times10(phy_vars_ue->PHY_measurements.rsrp[eNB_offset])/10.0)-phy_vars_ue->rx_total_gain_dB-dB_fixed(phy_vars_ue->lte_frame_parms.N_RB_DL*12), - (10*log10(phy_vars_ue->PHY_measurements.rx_power_avg[0])/10.0)-phy_vars_ue->rx_total_gain_dB-dB_fixed(phy_vars_ue->lte_frame_parms.N_RB_DL*12), - (10*log10(phy_vars_ue->PHY_measurements.rsrq[eNB_offset]))-20); + LOG_D(PHY,"[UE %d] Frame %d, slot %d RRC Measurements (idx %d, Cell id %d) => rsrp: %3.1f (%3.1f) dBm, rsrq: %3.1f dB\n", + phy_vars_ue->Mod_id, + phy_vars_ue->frame,slot,eNB_offset, + (eNB_offset>0) ? phy_vars_ue->PHY_measurements.adj_cell_id[eNB_offset-1] : phy_vars_ue->lte_frame_parms.Nid_cell, + (dB_fixed_times10(phy_vars_ue->PHY_measurements.rsrp[eNB_offset])/10.0)-phy_vars_ue->rx_total_gain_dB-dB_fixed(phy_vars_ue->lte_frame_parms.N_RB_DL*12), + (10*log10(phy_vars_ue->PHY_measurements.rx_power_avg[0])/10.0)-phy_vars_ue->rx_total_gain_dB-dB_fixed(phy_vars_ue->lte_frame_parms.N_RB_DL*12), + (10*log10(phy_vars_ue->PHY_measurements.rsrq[eNB_offset]))-20); #endif diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index 592a25ccc6f5a6a1e54843002bc056893c774ae5..092b99c6c5ff57ca47cf083bda680f2ef6189f40 100755 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -331,8 +331,11 @@ typedef struct s8 tx_power_max_dBm; u32 frame; u8 n_connected_eNB; + u8 ho_initiated; + u8 ho_triggered; PHY_MEASUREMENTS PHY_measurements; /// Measurement variables LTE_DL_FRAME_PARMS lte_frame_parms; + LTE_DL_FRAME_PARMS lte_frame_parms_before_ho; // frame parame before ho used to recover if ho fails LTE_UE_COMMON lte_ue_common_vars; LTE_UE_PDSCH *lte_ue_pdsch_vars[NUMBER_OF_CONNECTED_eNB_MAX+1]; diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h index d56fc1df9295b92c6234360137130f5bd45c2a52..021eff76eac279f290875b52606fa794b0312b70 100755 --- a/openair1/PHY/impl_defs_top.h +++ b/openair1/PHY/impl_defs_top.h @@ -350,6 +350,8 @@ typedef struct unsigned int adj_cell_id[6]; int rsrq[7]; int rsrp[7]; + float rsrp_filtered[7]; // after layer 3 filtering + float rsrq_filtered[7]; // common measurements //! estimated noise power (linear) unsigned int n0_power[NB_ANTENNAS_RX]; diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h index 531b5ca323f7ac23cbf077450c2d3e3b280ed30d..7d33c162ff708d0b56a49ee090d1a49369213c2e 100644 --- a/openair1/SCHED/defs.h +++ b/openair1/SCHED/defs.h @@ -401,6 +401,9 @@ s32 remove_ue(u16 rnti, PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag); void process_timing_advance(u8 Mod_id,s16 timing_advance); void process_timing_advance_rar(PHY_VARS_UE *phy_vars_ue,u16 timing_advance); +unsigned int get_tx_amp(int gain_dBm, int gain_max_dBm); + +void phy_reset_ue(u8 Mod_id,u8 eNB_index); /** \brief This function retrives the resource (n1_pucch) corresponding to a PDSCH transmission in subframe n-4 which is acknowledged in subframe n (for FDD) according to n1_pucch = Ncce + N1_pucch. For diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 768c3e1d761c726813e29ac3d8e961102bbdf517..77ce055905381e564208c57e6cd53a8c98a56098 100755 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -2829,9 +2829,11 @@ void phy_procedures_eNB_RX(unsigned char last_slot,PHY_VARS_eNB *phy_vars_eNB,u8 LOG_I(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:\n",phy_vars_eNB->frame,last_slot>>1, harq_pid,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3); - for (j=0;j<phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3;j++) - LOG_T(PHY,"%x.",phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->c[0][j]); - LOG_T(PHY,"\n"); + if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->c[0]!=NULL){ + for (j=0;j<phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3;j++) + LOG_T(PHY,"%x.",phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->c[0][j]); + LOG_T(PHY,"\n"); + } //dump_ulsch(phy_vars_eNB, last_slot>>1, i); diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 06cf09fb16814081a1502a105702bb543b4f76b7..af9ecf9dc127c8a3061614670eb0b20b89fa07b4 100755 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -248,6 +248,39 @@ void dump_dlsch_ra(PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 subframe) { } #endif +void phy_reset_ue(u8 Mod_id,u8 eNB_index) { + + // This flushes ALL DLSCH and ULSCH harq buffers of ALL connected eNBs...add the eNB_index later + // for more flexibility + + u8 i,j,k; + PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id]; + //[NUMBER_OF_CONNECTED_eNB_MAX][2]; + for(i=0;i<NUMBER_OF_CONNECTED_eNB_MAX;i++) { + for(j=0;j<2;j++) { + //DL HARQ + if(phy_vars_ue->dlsch_ue[i][j]) { + for(k=0;k<NUMBER_OF_HARQ_PID_MAX && phy_vars_ue->dlsch_ue[i][j]->harq_processes[k];k++) { + phy_vars_ue->dlsch_ue[i][j]->harq_processes[k]->status = SCH_IDLE; + } + } + } + //UL HARQ + if(phy_vars_ue->ulsch_ue[i]) { + for(k=0;k<NUMBER_OF_HARQ_PID_MAX && phy_vars_ue->ulsch_ue[i]->harq_processes[k];k++) { + phy_vars_ue->ulsch_ue[i]->harq_processes[k]->status = SCH_IDLE; + //Set NDIs for all UL HARQs to 0 + phy_vars_ue->ulsch_ue[i]->harq_processes[k]->Ndi = 0; + + } + } + + // flush Msg3 buffer + phy_vars_ue->ulsch_ue_Msg3_active[i] = 0; + + } +} + void ra_failed(u8 Mod_id,u8 eNB_index) { // if contention resolution fails, go back to PRACH @@ -3194,6 +3227,10 @@ int phy_procedures_RN_UE_RX(u8 last_slot, u8 next_slot, relaying_type_t r_type) phy_vars_ue->UE_mode[eNB_id] = RESYNCH; mac_xface->macphy_exit("Connection lost"); //exit(-1); + } else if (ret == PHY_HO_PRACH) { + LOG_I(PHY,"[UE %d] Frame %d, subframe %d, return to PRACH and perform a contention-free access\n", + phy_vars_ue->Mod_id,phy_vars_ue->frame,next_slot>>1); + phy_vars_ue->UE_mode[eNB_id] = PRACH; } } #endif diff --git a/openair2/COMMON/mac_rrc_primitives.h b/openair2/COMMON/mac_rrc_primitives.h index 3906bc8ecbe3c4ee9e4b69855a2075dcef06c228..9b53a0ab5ca6dc18bd8281285699a5b2d7d4fea6 100644 --- a/openair2/COMMON/mac_rrc_primitives.h +++ b/openair2/COMMON/mac_rrc_primitives.h @@ -81,7 +81,9 @@ result could be based on an event-driven measurement report. typedef enum { RRC_OK=0, RRC_ConnSetup_failed, - RRC_PHY_RESYNCH + RRC_PHY_RESYNCH, + RRC_Handover_failed, + RRC_HO_STARTED } RRC_status_t; diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index 67e3172cee5592834ed17ae1e1aa4ccb4cf6e781..22722b65ba8a21594049056818a6229947a675ff 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -1,3 +1,41 @@ +/******************************************************************************* + + Eurecom OpenAirInterface + Copyright(c) 1999 - 2013 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 config.c +* \brief UE and eNB configuration +* \author Raymond Knopp, Navid Nikaein +* \date 2013 +* \version 0.1 +* \email: navid.nikaein@eurecom.fr +* @ingroup _mac + +*/ + #include "COMMON/platform_types.h" #include "COMMON/platform_constants.h" #include "SystemInformationBlockType2.h" @@ -16,6 +54,36 @@ #include "MBSFN-SubframeConfigList.h" #include "PMCH-InfoList-r9.h" #endif + +/* sec 5.9, 36.321: MAC Reset Procedure */ +void ue_mac_reset(u8 Mod_id,u8 eNB_index) { + + //Resetting Bj + UE_mac_inst[Mod_id].scheduling_info.Bj[0] = 0; + UE_mac_inst[Mod_id].scheduling_info.Bj[1] = 0; + UE_mac_inst[Mod_id].scheduling_info.Bj[2] = 0; + //Stopping all timers + + //timeAlignmentTimer expires + + // PHY changes for UE MAC reset + mac_xface->phy_reset_ue(Mod_id,eNB_index); + + // notify RRC to relase PUCCH/SRS + // cancel all pending SRs + UE_mac_inst[Mod_id].scheduling_info.SR_pending=0; + UE_mac_inst[Mod_id].scheduling_info.SR_COUNTER=0; + + // stop ongoing RACH procedure + + // discard explicitly signaled ra_PreambleIndex and ra_RACH_MaskIndex, if any + UE_mac_inst[Mod_id].RA_prach_resources.ra_PreambleIndex = 0; // check! + UE_mac_inst[Mod_id].RA_prach_resources.ra_RACH_MaskIndex = 0; + + ue_init_mac(Mod_id); //This will hopefully do the rest of the MAC reset procedure + +} + int rrc_mac_config_req(u8 Mod_id,u8 eNB_flag,u8 UE_id,u8 eNB_index, RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, struct PhysicalConfigDedicated *physicalConfigDedicated, @@ -25,6 +93,7 @@ int rrc_mac_config_req(u8 Mod_id,u8 eNB_flag,u8 UE_id,u8 eNB_index, LogicalChannelConfig_t *logicalChannelConfig, MeasGapConfig_t *measGapConfig, TDD_Config_t *tdd_Config, + MobilityControlInfo_t *mobilityControlInfo, u8 *SIwindowsize, u16 *SIperiod, ARFCN_ValueEUTRA_t *ul_CarrierFreq, @@ -32,14 +101,12 @@ int rrc_mac_config_req(u8 Mod_id,u8 eNB_flag,u8 UE_id,u8 eNB_index, AdditionalSpectrumEmission_t *additionalSpectrumEmission, struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList #ifdef Rel10 - , - u8 MBMS_Flag, + ,u8 MBMS_Flag, MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList, PMCH_InfoList_r9_t *pmch_InfoList #endif #ifdef CBA - , - u8 num_active_cba_groups, + ,u8 num_active_cba_groups, u16 cba_rnti #endif ) { @@ -60,10 +127,7 @@ int rrc_mac_config_req(u8 Mod_id,u8 eNB_flag,u8 UE_id,u8 eNB_index, } } - if ((tdd_Config!=NULL)|| - (SIwindowsize!=NULL)|| - (SIperiod!=NULL)){ - + if ((tdd_Config!=NULL)||(SIwindowsize!=NULL)||(SIperiod!=NULL)){ if (eNB_flag==1) mac_xface->phy_config_sib1_eNB(Mod_id,tdd_Config,*SIwindowsize,*SIperiod); else @@ -73,27 +137,14 @@ int rrc_mac_config_req(u8 Mod_id,u8 eNB_flag,u8 UE_id,u8 eNB_index, if (radioResourceConfigCommon!=NULL) { if (eNB_flag==1) { LOG_I(MAC,"[CONFIG]SIB2/3 Contents (partial)\n"); - LOG_I(MAC,"[CONFIG]pusch_config_common.n_SB = %ld\n",radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.n_SB); - - LOG_I(MAC,"[CONFIG]pusch_config_common.hoppingMode = %ld\n",radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode); - LOG_I(MAC,"[CONFIG]pusch_config_common.pusch_HoppingOffset = %ld\n", radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset); - LOG_I(MAC,"[CONFIG]pusch_config_common.enable64QAM = %d\n",radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM); - LOG_I(MAC,"[CONFIG]pusch_config_common.groupHoppingEnabled = %d\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled); - - LOG_I(MAC,"[CONFIG]pusch_config_common.groupAssignmentPUSCH = %ld\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH); - - LOG_I(MAC,"[CONFIG]pusch_config_common.sequenceHoppingEnabled = %d\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled); - - LOG_I(MAC,"[CONFIG]pusch_config_common.cyclicShift = %ld\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift); - mac_xface->phy_config_sib2_eNB(Mod_id,radioResourceConfigCommon,ul_CarrierFreq,ul_Bandwidth,additionalSpectrumEmission,mbsfn_SubframeConfigList); } else { @@ -167,8 +218,8 @@ int rrc_mac_config_req(u8 Mod_id,u8 eNB_flag,u8 UE_id,u8 eNB_index, UE_mac_inst[Mod_id].scheduling_info.periodicPHR_SF = get_sf_perioidicPHR_Timer(UE_mac_inst[Mod_id].scheduling_info.periodicPHR_Timer); UE_mac_inst[Mod_id].scheduling_info.prohibitPHR_SF = get_sf_prohibitPHR_Timer(UE_mac_inst[Mod_id].scheduling_info.prohibitPHR_Timer); UE_mac_inst[Mod_id].scheduling_info.PathlossChange_db = get_db_dl_PathlossChange(UE_mac_inst[Mod_id].scheduling_info.PathlossChange); - LOG_D(MAC,"[UE %d] config PHR : periodic %d (SF) prohibit %d (SF) pathlosschange %d (db) \n", - Mod_id, + LOG_D(MAC,"[UE %d] config PHR (%d): periodic %d (SF) prohibit %d (SF) pathlosschange %d (db) \n", + Mod_id,mac_MainConfig->phr_Config->present, UE_mac_inst[Mod_id].scheduling_info.periodicPHR_SF, UE_mac_inst[Mod_id].scheduling_info.prohibitPHR_SF, UE_mac_inst[Mod_id].scheduling_info.PathlossChange_db); @@ -195,10 +246,89 @@ int rrc_mac_config_req(u8 Mod_id,u8 eNB_flag,u8 UE_id,u8 eNB_index, } mac_xface->phy_config_meas_ue(Mod_id,eNB_index,UE_mac_inst[Mod_id].n_adj_cells,UE_mac_inst[Mod_id].adj_cell_id); } + /* + if (quantityConfig != NULL) { + if (quantityConfig[0] != NULL) { + UE_mac_inst[Mod_id].quantityConfig = quantityConfig[0]; + LOG_I(MAC,"UE %d configured filterCoeff.",UE_mac_inst[Mod_id].crnti); + mac_xface->phy_config_meas_ue + } + } + */ } } - - + if (eNB_flag==0) { + if(mobilityControlInfo != NULL) { + + LOG_D(MAC,"[UE%d] MAC Reset procedure triggered by RRC eNB %d \n",Mod_id,eNB_index); + ue_mac_reset(Mod_id,eNB_index); + + if(mobilityControlInfo->radioResourceConfigCommon.rach_ConfigCommon) { + memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->rach_ConfigCommon, + (void *)mobilityControlInfo->radioResourceConfigCommon.rach_ConfigCommon, + sizeof(RACH_ConfigCommon_t)); + } + + memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->prach_Config.prach_ConfigInfo, + (void *)mobilityControlInfo->radioResourceConfigCommon.prach_Config.prach_ConfigInfo, + sizeof(PRACH_ConfigInfo_t)); + UE_mac_inst[Mod_id].radioResourceConfigCommon->prach_Config.rootSequenceIndex = mobilityControlInfo->radioResourceConfigCommon.prach_Config.rootSequenceIndex; + + if(mobilityControlInfo->radioResourceConfigCommon.pdsch_ConfigCommon) { + memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->pdsch_ConfigCommon, + (void *)mobilityControlInfo->radioResourceConfigCommon.pdsch_ConfigCommon, + sizeof(PDSCH_ConfigCommon_t)); + } + // not a pointer: mobilityControlInfo->radioResourceConfigCommon.pusch_ConfigCommon + memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->pusch_ConfigCommon, + (void *)&mobilityControlInfo->radioResourceConfigCommon.pusch_ConfigCommon, + sizeof(PUSCH_ConfigCommon_t)); + + if(mobilityControlInfo->radioResourceConfigCommon.phich_Config) { + /* memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->phich_Config, + (void *)mobilityControlInfo->radioResourceConfigCommon.phich_Config, + sizeof(PHICH_Config_t)); */ + } + if(mobilityControlInfo->radioResourceConfigCommon.pucch_ConfigCommon) { + memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->pucch_ConfigCommon, + (void *)mobilityControlInfo->radioResourceConfigCommon.pucch_ConfigCommon, + sizeof(PUCCH_ConfigCommon_t)); + } + if(mobilityControlInfo->radioResourceConfigCommon.soundingRS_UL_ConfigCommon) { + memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->soundingRS_UL_ConfigCommon, + (void *)mobilityControlInfo->radioResourceConfigCommon.soundingRS_UL_ConfigCommon, + sizeof(SoundingRS_UL_ConfigCommon_t)); + } + if(mobilityControlInfo->radioResourceConfigCommon.uplinkPowerControlCommon) { + memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->uplinkPowerControlCommon, + (void *)mobilityControlInfo->radioResourceConfigCommon.uplinkPowerControlCommon, + sizeof(UplinkPowerControlCommon_t)); + } + //configure antennaInfoCommon somewhere here.. + if(mobilityControlInfo->radioResourceConfigCommon.p_Max) { + //to be configured + } + if(mobilityControlInfo->radioResourceConfigCommon.tdd_Config) { + UE_mac_inst[Mod_id].tdd_Config = mobilityControlInfo->radioResourceConfigCommon.tdd_Config; + } + if(mobilityControlInfo->radioResourceConfigCommon.ul_CyclicPrefixLength) { + memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->ul_CyclicPrefixLength, + (void *)mobilityControlInfo->radioResourceConfigCommon.ul_CyclicPrefixLength, + sizeof(UL_CyclicPrefixLength_t)); + } + + UE_mac_inst[Mod_id].crnti = ((mobilityControlInfo->newUE_Identity.buf[0])|(mobilityControlInfo->newUE_Identity.buf[1]<<8)); + LOG_I(MAC,"[UE %d] Received new identity %x from %d\n", Mod_id, UE_mac_inst[Mod_id].crnti, eNB_index); + UE_mac_inst[Mod_id].rach_ConfigDedicated = malloc(sizeof(*mobilityControlInfo->rach_ConfigDedicated)); + if (mobilityControlInfo->rach_ConfigDedicated){ + memcpy((void*)UE_mac_inst[Mod_id].rach_ConfigDedicated, + (void*)mobilityControlInfo->rach_ConfigDedicated, + sizeof(*mobilityControlInfo->rach_ConfigDedicated)); + } + mac_xface->phy_config_afterHO_ue(Mod_id,eNB_index,mobilityControlInfo,0); + } + } + 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); diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index acfdb62da3ee074377367daa4bf65f871f0f7783..c66218418c61a8d816dfeafe1bd88c8d15c2aab5 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -59,6 +59,7 @@ #include "TDD-Config.h" #include "RACH-ConfigCommon.h" #include "MeasObjectToAddModList.h" +#include "MobilityControlInfo.h" #ifdef Rel10 #include "MBSFN-AreaInfoList-r9.h" #include "MBSFN-SubframeConfigList.h" @@ -139,7 +140,8 @@ typedef enum { CONNECTION_OK=0, CONNECTION_LOST, - PHY_RESYNCH + PHY_RESYNCH, + PHY_HO_PRACH } UE_L2_STATE_t; typedef struct { @@ -713,6 +715,8 @@ typedef struct{ uint8_t ul_active; /// pointer to RRC PHY configuration RadioResourceConfigCommonSIB_t *radioResourceConfigCommon; + /// pointer to RACH_ConfigDedicated (NULL when not active, i.e. upon HO completion or T304 expiry) + struct RACH_ConfigDedicated *rach_ConfigDedicated; /// pointer to RRC PHY configuration struct PhysicalConfigDedicated *physicalConfigDedicated; /// pointer to TDD Configuration (NULL for FDD) @@ -839,6 +843,7 @@ unsigned char generate_dlsch_header(unsigned char *mac_header, @param logicalChannelConfig Pointer to logical channel configuration @param measGapConfig Measurement Gap configuration for MAC (if NULL keep existing configuration) @param tdd_Config TDD Configuration from SIB1 (if NULL keep existing configuration) +@param mobilityControlInfo mobility control info received for Handover @param SIwindowsize SI Windowsize from SIB1 (if NULL keep existing configuration) @param SIperiod SI Period from SIB1 (if NULL keep existing configuration) @param MBMS_Flag indicates MBMS transmission @@ -855,6 +860,7 @@ int rrc_mac_config_req(u8 Mod_id,u8 eNB_flag,u8 UE_id,u8 eNB_index, LogicalChannelConfig_t *logicalChannelConfig, MeasGapConfig_t *measGapConfig, TDD_Config_t *tdd_Config, + MobilityControlInfo_t *mobilityControlInfo, u8 *SIwindowsize, u16 *SIperiod, ARFCN_ValueEUTRA_t *ul_CarrierFreq, @@ -985,11 +991,11 @@ s8 get_deltaP_rampup(u8 Mod_id); //main.c -void chbch_phy_sync_success(u8 Mod_id,u32 frame,u8 CH_index); +void chbch_phy_sync_success(u8 Mod_id,u32 frame,u8 eNB_index); void mrbch_phy_sync_failure(u8 Mod_id, u32 frame,u8 free_eNB_index); -int mac_top_init(int eMBMS_active, u8 cba_group_active); +int mac_top_init(int eMBMS_active, u8 cba_group_active, u8 HO_active); char layer2_init_UE(u8 Mod_id); @@ -1001,7 +1007,7 @@ int mac_init_global_param(void); void mac_top_cleanup(void); -void mac_UE_out_of_sync_ind(u8 Mod_id,u32 frame, u16 CH_index); +void mac_UE_out_of_sync_ind(u8 Mod_id,u32 frame, u16 eNB_index); // eNB functions @@ -1106,8 +1112,8 @@ void UpdateSBnumber(unsigned char Mod_id); //end ALU's algo - - +void ue_mac_reset(u8 Mod_id,u8 eNB_index); +void ue_init_mac(u8 Mod_id); void init_ue_sched_info(void); void add_ue_ulsch_info(u8 Mod_id, u8 UE_id, u8 subframe,UE_ULSCH_STATUS status); void add_ue_dlsch_info(u8 Mod_id, u8 UE_id, u8 subframe,UE_DLSCH_STATUS status); @@ -1270,9 +1276,8 @@ u8 *parse_ulsch_header(u8 *mac_header, u16 tx_lenght); -int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, u8 cba_group_active); +int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, u8 cba_group_active, u8 HO_active); int mac_init(void); -void ue_init_mac(void); s8 add_new_ue(u8 Mod_id, u16 rnti); s8 mac_remove_ue(u8 Mod_id, u8 UE_id); diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index a8cd4ac648ddffc395bb74789463bb0e0634b033..16d5a343afd67fb73791f5afdfee7539addee034 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -4296,6 +4296,12 @@ void eNB_dlsch_ulsch_scheduler(u8 Mod_id,u8 cooperation_flag, u32 frame, u8 subf #endif #ifdef CELLULAR rrc_rx_tx(Mod_id, frame, 0, 0); +#else + // check HO + rrc_rx_tx(Mod_id, + frame, + 1, + Mod_id); #endif #ifdef Rel10 diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index e44b1d5caa777dfdf156b7079a1021b1210eb4b0..1fc5d38a5afe1d63a83a7c0ffd68531bce0f8395 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -97,6 +97,9 @@ void mrbch_phy_sync_failure(u8 Mod_id, u32 frame, u8 free_eNB_index){//init as C layer2_init_eNB(Mod_id, free_eNB_index); openair_rrc_eNB_init(Mod_id); + + + } char layer2_init_eNB(unsigned char Mod_id, unsigned char eNB_index){ @@ -120,7 +123,7 @@ void mac_UE_out_of_sync_ind(u8 Mod_id, u32 frame, u16 eNB_index){ /***********************************************************************/ -int mac_top_init(int eMBMS_active, u8 cba_group_active){ +int mac_top_init(int eMBMS_active, u8 cba_group_active, u8 HO_active){ /***********************************************************************/ unsigned char Mod_id,i,j; RA_TEMPLATE *RA_template; @@ -135,8 +138,11 @@ int mac_top_init(int eMBMS_active, u8 cba_group_active){ mac_xface->macphy_exit("[MAC][MAIN] not enough memory for UEs \n"); } LOG_D(MAC,"[MAIN] ALLOCATE %d Bytes for %d UE_MAC_INST @ %p\n",NB_UE_INST*sizeof(UE_MAC_INST),NB_UE_INST,UE_mac_inst); + bzero(UE_mac_inst,NB_UE_INST*sizeof(UE_MAC_INST)); - ue_init_mac(); + for(i=0;i<NB_UE_INST; i++) + ue_init_mac(i); + } else UE_mac_inst = NULL; @@ -172,7 +178,7 @@ int mac_top_init(int eMBMS_active, u8 cba_group_active){ if (Is_rrc_registered == 1){ LOG_I(MAC,"[MAIN] calling RRC\n"); #ifndef CELLULAR //nothing to be done yet for cellular - openair_rrc_top_init(eMBMS_active, cba_group_active); + openair_rrc_top_init(eMBMS_active, cba_group_active,HO_active); #endif } else { @@ -287,6 +293,7 @@ int mac_top_init(int eMBMS_active, u8 cba_group_active){ //ICIC init param #ifdef ICIC + u8 SB_size; SB_size=mac_xface->get_SB_size(mac_xface->lte_frame_parms->N_RB_DL); srand (time(NULL)); @@ -388,7 +395,7 @@ void mac_top_cleanup(void){ free( Mac_rlc_xface); } -int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, u8 cba_group_active) { +int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, u8 cba_group_active, u8 HO_active) { @@ -447,6 +454,11 @@ int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, u8 cba_group_activ mac_xface->get_ue_active_harq_pid = get_ue_active_harq_pid; mac_xface->get_PL = get_PL; + mac_xface->get_RSRP = get_RSRP; + mac_xface->get_RSRQ = get_RSRQ; + mac_xface->get_RSSI = get_RSSI; + mac_xface->get_n_adj_cells = get_n_adj_cells; + mac_xface->get_rx_total_gain_dB = get_rx_total_gain_dB; mac_xface->get_Po_NOMINAL_PUSCH = get_Po_NOMINAL_PUSCH; mac_xface->get_num_prach_tdd = get_num_prach_tdd; mac_xface->get_fid_prach_tdd = get_fid_prach_tdd; @@ -461,7 +473,7 @@ int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, u8 cba_group_activ mac_xface->phy_config_sib2_eNB = phy_config_sib2_eNB; mac_xface->phy_config_sib2_ue = phy_config_sib2_ue; - + mac_xface->phy_config_afterHO_ue = phy_config_afterHO_ue; #ifdef Rel10 mac_xface->phy_config_sib13_eNB = phy_config_sib13_eNB; mac_xface->phy_config_sib13_ue = phy_config_sib13_ue; @@ -470,6 +482,7 @@ int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, u8 cba_group_activ mac_xface->phy_config_cba_rnti = phy_config_cba_rnti ; #endif mac_xface->phy_config_meas_ue = phy_config_meas_ue; + mac_xface->phy_reset_ue = phy_reset_ue; mac_xface->phy_config_dedicated_eNB = phy_config_dedicated_eNB; mac_xface->phy_config_dedicated_ue = phy_config_dedicated_ue; @@ -481,7 +494,7 @@ int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, u8 cba_group_activ mac_xface->get_PHR = get_PHR; LOG_D(MAC,"[MAIN] ALL INIT OK\n"); - mac_xface->macphy_init(eMBMS_active,cba_group_active); + mac_xface->macphy_init(eMBMS_active,cba_group_active,HO_active); //Mac_rlc_xface->Is_cluster_head[0] = 1; //Mac_rlc_xface->Is_cluster_head[1] = 0; diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index b46b9faf54e4081cfab8212a0b6d1aede70e7af6..e8e8a920f35d4b2f0b1a87a72eddb79e4cf8cee6 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -89,43 +89,42 @@ mapping BSR_names[] = { extern inline unsigned int taus(void); -void ue_init_mac(){ - int i,j; - for (i=0 ; i < NB_UE_INST; i++){ - // default values as deined in 36.331 sec 9.2.2 - LOG_I(MAC,"[UE%d] Applying default macMainConfig\n",i); - LOG_D(MAC, "[MSC_NEW][FRAME 00000][MAC_UE][MOD %02d][]\n", i+NB_eNB_INST); - - //UE_mac_inst[Mod_id].scheduling_info.macConfig=NULL; - UE_mac_inst[i].scheduling_info.retxBSR_Timer= MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560; - UE_mac_inst[i].scheduling_info.periodicBSR_Timer=MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity; - UE_mac_inst[i].scheduling_info.periodicPHR_Timer = MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; - UE_mac_inst[i].scheduling_info.prohibitPHR_Timer = MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; - UE_mac_inst[i].scheduling_info.PathlossChange_db = MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; - UE_mac_inst[i].PHR_state = MAC_MainConfig__phr_Config_PR_setup; - UE_mac_inst[i].scheduling_info.SR_COUNTER=0; - UE_mac_inst[i].scheduling_info.sr_ProhibitTimer=0; - UE_mac_inst[i].scheduling_info.sr_ProhibitTimer_Running=0; - UE_mac_inst[i].scheduling_info.maxHARQ_Tx=MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; - UE_mac_inst[i].scheduling_info.ttiBundling=0; - UE_mac_inst[i].scheduling_info.drx_config=NULL; - UE_mac_inst[i].scheduling_info.phr_config=NULL; - UE_mac_inst[i].scheduling_info.periodicBSR_SF = get_sf_periodicBSRTimer(UE_mac_inst[i].scheduling_info.periodicBSR_Timer); - UE_mac_inst[i].scheduling_info.retxBSR_SF = get_sf_retxBSRTimer(UE_mac_inst[i].scheduling_info.retxBSR_Timer); - UE_mac_inst[i].scheduling_info.periodicPHR_SF = get_sf_perioidicPHR_Timer(UE_mac_inst[i].scheduling_info.periodicPHR_Timer); - UE_mac_inst[i].scheduling_info.prohibitPHR_SF = get_sf_prohibitPHR_Timer(UE_mac_inst[i].scheduling_info.prohibitPHR_Timer); - UE_mac_inst[i].scheduling_info.PathlossChange_db = get_db_dl_PathlossChange(UE_mac_inst[i].scheduling_info.PathlossChange); - - for (j=0; j < MAX_NUM_LCID; j++){ - LOG_D(MAC,"[UE%d] Applying default logical channel config for LCGID %d\n",i,j); - UE_mac_inst[i].scheduling_info.Bj[j]=-1; - UE_mac_inst[i].scheduling_info.bucket_size[j]=-1; - if (j < DTCH) // initilize all control channels lcgid to 0 - UE_mac_inst[i].scheduling_info.LCGID[j]=0; - else // initialize all the data channels lcgid to 1 - UE_mac_inst[i].scheduling_info.LCGID[j]=1; - UE_mac_inst[i].scheduling_info.LCID_status[j]=0; - } +void ue_init_mac(u8 Mod_id){ + int i; + + // default values as deined in 36.331 sec 9.2.2 + LOG_I(MAC,"[UE%d] Applying default macMainConfig\n",Mod_id); + LOG_D(MAC, "[MSC_NEW][FRAME 00000][MAC_UE][MOD %02d][]\n", Mod_id+NB_eNB_INST); + + //UE_mac_inst[Mod_id].scheduling_info.macConfig=NULL; + UE_mac_inst[Mod_id].scheduling_info.retxBSR_Timer= MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560; + UE_mac_inst[Mod_id].scheduling_info.periodicBSR_Timer=MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity; + UE_mac_inst[Mod_id].scheduling_info.periodicPHR_Timer = MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; + UE_mac_inst[Mod_id].scheduling_info.prohibitPHR_Timer = MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; + UE_mac_inst[Mod_id].scheduling_info.PathlossChange_db = MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; + UE_mac_inst[Mod_id].PHR_state = MAC_MainConfig__phr_Config_PR_setup; + UE_mac_inst[Mod_id].scheduling_info.SR_COUNTER=0; + UE_mac_inst[Mod_id].scheduling_info.sr_ProhibitTimer=0; + UE_mac_inst[Mod_id].scheduling_info.sr_ProhibitTimer_Running=0; + UE_mac_inst[Mod_id].scheduling_info.maxHARQ_Tx=MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; + UE_mac_inst[Mod_id].scheduling_info.ttiBundling=0; + UE_mac_inst[Mod_id].scheduling_info.drx_config=NULL; + UE_mac_inst[Mod_id].scheduling_info.phr_config=NULL; + UE_mac_inst[Mod_id].scheduling_info.periodicBSR_SF = get_sf_periodicBSRTimer(UE_mac_inst[Mod_id].scheduling_info.periodicBSR_Timer); + UE_mac_inst[Mod_id].scheduling_info.retxBSR_SF = get_sf_retxBSRTimer(UE_mac_inst[Mod_id].scheduling_info.retxBSR_Timer); + UE_mac_inst[Mod_id].scheduling_info.periodicPHR_SF = get_sf_perioidicPHR_Timer(UE_mac_inst[Mod_id].scheduling_info.periodicPHR_Timer); + UE_mac_inst[Mod_id].scheduling_info.prohibitPHR_SF = get_sf_prohibitPHR_Timer(UE_mac_inst[Mod_id].scheduling_info.prohibitPHR_Timer); + UE_mac_inst[Mod_id].scheduling_info.PathlossChange_db = get_db_dl_PathlossChange(UE_mac_inst[Mod_id].scheduling_info.PathlossChange); + + for (i=0; i < MAX_NUM_LCID; i++){ + LOG_D(MAC,"[UE%d] Applying default logical channel config for LCGID %d\n",Mod_id,i); + UE_mac_inst[Mod_id].scheduling_info.Bj[i]=-1; + UE_mac_inst[Mod_id].scheduling_info.bucket_size[i]=-1; + if (i < DTCH) // initilize all control channels lcgid to 0 + UE_mac_inst[Mod_id].scheduling_info.LCGID[i]=0; + else // initialize all the data channels lcgid to 1 + UE_mac_inst[Mod_id].scheduling_info.LCGID[i]=1; + UE_mac_inst[Mod_id].scheduling_info.LCID_status[i]=0; } } @@ -1366,6 +1365,15 @@ UE_L2_STATE_t ue_scheduler(u8 Mod_id,u32 frame, u8 subframe, lte_subframe_t dire case RRC_PHY_RESYNCH: LOG_E(MAC,"RRC Loss of synch, returning PHY_RESYNCH\n"); return(PHY_RESYNCH); + case RRC_Handover_failed: + LOG_D(MAC,"Handover failure for UE %d eNB_index %d\n",Mod_id,eNB_index); + //Invalid...need to add another MAC UE state for re-connection procedure + mac_xface->phy_config_afterHO_ue(Mod_id,eNB_index,(MobilityControlInfo_t *)NULL,1); + //return(3); + break; + case RRC_HO_STARTED: + LOG_I(MAC,"RRC handover, Instruct PHY to start the contention-free PRACH and synchronization\n"); + return(PHY_HO_PRACH); default: break; } @@ -1402,7 +1410,7 @@ UE_L2_STATE_t ue_scheduler(u8 Mod_id,u32 frame, u8 subframe, lte_subframe_t dire // Put this in another function // Get RLC status info and update Bj for all lcids that are active - for (lcid=CCCH; lcid <= DTCH; lcid++ ) { + for (lcid=DCCH; lcid <= DTCH; lcid++ ) { if ((lcid == 0) ||(UE_mac_inst[Mod_id].logicalChannelConfig[lcid])) { // meausre the Bj if ((direction == SF_UL)&& (UE_mac_inst[Mod_id].scheduling_info.Bj[lcid] >= 0)){ @@ -1573,9 +1581,11 @@ int update_bsr(u8 Mod_id, u32 frame, u8 lcid, u8 lcg_id){ u8 sr_pending = 0; if ((lcg_id < 0) || (lcg_id > MAX_NUM_LCGID) ) return sr_pending; - - UE_mac_inst[Mod_id].scheduling_info.BSR[lcg_id]=0; - UE_mac_inst[Mod_id].scheduling_info.BSR_bytes[lcg_id]=0; + // fixme: need a better way to reset + if ((lcid == DCCH) || (lcid == DTCH)){ + UE_mac_inst[Mod_id].scheduling_info.BSR[lcg_id]=0; + UE_mac_inst[Mod_id].scheduling_info.BSR_bytes[lcg_id]=0; + } // for (lcid =0 ; lcid < MAX_NUM_LCID; lcid++) { if (UE_mac_inst[Mod_id].scheduling_info.LCGID[lcid] == lcg_id) { rlc_status = mac_rlc_status_ind(Mod_id+NB_eNB_INST,frame,0,RLC_MBMS_NO, @@ -1587,13 +1597,13 @@ int update_bsr(u8 Mod_id, u32 frame, u8 lcid, u8 lcg_id){ UE_mac_inst[Mod_id].scheduling_info.BSR[lcg_id] += locate (BSR_TABLE,BSR_TABLE_SIZE, rlc_status.bytes_in_buffer); UE_mac_inst[Mod_id].scheduling_info.BSR_bytes[lcg_id] += rlc_status.bytes_in_buffer; // UE_mac_inst[Mod_id].scheduling_info.BSR_short_lcid = lcid; // only applicable to short bsr + LOG_D(MAC,"[UE %d] BSR level %d (LCGID %d, rlc buffer %d byte)\n", + Mod_id, UE_mac_inst[Mod_id].scheduling_info.BSR[lcg_id],lcg_id, UE_mac_inst[Mod_id].scheduling_info.BSR_bytes[lcg_id]); } else UE_mac_inst[Mod_id].scheduling_info.LCID_status[lcid]=LCID_EMPTY; } //} - //LOG_D(MAC,"[UE %d] BSR level %d (LCGID %d, rlc buffer %d byte)\n", - // Mod_id, UE_mac_inst[Mod_id].scheduling_info.BSR[lcg_id],lcg_id, UE_mac_inst[Mod_id].scheduling_info.BSR_bytes[lcg_id]); return sr_pending; } diff --git a/openair2/LAYER2/MAC/vars.h b/openair2/LAYER2/MAC/vars.h index a1ec80d1583743e45242b6f34ea8177ab207abb2..522ca53405bd86264f9a196c7c40dccbe97c552a 100644 --- a/openair2/LAYER2/MAC/vars.h +++ b/openair2/LAYER2/MAC/vars.h @@ -31,6 +31,7 @@ * \author Raymond Knopp, Navid Nikaein * \date 2012 * \version 1.0 +* \email navid.nikaein@eurecom.fr * @ingroup _mac */ @@ -91,6 +92,7 @@ DCI1A_5MHz_TDD_1_6_t BCCH_alloc_pdu; DCI1A_5MHz_TDD_1_6_t CCCH_alloc_pdu; DCI1_5MHz_TDD_t DLSCH_alloc_pdu; + #ifdef Rel10 DCI1C_5MHz_t MCCH_alloc_pdu; #endif diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 74b29eb070ced3d634e585e547b2ecca5b363c4d..2d971e90c99e00874b0559b978a8191c41db639c 100755 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -733,7 +733,7 @@ BOOL rrc_pdcp_config_asn1_req (module_id_t module_id, u32_t frame, u8_t eNB_flag } if (drb2release_list != NULL) { - for (cnt=0;cnt<drb2add_list->list.count;cnt++) { + for (cnt=0;cnt<drb2release_list->list.count;cnt++) { pdrb_id = drb2release_list->list.array[cnt]; rb_id = (index * NB_RB_MAX) + *pdrb_id; action = ACTION_REMOVE; diff --git a/openair2/LAYER2/RLC/rlc_rrc.c b/openair2/LAYER2/RLC/rlc_rrc.c index 8c3dd898fc61c3301b54cf7294eb80623647ba1c..432f64c0306b72393794969cad894e93f65f0f23 100644 --- a/openair2/LAYER2/RLC/rlc_rrc.c +++ b/openair2/LAYER2/RLC/rlc_rrc.c @@ -256,10 +256,10 @@ rlc_op_status_t rrc_rlc_config_asn1_req (module_id_t module_idP, u32_t frameP, u } } if (drb2release_listP != NULL) { - for (cnt=0;cnt<drb2add_listP->list.count;cnt++) { - pdrb_id = drb2release_listP->list.array[cnt]; - rrc_rlc_remove_rlc(module_idP, (UE_index * NB_RB_MAX) + *pdrb_id, frameP); - } + for (cnt=0;cnt<drb2release_listP->list.count;cnt++) { + pdrb_id = drb2release_listP->list.array[cnt]; + rrc_rlc_remove_rlc(module_idP, (UE_index * NB_RB_MAX) + *pdrb_id, frameP); + } } diff --git a/openair2/PHY_INTERFACE/defs.h b/openair2/PHY_INTERFACE/defs.h index 968192dfc4df3978263bfcc8c12c78048994946a..c88cf7beee757e725856741bf3d5b90ae5eb9ba6 100755 --- a/openair2/PHY_INTERFACE/defs.h +++ b/openair2/PHY_INTERFACE/defs.h @@ -31,6 +31,7 @@ * \author Raymond Knopp and Navid Nikaein * \date 2011 * \version 0.5 +* \mail navid.nikaein@eurecom.fr or openair_tech@eurecom.fr * @ingroup _mac */ @@ -57,7 +58,7 @@ typedef struct { /// Pointer function that initializes L2 - int (*macphy_init)(int eMBMS_active, u8 CBA_enabled); + int (*macphy_init)(int eMBMS_active, u8 CBA_active,u8 HO_active); /// Pointer function that stops the low-level scheduler due an exit condition void (*macphy_exit)(const char *); @@ -112,7 +113,7 @@ typedef struct void (*phy_config_sib13_eNB)(u8 Mod_id,int mbsfn_Area_idx, long mbsfn_AreaId_r9); #endif - + /// PHY-Config-Dedicated eNB void (*phy_config_dedicated_eNB)(u8 Mod_id,u16 rnti, struct PhysicalConfigDedicated *physicalConfigDedicated); @@ -124,8 +125,11 @@ typedef struct // configure the cba rnti at the physical layer void (*phy_config_cba_rnti)(u8 Mod_id,u8 eNB_flag, u8 index, u16 cba_rnti, u8 cba_group_id, u8 num_active_cba_groups); - // UE functions - + /// UE functions + + /// reset the ue phy + void (*phy_reset_ue)(u8 Mod_id,u8 eNB_index); + /// Indicate loss of synchronization of PBCH for this eNB to MAC layer void (*out_of_sync_ind)(u8 Mod_id,u32 frame,u16 eNB_index); @@ -185,6 +189,10 @@ typedef struct void (*phy_config_sib13_ue)(u8 Mod_id,u8 CH_index,int mbsfn_Area_idx, long mbsfn_AreaId_r9); #endif + /// Configure Common PHY parameters from mobilityControlInfo + void (*phy_config_afterHO_ue)(u8 Mod_id,u8 CH_index, + MobilityControlInfo_t *mobilityControlInfo, + u8 ho_failed); /// Function to indicate failure of contention resolution or RA procedure void (*ra_failed)(u8 Mod_id,u8 eNB_index); @@ -233,11 +241,26 @@ typedef struct /// Function for UE MAC to retrieve measured Path Loss s16 (*get_PL)(u8 Mod_id,u8 eNB_index); + /// Function for UE MAC to retrieve the rssi + u8 (*get_RSSI)(u8 Mod_id); + + /// Function for UE MAC to retrieve the total gain + u8 (*get_rx_total_gain_dB)(u8 Mod_id); + + /// Function for UE MAC to retrieve the number of adjustent cells + u8 (*get_n_adj_cells)(u8 Mod_id); + /// Function for UE MAC to retrieve RSRP/RSRQ measurements - u8* (*get_RSRP)(u8 Mod_id,u8 eNB_index); + u8 (*get_RSRP)(u8 Mod_id,u8 eNB_index); /// Function for UE MAC to retrieve RSRP/RSRQ measurements - u8* (*get_RSRQ)(u8 Mod_id,u8 eNB_index); + u8 (*get_RSRQ)(u8 Mod_id,u8 eNB_index); + + /// Function for UE MAC to set the layer3 filtered RSRP/RSRQ measurements + u8 (*set_RSRP_filtered)(u8 Mod_id,u8 eNB_index,float rsrp); + + /// Function for UE MAC to set the layer3 filtered RSRP/RSRQ measurements + u8 (*set_RSRQ_filtered)(u8 Mod_id,u8 eNB_index,float rsrq); /// Function for UE/eNB MAC to retrieve number of PRACH in TDD u8 (*get_num_prach_tdd)(LTE_DL_FRAME_PARMS *frame_parms); diff --git a/openair2/RRC/LITE/L2_interface.c b/openair2/RRC/LITE/L2_interface.c index af1486fde134c9652d75f3c1d4b3dcfc94b41623..e9b1e426d282b153fdf20ff815c632875519d884 100644 --- a/openair2/RRC/LITE/L2_interface.c +++ b/openair2/RRC/LITE/L2_interface.c @@ -514,9 +514,9 @@ void rrc_lite_data_ind( u8 Mod_id, u32 frame, u8 eNB_flag,u32 Srb_id, u32 sdu_si u8 DCCH_index = Srb_id % NB_RB_MAX; LOG_N(RRC,"[%s %d] Frame %d: received a DCCH %d message on SRB %d with Size %d\n", - (eNB_flag == 1)? "eNB": "UE", - (eNB_flag == 1)? Mod_id : UE_index, - frame, DCCH_index,Srb_id-1,sdu_size); + (eNB_flag == 1)? "eNB": "UE", + (eNB_flag == 1)? Mod_id : UE_index, + frame, DCCH_index,Srb_id-1,sdu_size); #if defined(ENABLE_ITTI) { diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c index a1c6e34bb0bd15b06738f1261252fd2634866b9b..647154570380e4fedcf4c1bc27464e03b5ff8973 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c @@ -1,3 +1,41 @@ +/******************************************************************************* + + 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 asn1_msg.c +* \brief primitives to build the asn1 messages +* \author Raymond Knopp and Navid Nikaein +* \date 2011 +* \version 1.0 +* \company Eurecom +* \email: raymond.knopp@eurecom.fr and navid.nikaein@eurecom.fr +*/ + #ifdef USER_MODE #include <stdio.h> #include <sys/types.h> @@ -78,7 +116,16 @@ uint16_t two_tier_hexagonal_adjacent_cellIds[7][6] = {{1,2,4,5,7,8}, // CellI uint16_t get_adjacent_cell_id(uint8_t Mod_id,uint8_t index) { return(two_tier_hexagonal_adjacent_cellIds[Mod_id][index]); } - +/* This only works for the hexagonal topology...need a more general function for other topologies */ +u8 get_adjacent_cell_mod_id(uint16_t phyCellId) { + u8 i; + for(i=0;i<7;i++) { + if(two_tier_hexagonal_cellIds[i] == phyCellId) + return i; + } + LOG_E(RRC,"\nCannot get adjacent cell mod id! Fatal error!\n"); + return 0xFF; //error! +} /* uint8_t do_SIB1(LTE_DL_FRAME_PARMS *frame_parms, uint8_t *buffer, SystemInformationBlockType1_t *sib1) { @@ -1422,10 +1469,13 @@ uint8_t do_RRCConnectionReconfiguration(uint8_t Mod_id struct PhysicalConfigDedicated *physicalConfigDedicated, MeasObjectToAddModList_t *MeasObj_list, ReportConfigToAddModList_t *ReportConfig_list, - QuantityConfig_t *QuantityConfig, + QuantityConfig_t *quantityConfig, MeasIdToAddModList_t *MeasId_list, MAC_MainConfig_t *mac_MainConfig, MeasGapConfig_t *measGapConfig, + MobilityControlInfo_t *mobilityInfo, + struct MeasConfig__speedStatePars *speedStatePars, + RSRP_Range_t *rsrp, C_RNTI_t *cba_rnti, uint8_t *nas_pdu, uint32_t nas_length @@ -1436,8 +1486,7 @@ uint8_t do_RRCConnectionReconfiguration(uint8_t Mod_id DL_DCCH_Message_t dl_dcch_msg; RRCConnectionReconfiguration_t *rrcConnectionReconfiguration; - // int i; - + memset(&dl_dcch_msg,0,sizeof(DL_DCCH_Message_t)); dl_dcch_msg.message.present = DL_DCCH_MessageType_PR_c1; @@ -1458,7 +1507,7 @@ uint8_t do_RRCConnectionReconfiguration(uint8_t Mod_id #ifdef CBA rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->cba_RNTI_vlola= cba_rnti; #endif - if (mac_MainConfig) { + if (mac_MainConfig!=NULL) { rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->mac_MainConfig = CALLOC(1,sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->mac_MainConfig)); rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->mac_MainConfig->present =RadioResourceConfigDedicated__mac_MainConfig_PR_explicitValue; memcpy(&rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue, @@ -1476,10 +1525,31 @@ uint8_t do_RRCConnectionReconfiguration(uint8_t Mod_id rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list; rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measIdToAddModList = MeasId_list; rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measObjectToAddModList = MeasObj_list; + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->quantityConfig = quantityConfig; + /* if (quantityConfig!=NULL) { + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->quantityConfig = CALLOC(1,sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->quantityConfig)); + memcpy((void *)rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->quantityConfig, + (void *)quantityConfig, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->quantityConfig)); + } + else + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->quantityConfig = NULL; + */ + if(speedStatePars != NULL) { + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->speedStatePars = CALLOC(1,sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->speedStatePars)); + memcpy((void *)rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->speedStatePars, + (void *)speedStatePars,sizeof(*speedStatePars)); + } + else + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->speedStatePars = NULL; - - // Note: RK, I'm not sure this is ok, we have to use ASN_SEQ_ADD - rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo = NULL; + if (mobilityInfo !=NULL) { + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo = CALLOC(1,sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo)); + memcpy((void *)rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo, (void *)mobilityInfo,sizeof(MobilityControlInfo_t)); + } + else + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo = NULL; + if ((nas_pdu == NULL) || (nas_length == 0)) { rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.dedicatedInfoNASList = (DedicatedInfoNAS_t*)NULL; } else { @@ -1489,13 +1559,14 @@ uint8_t do_RRCConnectionReconfiguration(uint8_t Mod_id dedicatedInfoNAS->size = nas_length; } rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.securityConfigHO = NULL; + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->s_Measure= rsrp; enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message, (void*)&dl_dcch_msg, buffer, - 100); + RRC_BUF_SIZE); #ifdef XER_PRINT - xer_fprint(stdout,&asn_DEF_DL_DCCH_Message,(void*)&dl_dcch_msg); + xer_fprint(stdout,&asn_DEF_DL_DCCH_Message,(void*)&dl_dcch_msg); #endif //#ifdef USER_MODE LOG_I(RRC,"RRCConnectionReconfiguration Encoded %d bits (%d bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); @@ -1677,44 +1748,44 @@ uint8_t do_MeasurementReport(uint8_t *buffer,int measid,int phy_id,int rsrp_s,in asn_set_empty(&measresult_cgi2->cellGlobalId.plmn_Identity.mcc->list);//.size=0; - MCC_MNC_Digit_t dummy; - dummy=2;ASN_SEQUENCE_ADD(&measresult_cgi2->cellGlobalId.plmn_Identity.mcc->list,&dummy); - dummy=6;ASN_SEQUENCE_ADD(&measresult_cgi2->cellGlobalId.plmn_Identity.mcc->list,&dummy); - dummy=2;ASN_SEQUENCE_ADD(&measresult_cgi2->cellGlobalId.plmn_Identity.mcc->list,&dummy); - - measresult_cgi2->cellGlobalId.plmn_Identity.mnc.list.size=0; - measresult_cgi2->cellGlobalId.plmn_Identity.mnc.list.count=0; - dummy=8;ASN_SEQUENCE_ADD(&measresult_cgi2->cellGlobalId.plmn_Identity.mnc.list,&dummy); - dummy=0;ASN_SEQUENCE_ADD(&measresult_cgi2->cellGlobalId.plmn_Identity.mnc.list,&dummy); - - - measresult_cgi2->cellGlobalId.cellIdentity.buf=MALLOC(8); - measresult_cgi2->cellGlobalId.cellIdentity.buf[0]=0x01; - measresult_cgi2->cellGlobalId.cellIdentity.buf[1]=0x48; - measresult_cgi2->cellGlobalId.cellIdentity.buf[2]=0x0f; - measresult_cgi2->cellGlobalId.cellIdentity.buf[3]=0x03; - measresult_cgi2->cellGlobalId.cellIdentity.size=4; - measresult_cgi2->cellGlobalId.cellIdentity.bits_unused=4; - - measresult_cgi2->trackingAreaCode.buf = MALLOC(2); - measresult_cgi2->trackingAreaCode.buf[0]=0x00; - measresult_cgi2->trackingAreaCode.buf[1]=0x10; - measresult_cgi2->trackingAreaCode.size=2; - measresult_cgi2->trackingAreaCode.bits_unused=0; - - - measresulteutra2->cgi_Info=measresult_cgi2; - struct MeasResultEUTRA__measResult meas2; - // int rsrp_va=10; - meas2.rsrpResult=&rsrp_t; - //&rsrp_va; - meas2.rsrqResult=&rsrq_t; + MCC_MNC_Digit_t dummy; + dummy=2;ASN_SEQUENCE_ADD(&measresult_cgi2->cellGlobalId.plmn_Identity.mcc->list,&dummy); + dummy=6;ASN_SEQUENCE_ADD(&measresult_cgi2->cellGlobalId.plmn_Identity.mcc->list,&dummy); + dummy=2;ASN_SEQUENCE_ADD(&measresult_cgi2->cellGlobalId.plmn_Identity.mcc->list,&dummy); + + measresult_cgi2->cellGlobalId.plmn_Identity.mnc.list.size=0; + measresult_cgi2->cellGlobalId.plmn_Identity.mnc.list.count=0; + dummy=8;ASN_SEQUENCE_ADD(&measresult_cgi2->cellGlobalId.plmn_Identity.mnc.list,&dummy); + dummy=0;ASN_SEQUENCE_ADD(&measresult_cgi2->cellGlobalId.plmn_Identity.mnc.list,&dummy); + + + measresult_cgi2->cellGlobalId.cellIdentity.buf=MALLOC(8); + measresult_cgi2->cellGlobalId.cellIdentity.buf[0]=0x01; + measresult_cgi2->cellGlobalId.cellIdentity.buf[1]=0x48; + measresult_cgi2->cellGlobalId.cellIdentity.buf[2]=0x0f; + measresult_cgi2->cellGlobalId.cellIdentity.buf[3]=0x03; + measresult_cgi2->cellGlobalId.cellIdentity.size=4; + measresult_cgi2->cellGlobalId.cellIdentity.bits_unused=4; + + measresult_cgi2->trackingAreaCode.buf = MALLOC(2); + measresult_cgi2->trackingAreaCode.buf[0]=0x00; + measresult_cgi2->trackingAreaCode.buf[1]=0x10; + measresult_cgi2->trackingAreaCode.size=2; + measresult_cgi2->trackingAreaCode.bits_unused=0; + - measresulteutra2->measResult=meas2; + measresulteutra2->cgi_Info=measresult_cgi2; + struct MeasResultEUTRA__measResult meas2; + // int rsrp_va=10; + meas2.rsrpResult=&rsrp_t; + //&rsrp_va; + meas2.rsrqResult=&rsrq_t; - ASN_SEQUENCE_ADD(&measResultListEUTRA2->list,measresulteutra2); + measresulteutra2->measResult=meas2; - measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultNeighCells->choice.measResultListEUTRA=*(measResultListEUTRA2); + ASN_SEQUENCE_ADD(&measResultListEUTRA2->list,measresulteutra2); + + measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultNeighCells->choice.measResultListEUTRA=*(measResultListEUTRA2); enc_rval = uper_encode_to_buffer(&asn_DEF_UL_DCCH_Message, diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.h b/openair2/RRC/LITE/MESSAGES/asn1_msg.h index 6cca670c97d81e2030ee6135ea1bfd1f18bac468..4c912a942d6dea61d8bd4404e21043b419f91e70 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.h @@ -1,3 +1,41 @@ +/******************************************************************************* + + 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 asn1_msg.h +* \brief primitives to build the asn1 messages +* \author Raymond Knopp and Navid Nikaein +* \date 2011 +* \version 1.0 +* \company Eurecom +* \email: raymond.knopp@eurecom.fr and navid.nikaein@eurecom.fr +*/ + #ifdef USER_MODE #include <stdio.h> #include <sys/types.h> @@ -105,6 +143,8 @@ uint8_t do_RRCConnectionSetup(uint8_t *buffer, @param ReportConfig_list Pointer to ReportConfig List (NULL if no additions/modifications) @param QuantityConfig Pointer to QuantityConfig to be modified (NULL if no modifications) @param MeasId_list Pointer to MeasID List (NULL if no additions/modifications) +@param mobilityInfo mobility control information for handover +@param speedStatePars speed state parameteres for handover @param mac_MainConfig Pointer to Mac_MainConfig(NULL if no modifications) @param measGapConfig Pointer to MeasGapConfig (NULL if no modifications) @param cba_rnti RNTI for the cba transmission @@ -121,11 +161,14 @@ uint8_t do_RRCConnectionReconfiguration(uint8_t Mod_id struct PhysicalConfigDedicated *physicalConfigDedicated, MeasObjectToAddModList_t *MeasObj_list, ReportConfigToAddModList_t *ReportConfig_list, - QuantityConfig_t *QuantityConfig, + QuantityConfig_t *quantityConfig, MeasIdToAddModList_t *MeasId_list, MAC_MainConfig_t *mac_MainConfig, MeasGapConfig_t *measGapConfig, - C_RNTI_t *cba_rnti, + MobilityControlInfo_t *mobilityInfo, + struct MeasConfig__speedStatePars *speedStatePars, + RSRP_Range_t *rsrp, + C_RNTI_t *cba_rnti, uint8_t *nas_pdu, uint32_t nas_length); diff --git a/openair2/RRC/LITE/defs.h b/openair2/RRC/LITE/defs.h index c95527af61a667125bcf38fee8f8f57b9a04553f..486b487e72c4f6482512c5ff5bcdb97658bff741 100644 --- a/openair2/RRC/LITE/defs.h +++ b/openair2/RRC/LITE/defs.h @@ -71,6 +71,8 @@ #include "MCCH-Message.h" #include "MBSFNAreaConfiguration-r9.h" #endif +#include "AS-Config.h" +#include "AS-Context.h" #include "UE-EUTRA-Capability.h" #include "MeasResults.h" @@ -88,16 +90,23 @@ //#define NUM_PRECONFIGURED_LCHAN (NB_CH_CX*2) //BCCH, CCCH -#define CH_READY 0 - typedef enum { RRC_IDLE=0, RRC_SI_RECEIVED, RRC_CONNECTED, - RRC_RECONFIGURED + RRC_RECONFIGURED, + RRC_HO_EXECUTION } UE_STATE_t; +typedef enum { + HO_IDLE=0, + HO_MEASURMENT, + HO_PREPARE, + HO_CMD, // initiated by the src eNB + HO_COMPLETE // initiated by the target eNB +} HO_STATE_t; + //#define NUMBER_OF_UE_MAX MAX_MOBILES_PER_RG #define RRM_FREE(p) if ( (p) != NULL) { free(p) ; p=NULL ; } @@ -105,12 +114,12 @@ typedef enum { #define RRM_CALLOC(t,n) (t *) malloc16( sizeof(t) * n) #define RRM_CALLOC2(t,s) (t *) malloc16( s ) -#define MAX_MEAS_OBJ 3 -#define MAX_MEAS_CONFIG 3 -#define MAX_MEAS_ID 3 +#define MAX_MEAS_OBJ 6 +#define MAX_MEAS_CONFIG 6 +#define MAX_MEAS_ID 6 #define PAYLOAD_SIZE_MAX 1024 - +#define RRC_BUF_SIZE 140 #define UNDEF_SECURITY_MODE 0xff #define NO_SECURITY_MODE 0x33 @@ -126,6 +135,8 @@ typedef struct{ u8 MCCHStatus[8]; // MAX_MBSFN_AREA #endif u8 SIwindowsize; + u8 handoverTarget; + HO_STATE_t ho_state; u16 SIperiod; unsigned short UE_index; u32 T300_active; @@ -154,8 +165,19 @@ union{ }Info; }RRC_INFO; - - +/* Intermediate structure for Hanodver management. Associated per-UE in eNB_RRC_INST */ +typedef struct{ + u8 ho_prepare; + u8 ho_complete; + u8 modid_s; //Mod_id of serving cell + u8 modid_t; //Mod_id of target cell + u8 ueid_s; //UE index in serving cell + u8 ueid_t; //UE index in target cell + AS_Config_t as_config; /* these two parameters are taken from 36.331 section 10.2.2: HandoverPreparationInformation-r8-IEs */ + AS_Context_t as_context; /* They are mandatory for HO */ + uint8_t buf[RRC_BUF_SIZE]; /* ASN.1 encoded handoverCommandMessage */ + int size; /* size of above message in bytes */ +}HANDOVER_INFO; #define RRC_HEADER_SIZE_MAX 64 #define RRC_BUFFER_SIZE_MAX 1024 @@ -192,10 +214,19 @@ typedef struct{ SRB_INFO Srb_info; u8 Active; u8 Status; -u32 Next_check_frame; + u32 Next_check_frame; }SRB_INFO_TABLE_ENTRY; +typedef struct { + MeasId_t measId; + //CellsTriggeredList cellsTriggeredList;//OPTIONAL + u32 numberOfReportsSent; +} MEAS_REPORT_LIST; +typedef struct { + PhysCellId_t targetCellId; + u8 measFlag; +}HANDOVER_INFO_UE; typedef struct{ @@ -241,12 +272,13 @@ typedef struct{ SRB_INFO Srb0; SRB_INFO_TABLE_ENTRY Srb1[NUMBER_OF_UE_MAX+1]; SRB_INFO_TABLE_ENTRY Srb2[NUMBER_OF_UE_MAX+1]; - + MeasConfig_t *measConfig[NUMBER_OF_UE_MAX]; + HANDOVER_INFO *handover_info[NUMBER_OF_UE_MAX]; + uint8_t HO_flag; #if defined(ENABLE_SECURITY) /* KeNB as derived from KASME received from EPC */ uint8_t kenb[NUMBER_OF_UE_MAX][32]; #endif - /* Used integrity/ciphering algorithms */ e_SecurityAlgorithmConfig__cipheringAlgorithm ciphering_algorithm[NUMBER_OF_UE_MAX]; e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm[NUMBER_OF_UE_MAX]; @@ -266,6 +298,7 @@ typedef struct{ SRB_INFO Srb0[NB_SIG_CNX_UE]; SRB_INFO_TABLE_ENTRY Srb1[NB_CNX_UE]; SRB_INFO_TABLE_ENTRY Srb2[NB_CNX_UE]; + HANDOVER_INFO_UE HandoverInfoUe; u8 *SIB1[NB_CNX_UE]; u8 sizeof_SIB1[NB_CNX_UE]; u8 *SI[NB_CNX_UE]; @@ -305,12 +338,20 @@ typedef struct{ struct ReportConfigToAddMod *ReportConfig[NB_CNX_UE][MAX_MEAS_CONFIG]; struct QuantityConfig *QuantityConfig[NB_CNX_UE]; struct MeasIdToAddMod *MeasId[NB_CNX_UE][MAX_MEAS_ID]; + MEAS_REPORT_LIST *measReportList[NB_CNX_UE][MAX_MEAS_ID]; + u32 measTimer[NB_CNX_UE][MAX_MEAS_ID][6]; // 6 neighboring cells RSRP_Range_t s_measure; + struct MeasConfig__speedStatePars *speedStatePars; struct PhysicalConfigDedicated *physicalConfigDedicated[NB_CNX_UE]; struct SPS_Config *sps_Config[NB_CNX_UE]; MAC_MainConfig_t *mac_MainConfig[NB_CNX_UE]; MeasGapConfig_t *measGapConfig[NB_CNX_UE]; - + double filter_coeff_rsrp; // [7] ??? + double filter_coeff_rsrq; // [7] ??? + float rsrp_db[7]; + float rsrq_db[7]; + float rsrp_db_filtered[7]; + float rsrq_db_filtered[7]; #if defined(ENABLE_SECURITY) /* KeNB as computed from parameters within USIM card */ uint8_t kenb[32]; @@ -324,7 +365,7 @@ typedef struct{ //main.c int rrc_init_global_param(void); int L3_xface_init(void); -void openair_rrc_top_init(int eMBMS_active, u8 cba_group_active); +void openair_rrc_top_init(int eMBMS_active, u8 cba_group_active,u8 HO_enabled); char openair_rrc_lite_eNB_init(u8 Mod_id); char openair_rrc_lite_ue_init(u8 Mod_id,u8 CH_IDX); void rrc_config_buffer(SRB_INFO *srb_info, u8 Lchan_type, u8 Role); @@ -344,41 +385,41 @@ RRC_status_t rrc_rx_tx(u8 Mod_id,u32 frame, u8 eNB_flag,u8 index); /** \brief Decodes DL-CCCH message and invokes appropriate routine to handle the message \param Mod_id Instance ID of UE \param Srb_info Pointer to SRB_INFO structure (SRB0) - \param CH_index Index of corresponding eNB/CH*/ -int rrc_ue_decode_ccch(u8 Mod_id, u32 frame, SRB_INFO *Srb_info,u8 CH_index); + \param eNB_index Index of corresponding eNB/CH*/ +int rrc_ue_decode_ccch(u8 Mod_id, u32 frame, SRB_INFO *Srb_info,u8 eNB_index); /** \brief Decodes a DL-DCCH message and invokes appropriate routine to handle the message \param Mod_id Instance ID of UE \param frame Frame index \param Srb_id Index of Srb (1,2) \param Buffer Pointer to received SDU - \param CH_index Index of corresponding CH/eNB*/ -void rrc_ue_decode_dcch(u8 Mod_id, u32 frame, u8 Srb_id, u8* Buffer,u8 CH_index); + \param eNB_index Index of corresponding CH/eNB*/ +void rrc_ue_decode_dcch(u8 Mod_id, u32 frame, u8 Srb_id, u8* Buffer,u8 eNB_index); /** \brief Generate/Encodes RRCConnnectionRequest message at UE \param Mod_id Instance ID of UE \param frame Frame index \param Srb_id Index of Srb (1,2) - \param CH_index Index of corresponding eNB/CH*/ -void rrc_ue_generate_RRCConnectionRequest(u8 Mod_id, u32 frame, u8 CH_index); + \param eNB_index Index of corresponding eNB/CH*/ +void rrc_ue_generate_RRCConnectionRequest(u8 Mod_id, u32 frame, u8 eNB_index); /** \brief Generates/Encodes RRCConnnectionSetupComplete message at UE \param Mod_id Instance ID of UE \param frame Frame index - \param CH_index Index of corresponding eNB/CH*/ -void rrc_ue_generate_RRCConnectionSetupComplete(u8 Mod_id,u32 frame,u8 CH_index);\ + \param eNB_index Index of corresponding eNB/CH*/ +void rrc_ue_generate_RRCConnectionSetupComplete(u8 Mod_id,u32 frame,u8 eNB_index); /** \brief process the received rrcConnectionReconfiguration message at UE \param Mod_id Instance ID of UE \param frame Frame index \param *rrcConnectionReconfiguration pointer to the sturcture - \param CH_index Index of corresponding eNB/CH*/ + \param eNB_index Index of corresponding eNB/CH*/ void rrc_ue_process_rrcConnectionReconfiguration(u8 Mod_id, u32 frame,RRCConnectionReconfiguration_t *rrcConnectionReconfiguration,u8 eNB_index); /** \brief Generates/Encodes RRCConnectionReconfigurationComplete message at UE \param Mod_id Instance ID of UE \param frame Frame index - \param CH_index Index of corresponding eNB/CH*/ + \param eNB_index Index of corresponding eNB/CH*/ void rrc_ue_generate_RRCConnectionReconfigurationComplete(u8 Mod_id, u32 frame, u8 eNB_index); /** \brief Establish SRB1 based on configuration in SRB_ToAddMod structure. Configures RLC/PDCP accordingly @@ -399,22 +440,33 @@ s32 rrc_ue_establish_srb2(u8 Mod_id,u32 frame, u8 eNB_index,struct SRB_ToAddMod /** \brief Establish a DRB according to DRB_ToAddMod structure \param Mod_id Instance ID of UE - \param CH_index Index of corresponding CH/eNB + \param eNB_index Index of corresponding CH/eNB \param DRB_config Pointer to DRB_ToAddMod IE from configuration @returns 0 on success */ -s32 rrc_ue_establish_drb(u8 Mod_id,u32 frame,u8 CH_index,struct DRB_ToAddMod *DRB_config); +s32 rrc_ue_establish_drb(u8 Mod_id,u32 frame,u8 eNB_index,struct DRB_ToAddMod *DRB_config); + + +/** \brief Process MobilityControlInfo Message to proceed with handover and configure PHY/MAC + \param Mod_id Instance of UE on which to act + \param frame frame time interval + \param eNB_index Index of corresponding CH/eNB + \param mobilityControlInfo Pointer to mobilityControlInfo +*/ + +void rrc_ue_process_mobilityControlInfo(u8 Mod_id,u32 frame, u8 eNB_index,struct MobilityControlInfo *mobilityControlInfo); /** \brief Process a measConfig Message and configure PHY/MAC \param Mod_id Instance of UE on which to act - \param CH_index Index of corresponding CH/eNB + \param frame frame time interval + \param eNB_index Index of corresponding CH/eNB \param measConfig Pointer to MeasConfig IE from configuration*/ -void rrc_ue_process_measConfig(u8 Mod_id,u8 eNB_index,MeasConfig_t *measConfig); +void rrc_ue_process_measConfig(u8 Mod_id,u32 frame, u8 eNB_index,MeasConfig_t *measConfig); /** \brief Process a RadioResourceConfigDedicated Message and configure PHY/MAC \param Mod_id Instance of UE on which to act - \param CH_index Index of corresponding CH/eNB + \param eNB_index Index of corresponding CH/eNB \param radioResourceConfigDedicated Pointer to RadioResourceConfigDedicated IE from configuration*/ -void rrc_ue_process_radioResourceConfigDedicated(u8 Mod_id,u32 frame, u8 CH_index, +void rrc_ue_process_radioResourceConfigDedicated(u8 Mod_id,u32 frame, u8 eNB_index, RadioResourceConfigDedicated_t *radioResourceConfigDedicated); // eNB/CH RRC Procedures @@ -457,7 +509,7 @@ void rrc_eNB_process_RRCConnectionReconfigurationComplete(u8 Mod_id,u32 frame,u8 \param Mod_id Instance ID for eNB/CH \param frame Frame index \param UE_index Index of UE transmitting the messages*/ -void rrc_eNB_generate_defaultRRCConnectionReconfiguration(u8 Mod_id, u32 frame, u16 UE_index, u8 *nas_pdu, u32 nas_length); +void rrc_eNB_generate_defaultRRCConnectionReconfiguration(u8 Mod_id, u32 frame, u16 UE_index, u8 *nas_pdu, u32 nas_length, u8 ho_state); #if defined(ENABLE_ITTI) /**\brief RRC eNB task. @@ -469,6 +521,13 @@ void *rrc_enb_task(void *args_p); void *rrc_ue_task(void *args_p); #endif +/**\brief Generate/decode the handover RRCConnectionReconfiguration at eNB + \param Mod_id Instance ID for eNB/CH + \param frame Frame index + \param UE_index Index of UE transmitting the messages*/ +void rrc_eNB_generate_RRCConnectionReconfiguration_handover(u8 Mod_id, u32 frame, u16 UE_index, u8 *nas_pdu, u32 nas_length); + + //L2_interface.c s8 mac_rrc_lite_data_req( u8 Mod_id, u32 frame, unsigned short Srb_id, u8 Nb_tb, u8 *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, u8 *Sdu, unsigned short Sdu_len,u8 eNB_flag,u8 eNB_index, u8 mbsfn_sync_area); @@ -484,23 +543,28 @@ void decode_MBSFNAreaConfiguration(u8 Mod_id, u8 eNB_index, u32 frame,u8 mbsfn_s int decode_BCCH_DLSCH_Message(u8 Mod_id,u32 frame,u8 eNB_index,u8 *Sdu,u8 Sdu_len); - int decode_SIB1(u8 Mod_id,u8 CH_index); + int decode_SIB1(u8 Mod_id,u8 eNB_index); -int decode_SI(u8 Mod_id,u32 frame,u8 CH_index,u8 si_window); +int decode_SI(u8 Mod_id,u32 frame,u8 eNB_index,u8 si_window); int mac_get_rrc_lite_status(u8 Mod_id,u8 eNB_flag,u8 index); void rrc_eNB_generate_UECapabilityEnquiry(u8 Mod_id, u32 frame, u16 UE_index); void rrc_eNB_generate_SecurityModeCommand(u8 Mod_id, u32 frame, u16 UE_index); -void rrc_eNB_process_MeasurementReport(u8 Mod_id,u16 UE_index,MeasResults_t *measResults2) ; - +void rrc_eNB_process_MeasurementReport(u8 Mod_id,u32 frame, u16 UE_index,MeasResults_t *measResults2) ; +void rrc_eNB_generate_HandoverPreparationInformation (u8 Mod_id, u32 frame, u8 UE_index, PhysCellId_t targetPhyId) ; +u8 check_trigger_meas_event(u8 Mod_id,u32 frame, u8 eNB_index, u8 ue_cnx_index, u8 meas_index, + Q_OffsetRange_t ofn, Q_OffsetRange_t ocn, Hysteresis_t hys, + Q_OffsetRange_t ofs, Q_OffsetRange_t ocs, long a3_offset, TimeToTrigger_t ttt); //void rrc_ue_process_ueCapabilityEnquiry(uint8_t Mod_id,uint32_t frame,UECapabilityEnquiry_t *UECapabilityEnquiry,uint8_t eNB_index); //void rrc_ue_process_securityModeCommand(uint8_t Mod_id,uint32_t frame,SecurityModeCommand_t *securityModeCommand,uint8_t eNB_index); void rrc_remove_UE (u8 Mod_id, u8 UE_id); +long binary_search_int(int elements[], long numElem, int value); +long binary_search_float(float elements[], long numElem, float value); #endif diff --git a/openair2/RRC/LITE/extern.h b/openair2/RRC/LITE/extern.h index 541cffb2494a0239145c205d4a2a056232383a9b..3330f85b8fd675f652ab4fbe13c8207ace510fb6 100644 --- a/openair2/RRC/LITE/extern.h +++ b/openair2/RRC/LITE/extern.h @@ -1,9 +1,40 @@ -/*________________________openair_rrc_extern.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 vars.hles +* \brief rrc variab +* \author Raymond Knopp and Navid Nikaein +* \date 2011 +* \version 1.0 +* \company Eurecom +* \email: navid.nikaein@eurecom.fr +*/ #ifndef __OPENAIR_RRC_EXTERN_H__ #define __OPENAIR_RRC_EXTERN_H__ @@ -63,6 +94,16 @@ extern u16 RACH_FREQ_ALLOC; extern LCHAN_DESC BCCH_LCHAN_DESC,CCCH_LCHAN_DESC,DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC; extern MAC_MEAS_T BCCH_MEAS_TRIGGER,CCCH_MEAS_TRIGGER,DCCH_MEAS_TRIGGER,DTCH_MEAS_TRIGGER; extern MAC_AVG_T BCCH_MEAS_AVG,CCCH_MEAS_AVG,DCCH_MEAS_AVG, DTCH_MEAS_AVG; + +extern u16 T300[8]; +extern u16 T310[8]; +extern u16 N310[8]; +extern u16 N311[8]; +extern u32 T304[8]; +extern u32 timeToTrigger_ms[16]; +extern float RSRP_meas_mapping[100]; +extern float RSRQ_meas_mapping[33]; + #endif diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c index 7275c8a29012e0023ca40df90c99f4bcbb6454ed..558599e525d66a1dbedb170c31565d9eb4ed78ba 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LITE/rrc_UE.c @@ -93,6 +93,7 @@ extern void *bigphys_malloc(int); //#define XER_PRINT extern inline unsigned int taus(void); +extern s8 dB_fixed2(u32 x,u32 y); void init_SI_UE(u8 Mod_id,u8 eNB_index) { @@ -163,6 +164,7 @@ char openair_rrc_lite_ue_init(u8 Mod_id, unsigned char eNB_index){ UE_rrc_inst[Mod_id].Srb0[eNB_index].Active=0; UE_rrc_inst[Mod_id].Srb1[eNB_index].Active=0; UE_rrc_inst[Mod_id].Srb2[eNB_index].Active=0; + UE_rrc_inst[Mod_id].HandoverInfoUe.measFlag=1; UE_rrc_inst[Mod_id].ciphering_algorithm = SecurityAlgorithmConfig__cipheringAlgorithm_eea0; #ifdef Rel10 @@ -272,21 +274,6 @@ void rrc_ue_generate_RRCConnectionReconfigurationComplete(u8 Mod_id, u32 frame, pdcp_rrc_data_req (Mod_id + NB_eNB_INST, frame, 0, DCCH, rrc_mui++, 0, size, buffer, 1); } - -void rrc_ue_generate_MeasurementReport(u8 Mod_id, u32 frame, u8 eNB_index) { - - u8 buffer[32], size; - - LOG_D(RRC,"[UE %d] Frame %d : Generating Measurement Report\n",Mod_id,Mac_rlc_xface->frame); - - size = do_MeasurementReport(buffer,1,0,3,4,5,6); - - LOG_D(RLC, "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCConnectionReconfigurationComplete to eNB %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n", - Mac_rlc_xface->frame, Mod_id+NB_eNB_INST, size, eNB_index, rrc_mui, Mod_id+NB_eNB_INST, DCCH); - //rrc_rlc_data_req(Mod_id+NB_eNB_INST,DCCH,rrc_mui++,0,size,(char*)buffer); - pdcp_rrc_data_req (Mod_id + NB_eNB_INST, frame, 0, DCCH, rrc_mui++, 0, size, buffer, 1); -} - /*------------------------------------------------------------------------------*/ int rrc_ue_decode_ccch(u8 Mod_id, u32 frame, SRB_INFO *Srb_info, u8 eNB_index){ /*------------------------------------------------------------------------------*/ @@ -487,7 +474,7 @@ s32 rrc_ue_establish_drb(u8 Mod_id,u32 frame,u8 eNB_index, } -void rrc_ue_process_measConfig(u8 Mod_id,u8 eNB_index,MeasConfig_t *measConfig){ +void rrc_ue_process_measConfig(u8 Mod_id,u32 frame, u8 eNB_index,MeasConfig_t *measConfig){ // This is the procedure described in 36.331 Section 5.5.2.1 int i; @@ -497,7 +484,7 @@ void rrc_ue_process_measConfig(u8 Mod_id,u8 eNB_index,MeasConfig_t *measConfig) if (measConfig->measObjectToRemoveList != NULL) { for (i=0;i<measConfig->measObjectToRemoveList->list.count;i++) { ind = *measConfig->measObjectToRemoveList->list.array[i]; - free(UE_rrc_inst[Mod_id].MeasObj[eNB_index][ind]); + free(UE_rrc_inst[Mod_id].MeasObj[eNB_index][ind-1]); } } if (measConfig->measObjectToAddModList != NULL) { @@ -508,7 +495,7 @@ void rrc_ue_process_measConfig(u8 Mod_id,u8 eNB_index,MeasConfig_t *measConfig) if (UE_rrc_inst[Mod_id].MeasObj[eNB_index][ind-1]) { LOG_D(RRC,"Modifying measurement object %d\n",ind); - memcpy((char*)UE_rrc_inst[Mod_id].MeasObj[eNB_index][ind], + memcpy((char*)UE_rrc_inst[Mod_id].MeasObj[eNB_index][ind-1], (char*)measObj, sizeof(MeasObjectToAddMod_t)); } @@ -535,6 +522,7 @@ void rrc_ue_process_measConfig(u8 Mod_id,u8 eNB_index,MeasConfig_t *measConfig) (struct LogicalChannelConfig *)NULL, (MeasGapConfig_t *)NULL, (TDD_Config_t *)NULL, + (MobilityControlInfo_t *)NULL, NULL, NULL, NULL, @@ -557,22 +545,22 @@ void rrc_ue_process_measConfig(u8 Mod_id,u8 eNB_index,MeasConfig_t *measConfig) if (measConfig->reportConfigToRemoveList != NULL) { for (i=0;i<measConfig->reportConfigToRemoveList->list.count;i++) { ind = *measConfig->reportConfigToRemoveList->list.array[i]; - free(UE_rrc_inst[Mod_id].ReportConfig[eNB_index][ind]); + free(UE_rrc_inst[Mod_id].ReportConfig[eNB_index][ind-1]); } } if (measConfig->reportConfigToAddModList != NULL) { LOG_I(RRC,"Report Configuration List is present\n"); for (i=0;i<measConfig->reportConfigToAddModList->list.count;i++) { ind = measConfig->reportConfigToAddModList->list.array[i]->reportConfigId; - if (UE_rrc_inst[Mod_id].ReportConfig[eNB_index][ind]) { - LOG_I(RRC,"Modifying Report Configuration %d\n",ind); + if (UE_rrc_inst[Mod_id].ReportConfig[eNB_index][ind-1]) { + LOG_I(RRC,"Modifying Report Configuration %d\n",ind-1); memcpy((char*)UE_rrc_inst[Mod_id].ReportConfig[eNB_index][ind-1], (char*)measConfig->reportConfigToAddModList->list.array[i], sizeof(ReportConfigToAddMod_t)); } else { - LOG_D(RRC,"Adding Report Configuration %d\n",ind); - UE_rrc_inst[Mod_id].ReportConfig[eNB_index][ind] = measConfig->reportConfigToAddModList->list.array[i]; + LOG_D(RRC,"Adding Report Configuration %d %p \n",ind-1,measConfig->reportConfigToAddModList->list.array[i]); + UE_rrc_inst[Mod_id].ReportConfig[eNB_index][ind-1] = measConfig->reportConfigToAddModList->list.array[i]; } } } @@ -580,7 +568,8 @@ void rrc_ue_process_measConfig(u8 Mod_id,u8 eNB_index,MeasConfig_t *measConfig) if (measConfig->quantityConfig != NULL) { if (UE_rrc_inst[Mod_id].QuantityConfig[eNB_index]) { LOG_D(RRC,"Modifying Quantity Configuration \n"); - memcpy((char*)UE_rrc_inst[Mod_id].QuantityConfig[eNB_index],(char*)measConfig->quantityConfig, + memcpy((char*)UE_rrc_inst[Mod_id].QuantityConfig[eNB_index], + (char*)measConfig->quantityConfig, sizeof(QuantityConfig_t)); } else { @@ -592,29 +581,30 @@ void rrc_ue_process_measConfig(u8 Mod_id,u8 eNB_index,MeasConfig_t *measConfig) if (measConfig->measIdToRemoveList != NULL) { for (i=0;i<measConfig->measIdToRemoveList->list.count;i++) { ind = *measConfig->measIdToRemoveList->list.array[i]; - free(UE_rrc_inst[Mod_id].MeasId[eNB_index][ind]); + free(UE_rrc_inst[Mod_id].MeasId[eNB_index][ind-1]); } } if (measConfig->measIdToAddModList != NULL) { for (i=0;i<measConfig->measIdToAddModList->list.count;i++) { ind = measConfig->measIdToAddModList->list.array[i]->measId; - if (UE_rrc_inst[Mod_id].MeasId[eNB_index][ind]) { - LOG_D(RRC,"Modifying Measurement ID %d\n",ind); + if (UE_rrc_inst[Mod_id].MeasId[eNB_index][ind-1]) { + LOG_D(RRC,"Modifying Measurement ID %d\n",ind-1); memcpy((char*)UE_rrc_inst[Mod_id].MeasId[eNB_index][ind-1], (char*)measConfig->measIdToAddModList->list.array[i], sizeof(MeasIdToAddMod_t)); } else { - LOG_D(RRC,"Adding Measurement ID %d\n",ind); - UE_rrc_inst[Mod_id].MeasId[eNB_index][ind] = measConfig->measIdToAddModList->list.array[i]; + LOG_D(RRC,"Adding Measurement ID %d %p\n",ind-1,measConfig->measIdToAddModList->list.array[i]); + UE_rrc_inst[Mod_id].MeasId[eNB_index][ind-1] = measConfig->measIdToAddModList->list.array[i]; } } } if (measConfig->measGapConfig !=NULL) { if (UE_rrc_inst[Mod_id].measGapConfig[eNB_index]) { - memcpy((char*)UE_rrc_inst[Mod_id].measGapConfig[eNB_index],(char*)measConfig->measGapConfig, + memcpy((char*)UE_rrc_inst[Mod_id].measGapConfig[eNB_index], + (char*)measConfig->measGapConfig, sizeof(MeasGapConfig_t)); } else { @@ -622,15 +612,47 @@ void rrc_ue_process_measConfig(u8 Mod_id,u8 eNB_index,MeasConfig_t *measConfig) } } + if (measConfig->quantityConfig != NULL) { + if (UE_rrc_inst[Mod_id].QuantityConfig[eNB_index]) { + LOG_I(RRC,"Modifying Quantity Configuration \n"); + memcpy((char*)UE_rrc_inst[Mod_id].QuantityConfig[eNB_index], + (char*)measConfig->quantityConfig, + sizeof(QuantityConfig_t)); + } + else { + LOG_I(RRC,"Adding Quantity configuration\n"); + UE_rrc_inst[Mod_id].QuantityConfig[eNB_index] = measConfig->quantityConfig; + } + + UE_rrc_inst[Mod_id].filter_coeff_rsrp = 1./pow(2,(*UE_rrc_inst[Mod_id].QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRP)/4); + UE_rrc_inst[Mod_id].filter_coeff_rsrq = 1./pow(2,(*UE_rrc_inst[Mod_id].QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRQ)/4); + + LOG_I(RRC,"[UE %d] set rsrp-coeff for eNB %d: %d rsrq-coeff: %d rsrp_factor: %f rsrq_factor: %f \n", + Mod_id, eNB_index, // UE_rrc_inst[Mod_id].Info[eNB_index].UE_index, + *UE_rrc_inst[Mod_id].QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRP, + *UE_rrc_inst[Mod_id].QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRQ, + UE_rrc_inst[Mod_id].filter_coeff_rsrp, UE_rrc_inst[Mod_id].filter_coeff_rsrp, + UE_rrc_inst[Mod_id].filter_coeff_rsrp, UE_rrc_inst[Mod_id].filter_coeff_rsrq); + } + if (measConfig->s_Measure != NULL) { UE_rrc_inst[Mod_id].s_measure = *measConfig->s_Measure; } - + + if (measConfig->speedStatePars != NULL) { + if (UE_rrc_inst[Mod_id].speedStatePars) + memcpy((char*)UE_rrc_inst[Mod_id].speedStatePars,(char*)measConfig->speedStatePars,sizeof(struct MeasConfig__speedStatePars)); + else + UE_rrc_inst[Mod_id].speedStatePars = measConfig->speedStatePars; + LOG_I(RRC,"[UE %d] Configuring mobility optimization params for UE %d \n", + Mod_id,UE_rrc_inst[Mod_id].Info[0].UE_index); + } } -void rrc_ue_process_radioResourceConfigDedicated(u8 Mod_id,u32 frame, u8 eNB_index, - RadioResourceConfigDedicated_t *radioResourceConfigDedicated) { +void +rrc_ue_process_radioResourceConfigDedicated(u8 Mod_id,u32 frame, u8 eNB_index, + RadioResourceConfigDedicated_t *radioResourceConfigDedicated) { long SRB_id,DRB_id; int i,cnt; @@ -721,7 +743,7 @@ void rrc_ue_process_radioResourceConfigDedicated(u8 Mod_id,u32 frame, u8 eNB_ind ); // Refresh SRBs - rrc_rlc_config_asn1_req(NB_eNB_INST+Mod_id,frame,0,0, + rrc_rlc_config_asn1_req(NB_eNB_INST+Mod_id,frame,0,eNB_index, radioResourceConfigDedicated->srb_ToAddModList, (DRB_ToAddModList_t*)NULL, (DRB_ToReleaseList_t*)NULL @@ -772,6 +794,7 @@ void rrc_ue_process_radioResourceConfigDedicated(u8 Mod_id,u32 frame, u8 eNB_ind NULL, NULL, NULL, + NULL, NULL #ifdef Rel10 , @@ -822,8 +845,9 @@ void rrc_ue_process_radioResourceConfigDedicated(u8 Mod_id,u32 frame, u8 eNB_ind SRB2_logicalChannelConfig, UE_rrc_inst[Mod_id].measGapConfig[eNB_index], (TDD_Config_t *)NULL, - (u8 *)NULL, - (u16 *)NULL, + (MobilityControlInfo_t *)NULL, + NULL, + NULL, NULL, NULL, NULL, @@ -870,7 +894,7 @@ void rrc_ue_process_radioResourceConfigDedicated(u8 Mod_id,u32 frame, u8 eNB_ind ); // Refresh DRBs - rrc_rlc_config_asn1_req(NB_eNB_INST+Mod_id,frame,0,0, + rrc_rlc_config_asn1_req(NB_eNB_INST+Mod_id,frame,0,eNB_index, (SRB_ToAddModList_t*)NULL, radioResourceConfigDedicated->drb_ToAddModList, (DRB_ToReleaseList_t*)NULL @@ -900,12 +924,13 @@ void rrc_ue_process_radioResourceConfigDedicated(u8 Mod_id,u32 frame, u8 eNB_ind UE_rrc_inst[Mod_id].DRB_config[eNB_index][DRB_id]->logicalChannelConfig, UE_rrc_inst[Mod_id].measGapConfig[eNB_index], (TDD_Config_t*)NULL, - (u8 *)NULL, - (u16 *)NULL, + (MobilityControlInfo_t *)NULL, + NULL, NULL, NULL, NULL, - (MBSFN_SubframeConfigList_t*)NULL + NULL, + NULL #ifdef Rel10 , 0, @@ -1072,7 +1097,7 @@ void rrc_ue_process_ueCapabilityEnquiry(uint8_t Mod_id,uint32_t frame,UECapabili #ifdef USER_MODE LOG_D(RRC,"UECapabilityInformation Encoded %d bits (%d bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); -#endif +#endif for (i = 0; i < (enc_rval.encoded + 7) / 8; i++) LOG_T(RRC, "%02x.", buffer[i]); LOG_T(RRC, "\n"); @@ -1083,10 +1108,6 @@ void rrc_ue_process_ueCapabilityEnquiry(uint8_t Mod_id,uint32_t frame,UECapabili } } -void rrc_ue_process_mobilityControlInfo(u8 Mod_id,u8 eNB_index,struct MobilityControlInfo *mobilityControlInfo) { - - -} void rrc_ue_process_rrcConnectionReconfiguration(u8 Mod_id, u32 frame, RRCConnectionReconfiguration_t *rrcConnectionReconfiguration, @@ -1099,13 +1120,13 @@ void rrc_ue_process_rrcConnectionReconfiguration(u8 Mod_id, u32 frame, if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo) { LOG_I(RRC,"Mobility Control Information is present\n"); - rrc_ue_process_mobilityControlInfo(Mod_id,eNB_index, + rrc_ue_process_mobilityControlInfo(Mod_id,frame, eNB_index, rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo); } if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig != NULL) { LOG_I(RRC,"Measurement Configuration is present\n"); - rrc_ue_process_measConfig(Mod_id,eNB_index, + rrc_ue_process_measConfig(Mod_id,frame, eNB_index, rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig); } if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated) { @@ -1117,6 +1138,125 @@ void rrc_ue_process_rrcConnectionReconfiguration(u8 Mod_id, u32 frame, } // critical extensions present } +/* 36.331, 5.3.5.4 Reception of an RRCConnectionReconfiguration including the mobilityControlInfo by the UE (handover) */ +void rrc_ue_process_mobilityControlInfo(u8 Mod_id,u32 frame, u8 eNB_index,struct MobilityControlInfo *mobilityControlInfo) { + + DRB_ToReleaseList_t* drb2release_list; + DRB_Identity_t *lcid; + u8 i; + LOG_N(RRC,"Note: This function needs some updates\n"); + if(UE_rrc_inst[Mod_id].Info[eNB_index].T310_active == 1) + UE_rrc_inst[Mod_id].Info[eNB_index].T310_active = 0; + UE_rrc_inst[Mod_id].Info[eNB_index].T304_active = 1; + UE_rrc_inst[Mod_id].Info[eNB_index].T304_cnt = T304[mobilityControlInfo->t304]; + + drb2release_list = CALLOC (1, sizeof (*drb2release_list)); + lcid= CALLOC (1, sizeof (DRB_Identity_t)); // long + for (*lcid=0;*lcid<NB_RB_MAX;*lcid++) + ASN_SEQUENCE_ADD (&(drb2release_list)->list,lcid); + + //Removing SRB1 and SRB2 and DRB0 + LOG_N(RRC,"[UE %d] : Update needed for rrc_pdcp_config_req (deprecated) and rrc_rlc_config_req commands(deprecated)\n",Mod_id); + rrc_pdcp_config_req (Mod_id+NB_eNB_INST, frame, 0, ACTION_REMOVE, Mod_id+DCCH,UNDEF_SECURITY_MODE); + rrc_rlc_config_req(Mod_id+NB_eNB_INST,frame,0,ACTION_REMOVE,Mod_id+DCCH,SIGNALLING_RADIO_BEARER,Rlc_info_am_config); + + rrc_pdcp_config_req (Mod_id+NB_eNB_INST, frame, 0, ACTION_REMOVE, Mod_id+DCCH1,UNDEF_SECURITY_MODE); + rrc_rlc_config_req(Mod_id+NB_eNB_INST,frame,0,ACTION_REMOVE,Mod_id+DCCH1,SIGNALLING_RADIO_BEARER,Rlc_info_am_config); + + rrc_pdcp_config_req (Mod_id+NB_eNB_INST, frame, 0, ACTION_REMOVE, Mod_id+DTCH,UNDEF_SECURITY_MODE); + rrc_rlc_config_req(Mod_id+NB_eNB_INST,frame,0,ACTION_REMOVE,Mod_id+DTCH,RADIO_ACCESS_BEARER,Rlc_info_um); + /* + rrc_pdcp_config_asn1_req(NB_eNB_INST+Mod_id,frame, 0,eNB_index, + NULL, // SRB_ToAddModList + NULL, // DRB_ToAddModList + drb2release_list, + 0, // security mode + NULL, // key rrc encryption + NULL, // key rrc integrity + NULL // key encryption +#ifdef Rel10 + ,NULL +#endif + ); + + rrc_rlc_config_asn1_req(NB_eNB_INST+Mod_id, frame,0,eNB_index, + NULL,// SRB_ToAddModList + NULL,// DRB_ToAddModList + drb2release_list // DRB_ToReleaseList +#ifdef Rel10 + ,NULL +#endif + ); + */ + + + //A little cleanup at RRC... + //Copying current queue config to free RRC index + /* + memcpy((void *)UE_rrc_inst[Mod_id].SRB1_config[~(7<<eNB_index)],(void *)UE_rrc_inst[Mod_id].SRB1_config[7<<eNB_index],sizeof(SRB_ToAddMod_t)); + memcpy((void *)UE_rrc_inst[Mod_id].SRB2_config[~(7<<eNB_index)],(void *)UE_rrc_inst[Mod_id].SRB2_config[7<<eNB_index],sizeof(SRB_ToAddMod_t)); + memcpy((void *)UE_rrc_inst[Mod_id].DRB_config[~(7<<eNB_index)][0],(void *)UE_rrc_inst[Mod_id].DRB_config[7<<eNB_index][0],sizeof(DRB_ToAddMod_t)); + */ + /* + LOG_N(RRC,"Not sure if Freeing the current queue config works properly: Fix me\n"); + free((void *)&UE_rrc_inst[Mod_id].SRB1_config[eNB_index]); + free((void *)&UE_rrc_inst[Mod_id].SRB2_config[eNB_index]); + free((void *)&UE_rrc_inst[Mod_id].DRB_config[eNB_index][0]); + + UE_rrc_inst[Mod_id].SRB1_config[eNB_index] = NULL; + UE_rrc_inst[Mod_id].SRB2_config[eNB_index] = NULL; + UE_rrc_inst[Mod_id].DRB_config[eNB_index][0] = NULL; + */ + //Synchronisation to DL of target cell + LOG_D(RRC,"HO: Reset PDCP and RLC for configured RBs.. \n[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB2 eNB %d) --->][MAC_UE][MOD %02d][]\n", + frame, Mod_id, eNB_index, Mod_id); + + // Reset MAC and configure PHY + rrc_mac_config_req(Mod_id,0,0,eNB_index, + (RadioResourceConfigCommonSIB_t *)NULL, + (struct PhysicalConfigDedicated *)NULL, + (MeasObjectToAddMod_t **)NULL, + (MAC_MainConfig_t *)NULL, + 0, + (struct LogicalChannelConfig *)NULL, + (MeasGapConfig_t *)NULL, + (TDD_Config_t *)NULL, + mobilityControlInfo, + (u8 *)NULL, + (u16 *)NULL, + NULL, + NULL, + NULL, + NULL +#ifdef Rel10 + ,0, + (MBSFN_AreaInfoList_r9_t *)NULL, + (PMCH_InfoList_r9_t *)NULL +#endif +#ifdef CBA + ,0, + 0 +#endif + ); + + // Re-establish PDCP for all RBs that are established + // rrc_pdcp_config_req (Mod_id+NB_eNB_INST, frame, 0, ACTION_ADD, Mod_id+DCCH); + // rrc_pdcp_config_req (Mod_id+NB_eNB_INST, frame, 0, ACTION_ADD, Mod_id+DCCH1); + // rrc_pdcp_config_req (Mod_id+NB_eNB_INST, frame, 0, ACTION_ADD, Mod_id+DTCH); + + + // Re-establish RLC for all RBs that are established + // rrc_rlc_config_req(Mod_id+NB_eNB_INST,frame,0,ACTION_ADD,Mod_id+DCCH,SIGNALLING_RADIO_BEARER,Rlc_info_am_config); + // rrc_rlc_config_req(Mod_id+NB_eNB_INST,frame,0,ACTION_ADD,Mod_id+DCCH1,SIGNALLING_RADIO_BEARER,Rlc_info_am_config); + // rrc_rlc_config_req(Mod_id+NB_eNB_INST,frame,0,ACTION_ADD,Mod_id+DTCH,RADIO_ACCESS_BEARER,Rlc_info_um); + + UE_rrc_inst[Mod_id].Info[eNB_index].State = RRC_SI_RECEIVED; + +} +void rrc_detach_from_eNB(u8 Mod_id,u8 eNB_index) { + //UE_rrc_inst[Mod_id].DRB_config[eNB_index] +} + /*------------------------------------------------------------------------------------------*/ void rrc_ue_decode_dcch(u8 Mod_id,u32 frame,u8 Srb_id, u8 *Buffer,u8 eNB_index){ /*------------------------------------------------------------------------------------------*/ @@ -1125,7 +1265,7 @@ void rrc_ue_decode_dcch(u8 Mod_id,u32 frame,u8 Srb_id, u8 *Buffer,u8 eNB_index) DL_DCCH_Message_t *dl_dcch_msg=NULL;//&dldcchmsg; // asn_dec_rval_t dec_rval; // int i; - + u8 target_eNB_index=0xFF; if (Srb_id != 1) { LOG_E(RRC,"[UE %d] Frame %d: Received message on DL-DCCH (SRB1), should not have ...\n",Mod_id,frame); return; @@ -1144,7 +1284,7 @@ void rrc_ue_decode_dcch(u8 Mod_id,u32 frame,u8 Srb_id, u8 *Buffer,u8 eNB_index) &asn_DEF_DL_DCCH_Message, (void**)&dl_dcch_msg, (uint8_t*)Buffer, - 100,0,0); + RRC_BUF_SIZE,0,0); #ifdef XER_PRINT xer_fprint(stdout,&asn_DEF_DL_DCCH_Message,(void*)dl_dcch_msg); @@ -1152,7 +1292,7 @@ void rrc_ue_decode_dcch(u8 Mod_id,u32 frame,u8 Srb_id, u8 *Buffer,u8 eNB_index) if (dl_dcch_msg->message.present == DL_DCCH_MessageType_PR_c1) { - if (UE_rrc_inst[Mod_id].Info[eNB_index].State == RRC_CONNECTED) { + if (UE_rrc_inst[Mod_id].Info[eNB_index].State >= RRC_CONNECTED) { switch (dl_dcch_msg->message.choice.c1.present) { @@ -1169,10 +1309,32 @@ void rrc_ue_decode_dcch(u8 Mod_id,u32 frame,u8 Srb_id, u8 *Buffer,u8 eNB_index) case DL_DCCH_MessageType__c1_PR_mobilityFromEUTRACommand: break; case DL_DCCH_MessageType__c1_PR_rrcConnectionReconfiguration: + // first check if mobilityControlInfo is present + if(dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo != NULL) { + /* 36.331, 5.3.5.4 Reception of an RRCConnectionReconfiguration including the mobilityControlInfo by the UE (handover)*/ + if(UE_rrc_inst[Mod_id].HandoverInfoUe.targetCellId != dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo->targetPhysCellId) { + LOG_W(RRC,"[UE %d] Frame %d: Handover target (%d) is different from RSRP measured target (%d)..\n",Mod_id, frame, + dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo->targetPhysCellId,UE_rrc_inst[Mod_id].HandoverInfoUe.targetCellId); + return; + } else if ((target_eNB_index=get_adjacent_cell_mod_id(UE_rrc_inst[Mod_id].HandoverInfoUe.targetCellId)) == 0xFF ){ + LOG_W(RRC,"[UE %d] Frame %d: Mod_id of the target eNB not found, check the network topology\n",Mod_id, frame); + return; + } else { + LOG_I(RRC,"[UE% d] Frame %d: Received rrcConnectionReconfiguration with mobilityControlInfo \n", Mod_id, frame); + UE_rrc_inst[Mod_id].HandoverInfoUe.measFlag = 1; // Ready to send more MeasReports if required + } + } rrc_ue_process_rrcConnectionReconfiguration(Mod_id,frame,&dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration,eNB_index); - rrc_ue_generate_RRCConnectionReconfigurationComplete(Mod_id,frame,eNB_index); - UE_rrc_inst[Mod_id].Info[eNB_index].State = RRC_RECONFIGURED; - LOG_I(RRC,"[UE %d] State = RRC_RECONFIGURED (eNB %d)\n",Mod_id,eNB_index); + if (target_eNB_index!=0xFF){ + rrc_ue_generate_RRCConnectionReconfigurationComplete(Mod_id,frame,target_eNB_index); + UE_rrc_inst[Mod_id].Info[eNB_index].State = RRC_HO_EXECUTION; + UE_rrc_inst[Mod_id].Info[target_eNB_index].State = RRC_RECONFIGURED; + LOG_I(RRC,"[UE %d] State = RRC_RECONFIGURED during HO (eNB %d)\n",Mod_id,target_eNB_index); + }else { + rrc_ue_generate_RRCConnectionReconfigurationComplete(Mod_id,frame,eNB_index); + UE_rrc_inst[Mod_id].Info[eNB_index].State = RRC_RECONFIGURED; + LOG_I(RRC,"[UE %d] State = RRC_RECONFIGURED (eNB %d)\n",Mod_id,eNB_index); + } break; case DL_DCCH_MessageType__c1_PR_rrcConnectionRelease: break; @@ -1355,7 +1517,8 @@ int decode_SIB1(u8 Mod_id,u8 eNB_index) { 0, (struct LogicalChannelConfig *)NULL, (MeasGapConfig_t *)NULL, - UE_rrc_inst[Mod_id].sib1[eNB_index]->tdd_Config, + UE_rrc_inst[Mod_id].sib1[eNB_index]->tdd_Config, + (MobilityControlInfo_t *) NULL, &UE_rrc_inst[Mod_id].Info[eNB_index].SIwindowsize, &UE_rrc_inst[Mod_id].Info[eNB_index].SIperiod, NULL, @@ -1363,8 +1526,7 @@ int decode_SIB1(u8 Mod_id,u8 eNB_index) { NULL, (MBSFN_SubframeConfigList_t *)NULL #ifdef Rel10 - , - 0, + ,0, (MBSFN_AreaInfoList_r9_t *)NULL, (PMCH_InfoList_r9_t *)NULL #endif @@ -1520,6 +1682,7 @@ int decode_SI(u8 Mod_id,u32 frame,u8 eNB_index,u8 si_window) { (struct LogicalChannelConfig *)NULL, (MeasGapConfig_t *)NULL, (TDD_Config_t *)NULL, + (MobilityControlInfo_t *)NULL, NULL, NULL, UE_rrc_inst[Mod_id].sib2[eNB_index]->freqInfo.ul_CarrierFreq, @@ -1527,14 +1690,12 @@ int decode_SI(u8 Mod_id,u32 frame,u8 eNB_index,u8 si_window) { &UE_rrc_inst[Mod_id].sib2[eNB_index]->freqInfo.additionalSpectrumEmission, UE_rrc_inst[Mod_id].sib2[eNB_index]->mbsfn_SubframeConfigList #ifdef Rel10 - , - 0, + ,0, (MBSFN_AreaInfoList_r9_t *)NULL, (PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA - , - 0, + ,0, 0 #endif ); @@ -1611,6 +1772,7 @@ int decode_SI(u8 Mod_id,u32 frame,u8 eNB_index,u8 si_window) { (struct LogicalChannelConfig *)NULL, (MeasGapConfig_t *)NULL, (TDD_Config_t *)NULL, + (MobilityControlInfo_t *)NULL, NULL, NULL, NULL, @@ -1618,14 +1780,12 @@ int decode_SI(u8 Mod_id,u32 frame,u8 eNB_index,u8 si_window) { NULL, (MBSFN_SubframeConfigList_t *)NULL #ifdef Rel10 - , - 0, + ,0, &UE_rrc_inst[Mod_id].sib13[eNB_index]->mbsfn_AreaInfoList_r9, (PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA - , - 0, + ,0, 0 #endif ); @@ -1642,6 +1802,248 @@ int decode_SI(u8 Mod_id,u32 frame,u8 eNB_index,u8 si_window) { return 0; } + +// layer 3 filtering of RSRP (EUTRA) measurements: 36.331, Sec. 5.5.3.2 +void ue_meas_filtering(u8 Mod_id,u32 frame,u8 eNB_index){ + float a = UE_rrc_inst[Mod_id].filter_coeff_rsrp; // 'a' in 36.331 Sec. 5.5.3.2 + float a1 = UE_rrc_inst[Mod_id].filter_coeff_rsrq; + //float rsrp_db, rsrq_db; + u8 eNB_offset; + + if(UE_rrc_inst[Mod_id].QuantityConfig[0] != NULL) { // Only consider 1 serving cell (index: 0) + if (UE_rrc_inst[Mod_id].QuantityConfig[0]->quantityConfigEUTRA != NULL) { + if(UE_rrc_inst[Mod_id].QuantityConfig[0]->quantityConfigEUTRA->filterCoefficientRSRP != NULL) { + for (eNB_offset = 0;eNB_offset<1+mac_xface->get_n_adj_cells(Mod_id);eNB_offset++) { + //filter_factor = 1/power(2,*UE_rrc_inst[Mod_id].QuantityConfig[0]->quantityConfigEUTRA->filterCoefficientRSRP/4); + // LOG_N(RRC,"[UE %d] Frame %d : check proper operation in abstraction mode rsrp (%d), rx gain (%d) N_RB_DL (%d)\n", + // Mod_id,frame,mac_xface->get_RSRP(Mod_id,eNB_offset),mac_xface->get_rx_total_gain_dB(Mod_id),mac_xface->lte_frame_parms->N_RB_DL); + UE_rrc_inst[Mod_id].rsrp_db[eNB_offset] = (dB_fixed_times10(mac_xface->get_RSRP(Mod_id,eNB_offset))/10.0)-mac_xface->get_rx_total_gain_dB(Mod_id)-dB_fixed(mac_xface->lte_frame_parms->N_RB_DL*12); + UE_rrc_inst[Mod_id].rsrp_db_filtered[eNB_offset] = (1.0-a)*UE_rrc_inst[Mod_id].rsrp_db_filtered[eNB_offset] + a*UE_rrc_inst[Mod_id].rsrp_db[eNB_offset]; + //mac_xface->set_RSRP_filtered(Mod_id,eNB_offset,UE_rrc_inst[Mod_id].rsrp_db_filtered[eNB_offset]); + + LOG_D(RRC,"[UE %d] Frame %d: Meas RSRP: eNB_offset: %d rsrp_coef: %3.2f filter_coef: %d before L3 filtering: rsrp: %3.1f after L3 filtering: rsrp: %3.1f \n ", + Mod_id, frame, eNB_offset,a, + *UE_rrc_inst->QuantityConfig[0]->quantityConfigEUTRA->filterCoefficientRSRP, + UE_rrc_inst[Mod_id].rsrp_db[eNB_offset], + UE_rrc_inst[Mod_id].rsrp_db_filtered[eNB_offset]); + } + } + } + else { + for (eNB_offset = 0;eNB_offset<1+mac_xface->get_n_adj_cells(Mod_id);eNB_offset++) { + UE_rrc_inst[Mod_id].rsrp_db_filtered[eNB_offset]= mac_xface->get_RSRP(Mod_id,eNB_offset); + // phy_vars_ue->PHY_measurements.rsrp_filtered[eNB_offset]=UE_rrc_inst[Mod_id].rsrp_db_filtered[eNB_offset]; + //mac_xface->set_RSRP_filtered(Mod_id,eNB_offset,UE_rrc_inst[Mod_id].rsrp_db_filtered[eNB_offset]); + } + } + if (UE_rrc_inst[Mod_id].QuantityConfig[0]->quantityConfigEUTRA != NULL) { + if(UE_rrc_inst[Mod_id].QuantityConfig[0]->quantityConfigEUTRA->filterCoefficientRSRQ != NULL) { + for (eNB_offset = 0;eNB_offset<1+mac_xface->get_n_adj_cells(Mod_id);eNB_offset++) { + // LOG_N(RRC,"[UE %d] Frame %d : check if this operation workes properly in abstraction mode\n",Mod_id,frame); + UE_rrc_inst[Mod_id].rsrq_db[eNB_offset] = (10*log10(mac_xface->get_RSRQ(Mod_id,eNB_offset)))-20; + UE_rrc_inst[Mod_id].rsrq_db_filtered[eNB_offset]=(1-a1)*UE_rrc_inst[Mod_id].rsrq_db_filtered[eNB_offset] + a1 *UE_rrc_inst[Mod_id].rsrq_db[eNB_offset]; + //mac_xface->set_RSRP_filtered(Mod_id,eNB_offset,UE_rrc_inst[Mod_id].rsrp_db_filtered[eNB_offset]); + /* + LOG_D(RRC,"[UE %d] meas RSRQ: eNB_offset: %d rsrq_coef: %3.2f filter_coef: %d before L3 filtering: rsrq: %3.1f after L3 filtering: rsrq: %3.1f \n ", + Mod_id, eNB_offset, + a1, + *UE_rrc_inst->QuantityConfig[0]->quantityConfigEUTRA->filterCoefficientRSRQ, + mac_xface->get_RSRQ(Mod_id,eNB_offset), + UE_rrc_inst[Mod_id].rsrq_db[eNB_offset], + UE_rrc_inst[Mod_id].rsrq_db_filtered[eNB_offset]); + */ + } + } + } + else{ + for (eNB_offset = 0;eNB_offset<1+mac_xface->get_n_adj_cells(Mod_id);eNB_offset++) { + UE_rrc_inst[Mod_id].rsrq_db_filtered[eNB_offset]= mac_xface->get_RSRQ(Mod_id,eNB_offset); + } + } + } +} + +// Measurement report triggering, described in 36.331 Section 5.5.4.1: called periodically +void ue_measurement_report_triggering(u8 Mod_id, u32 frame,u8 eNB_index) { + u8 i,j; + Hysteresis_t hys; + TimeToTrigger_t ttt_ms; + Q_OffsetRange_t ofn; + Q_OffsetRange_t ocn; + Q_OffsetRange_t ofs; + Q_OffsetRange_t ocs; + long a3_offset; + MeasObjectToAddMod_t measObj; + //MeasId_t measId; + MeasObjectId_t measObjId; + ReportConfigId_t reportConfigId; + + for(i=0 ; i<NB_CNX_UE ; i++) { + for(j=0 ; j<MAX_MEAS_ID ; j++) { + if(UE_rrc_inst[Mod_id].MeasId[i][j] != NULL) { + measObjId = UE_rrc_inst[Mod_id].MeasId[i][j]->measObjectId; + reportConfigId = UE_rrc_inst[Mod_id].MeasId[i][j]->reportConfigId; + if( /*UE_rrc_inst[Mod_id].MeasId[i][j] != NULL && */ UE_rrc_inst[Mod_id].MeasObj[i][measObjId-1] != NULL) { + if(UE_rrc_inst[Mod_id].MeasObj[i][measObjId-1]->measObject.present == MeasObjectToAddMod__measObject_PR_measObjectEUTRA) { + /* consider any neighboring cell detected on the associated frequency to be + * applicable when the concerned cell is not included in the blackCellsToAddModList + * defined within the VarMeasConfig for this measId */ + // LOG_I(RRC,"event %d %d %p \n", measObjId,reportConfigId, UE_rrc_inst[Mod_id].ReportConfig[i][reportConfigId-1]); + if((UE_rrc_inst[Mod_id].ReportConfig[i][reportConfigId-1] != NULL) && + (UE_rrc_inst[Mod_id].ReportConfig[i][reportConfigId-1]->reportConfig.present==ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA) && + (UE_rrc_inst[Mod_id].ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.present == ReportConfigEUTRA__triggerType_PR_event)) { + hys = UE_rrc_inst[Mod_id].ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis; + //LOG_N(RRC,"[UE%d] Frame %d Check below lines for segfault :), Fix me \n",Mod_id, frame); + ttt_ms = timeToTrigger_ms[UE_rrc_inst[Mod_id].ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger]; + // Freq specific offset of neighbor cell freq + ofn = ((UE_rrc_inst[Mod_id].MeasObj[i][measObjId-1]->measObject.choice.measObjectEUTRA.offsetFreq != NULL) ? + *UE_rrc_inst[Mod_id].MeasObj[i][measObjId-1]->measObject.choice.measObjectEUTRA.offsetFreq : 15); // /* 15 is the Default */ + // cellIndividualOffset of neighbor cell - not defined yet + ocn = 0; + a3_offset = UE_rrc_inst[Mod_id].ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset; + + switch (UE_rrc_inst[Mod_id].ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present) { + case ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1: + LOG_D(RRC,"[UE %d] Frame %d : A1 event: check if serving becomes better than threshold\n",Mod_id, frame); + break; + case ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2: + LOG_D(RRC,"[UE %d] Frame %d : A2 event, check if serving becomes worse than a threshold\n",Mod_id, frame); + break; + case ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3: + LOG_D(RRC,"[UE %d] Frame %d : A3 event: check if a neighboring cell becomes offset better than serving to trigger a measurement event \n",Mod_id, frame); + if ((check_trigger_meas_event(Mod_id,frame,eNB_index,i,j,ofn,ocn,hys,ofs,ocs,a3_offset,ttt_ms)) && + (UE_rrc_inst[Mod_id].Info[0].State >= RRC_CONNECTED) && + (UE_rrc_inst[Mod_id].Info[0].T304_active == 0 ) && + (UE_rrc_inst[Mod_id].HandoverInfoUe.measFlag == 1)) { + //trigger measurement reporting procedure (36.331, section 5.5.5) + if (UE_rrc_inst[Mod_id].measReportList[i][j] == NULL) { + UE_rrc_inst[Mod_id].measReportList[i][j] = malloc(sizeof(MEAS_REPORT_LIST)); + } + UE_rrc_inst[Mod_id].measReportList[i][j]->measId = UE_rrc_inst[Mod_id].MeasId[i][j]->measId; + UE_rrc_inst[Mod_id].measReportList[i][j]->numberOfReportsSent = 0; + rrc_ue_generate_MeasurementReport(Mod_id,frame,eNB_index); + UE_rrc_inst[Mod_id].HandoverInfoUe.measFlag = 1; + LOG_I(RRC,"[UE %d] Frame %d: A3 event detected, state: %d \n", Mod_id, frame, UE_rrc_inst[Mod_id].Info[0].State); + } + else { + if(UE_rrc_inst[Mod_id].measReportList[i][j] != NULL){ + free(UE_rrc_inst[Mod_id].measReportList[i][j]); + } + UE_rrc_inst[Mod_id].measReportList[i][j] = NULL; + } + break; + case ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4: + LOG_D(RRC,"[UE %d] Frame %d : received an A4 event, neighbor becomes offset better than a threshold\n",Mod_id, frame); + break; + case ReportConfigEUTRA__triggerType__event__eventId_PR_eventA5: + LOG_D(RRC,"[UE %d] Frame %d: received an A5 event, serving becomes worse than threshold 1 and neighbor becomes better than threshold 2\n",Mod_id, frame); + break; + default: + LOG_D(RRC,"Invalid ReportConfigEUTRA__triggerType__event__eventId: %d", + UE_rrc_inst[Mod_id].ReportConfig[i][j]->reportConfig.choice.reportConfigEUTRA.triggerType.present); + break; + } + } + } + } + } + } + } +} + +//check_trigger_meas_event(Mod_id, frame, eNB_index, i,j,ofn,ocn,hys,ofs,ocs,a3_offset,ttt_ms) +u8 check_trigger_meas_event(u8 Mod_id,u32 frame, u8 eNB_index, u8 ue_cnx_index, u8 meas_index, + Q_OffsetRange_t ofn, Q_OffsetRange_t ocn, Hysteresis_t hys, + Q_OffsetRange_t ofs, Q_OffsetRange_t ocs, long a3_offset, TimeToTrigger_t ttt) { + u8 eNB_offset; + u8 currentCellIndex = mac_xface->lte_frame_parms->Nid_cell; + + LOG_I(RRC,"ofn(%d) ocn(%d) hys(%d) ofs(%d) ocs(%d) a3_offset(%d) ttt(%d) rssi %3.1f\n", \ + ofn,ocn,hys,ofs,ocs,a3_offset,ttt,10*log10(mac_xface->get_RSSI(Mod_id))-mac_xface->get_rx_total_gain_dB(Mod_id)); + + // for (eNB_offset = 0;(eNB_offset<1+mac_xface->get_n_adj_cells(Mod_id))&& (eNB_offset!=eNB_index);eNB_offset++) { + for (eNB_offset = 1;(eNB_offset<1+mac_xface->get_n_adj_cells(Mod_id));eNB_offset++) { + /* RHS: Verify that idx 0 corresponds to currentCellIndex in rsrp array */ + if(UE_rrc_inst[Mod_id].rsrp_db_filtered[eNB_offset]+ofn+ocn-hys > UE_rrc_inst[Mod_id].rsrp_db_filtered[0/*eNB_index*/]+ofs+ocs - 1 /*+a3_offset*/) { + UE_rrc_inst->measTimer[ue_cnx_index][meas_index][eNB_offset-1] += 2; //Called every subframe = 2ms + LOG_D(RRC,"[UE %d] Frame %d: Entry measTimer[%d][%d]: %d currentCell: %d betterCell: %d \n", + Mod_id, frame, ue_cnx_index,meas_index,UE_rrc_inst->measTimer[ue_cnx_index][meas_index][eNB_offset-1],currentCellIndex,eNB_offset); + } + else { + UE_rrc_inst->measTimer[ue_cnx_index][meas_index][eNB_offset-1] = 0; //Exit condition: Resetting the measurement timer + LOG_D(RRC,"[UE %d] Frame %d: Exit measTimer[%d][%d]: %d currentCell: %d betterCell: %d \n", + Mod_id, frame, ue_cnx_index,meas_index,UE_rrc_inst->measTimer[ue_cnx_index][meas_index][eNB_offset-1],currentCellIndex,eNB_offset); + } + if (UE_rrc_inst->measTimer[ue_cnx_index][meas_index][eNB_offset-1] >= ttt) { + UE_rrc_inst->HandoverInfoUe.targetCellId = get_adjacent_cell_id(Mod_id,eNB_offset-1); //check this! + LOG_D(RRC,"[UE %d] Frame %d eNB %d: Handover triggered: targetCellId: %d currentCellId: %d eNB_offset: %d rsrp source: %3.1f rsrp target: %3.1f\n", \ + Mod_id, frame, eNB_index, + UE_rrc_inst->HandoverInfoUe.targetCellId,ue_cnx_index,eNB_offset, + (dB_fixed_times10(UE_rrc_inst[Mod_id].rsrp_db[0])/10.0)-mac_xface->get_rx_total_gain_dB(Mod_id)-dB_fixed(mac_xface->lte_frame_parms->N_RB_DL*12), + (dB_fixed_times10(UE_rrc_inst[Mod_id].rsrp_db[eNB_offset])/10.0)-mac_xface->get_rx_total_gain_dB(Mod_id)-dB_fixed(mac_xface->lte_frame_parms->N_RB_DL*12)); + UE_rrc_inst->Info[0].handoverTarget = eNB_offset; + return 1; + } + } + return 0; +} + +//Below routine implements Measurement Reporting procedure from 36.331 Section 5.5.5 +void rrc_ue_generate_MeasurementReport(u8 Mod_id, u32 frame,u8 eNB_index) { + + u8 buffer[32], size; + u8 i,j; + u8 target_eNB_offset; + MeasId_t measId; + PhysCellId_t cellId, targetCellId; + long rsrq_s,rsrp_t,rsrq_t; + long rsrp_s, nElem, nElem1; + float rsrp_filtered, rsrq_filtered; + nElem = 100; + nElem1 = 33; + static u32 pframe=0; + int nid_cell = mac_xface->lte_frame_parms->Nid_cell; + target_eNB_offset = UE_rrc_inst[Mod_id].Info[0].handoverTarget; // eNB_offset of target eNB: used to obtain the mod_id of target eNB + + for (i=0;i<MAX_MEAS_ID;i++) { + if (UE_rrc_inst[Mod_id].measReportList[0][i] != NULL) { + measId = UE_rrc_inst[Mod_id].measReportList[0][i]->measId; + + // Note: Values in the meas report have to be the mapped values...to implement binary search for LUT + rsrp_filtered = UE_rrc_inst[Mod_id].rsrp_db_filtered[eNB_index];//nid_cell]; + rsrp_s = binary_search_float(RSRP_meas_mapping,nElem, rsrp_filtered); //mapped RSRP of serving cell + + rsrq_filtered = UE_rrc_inst[Mod_id].rsrq_db_filtered[eNB_index];//nid_cell]; //RSRQ of serving cell + rsrq_s = binary_search_float(RSRQ_meas_mapping,nElem1,rsrp_filtered);//mapped RSRQ of serving cell + + LOG_D(RRC,"[UE %d] Frame %d: source eNB %d :rsrp_s: %d rsrq_s: %d tmp: %f tmp1: %f \n", + Mod_id,frame,eNB_index, rsrp_s,rsrq_s,rsrp_filtered,rsrq_filtered); + + rsrp_t = binary_search_float(RSRP_meas_mapping,nElem,UE_rrc_inst[Mod_id].rsrp_db_filtered[target_eNB_offset]); //RSRP of target cell + rsrq_t = binary_search_float(RSRQ_meas_mapping,nElem1,UE_rrc_inst[Mod_id].rsrq_db_filtered[target_eNB_offset]); //RSRQ of target cell + + // if (measFlag == 1) { + cellId = get_adjacent_cell_id(Mod_id,eNB_index); //PhycellId of serving cell + targetCellId = UE_rrc_inst[Mod_id].HandoverInfoUe.targetCellId ;//get_adjacent_cell_id(Mod_id,target_eNB_offset); //PhycellId of target cell + + if (pframe!=frame){ + pframe=frame; + size = do_MeasurementReport(buffer,measId,targetCellId,rsrp_s,rsrq_s,rsrp_t,rsrq_t); + LOG_D(RRC,"[UE %d] Frame %d: Sending MeasReport: servingCell(%d) targetCell(%d) rsrp_s(%d) rsrq_s(%d) rsrp_t(%d) rsrq_t(%d) \n", + Mod_id, frame, cellId,targetCellId,rsrp_s,rsrq_s,rsrp_t,rsrq_t); + LOG_I(RRC,"[UE %d] Frame %d : Generating Measurement Report for eNB %d\n",Mod_id,frame,eNB_index); + LOG_D(RLC,"[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (MeasurementReport to eNB %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n", + frame, Mod_id+NB_eNB_INST, size, eNB_index, rrc_mui, Mod_id+NB_eNB_INST, DCCH); + pdcp_data_req(Mod_id+NB_eNB_INST,frame,0,DCCH,rrc_mui++,0,size,(char*)buffer,1); + //LOG_D(RRC, "[UE %d] Frame %d Sending MeasReport (%d bytes) through DCCH%d to PDCP \n",Mod_id,frame, size, DCCH); + } + // measFlag = 0; //re-setting measFlag so that no more MeasReports are sent in this frame + // } + } + } +} + + #ifdef Rel10 int decode_MCCH_Message(u8 Mod_id, u32 frame, u8 eNB_index, u8 *Sdu, u8 Sdu_len,u8 mbsfn_sync_area) { @@ -1700,6 +2102,7 @@ void decode_MBSFNAreaConfiguration(u8 Mod_id, u8 eNB_index, u32 frame,u8 mbsfn_s (struct LogicalChannelConfig *)NULL, (MeasGapConfig_t *)NULL, (TDD_Config_t *)NULL, + (MobilityControlInfo_t *)NULL, NULL, NULL, NULL, @@ -1722,9 +2125,7 @@ void decode_MBSFNAreaConfiguration(u8 Mod_id, u8 eNB_index, u32 frame,u8 mbsfn_s 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, - 0,// eNB_flag - eNB_index,// 0,// index + rrc_pdcp_config_asn1_req(NB_eNB_INST+Mod_id,frame,0,eNB_index, NULL, // SRB_ToAddModList NULL, // DRB_ToAddModList (DRB_ToReleaseList_t*)NULL, @@ -1733,18 +2134,18 @@ void decode_MBSFNAreaConfiguration(u8 Mod_id, u8 eNB_index, u32 frame,u8 mbsfn_s NULL, // key rrc integrity NULL // key encryption #ifdef Rel10 - , - &(UE_rrc_inst[Mod_id].mcch_message[eNB_index]->pmch_InfoList_r9) + ,&(UE_rrc_inst[Mod_id].mcch_message[eNB_index]->pmch_InfoList_r9) #endif ); - rrc_rlc_config_asn1_req(NB_eNB_INST+Mod_id, frame, - 0,// eNB_flag - 0, + rrc_rlc_config_asn1_req(NB_eNB_INST+Mod_id, frame,0,eNB_index, NULL,// SRB_ToAddModList NULL,// DRB_ToAddModList NULL,// DRB_ToReleaseList - &(UE_rrc_inst[Mod_id].mcch_message[eNB_index]->pmch_InfoList_r9)); +#ifdef Rel10 + &(UE_rrc_inst[Mod_id].mcch_message[eNB_index]->pmch_InfoList_r9) +#endif + ); // */ } diff --git a/openair2/RRC/LITE/rrc_common.c b/openair2/RRC/LITE/rrc_common.c index b22103ad4752782a0daaa171a31888681813cc63..b28b154e7aa5678f9244bd58846a0ae250122575 100644 --- a/openair2/RRC/LITE/rrc_common.c +++ b/openair2/RRC/LITE/rrc_common.c @@ -51,6 +51,8 @@ extern eNB_MAC_INST *eNB_mac_inst; extern UE_MAC_INST *UE_mac_inst; +extern mui_t rrc_eNB_mui; + //configure BCCH & CCCH Logical Channels and associated rrc_buffers, configure associated SRBs void openair_rrc_on(u8 Mod_id, u8 eNB_flag) { unsigned short i; @@ -203,7 +205,7 @@ void rrc_config_buffer(SRB_INFO *Srb_info, u8 Lchan_type, u8 Role) { } /*------------------------------------------------------------------------------*/ -void openair_rrc_top_init(int eMBMS_active, u8 cba_group_active) { +void openair_rrc_top_init(int eMBMS_active, u8 cba_group_active,u8 HO_active){ /*-----------------------------------------------------------------------------*/ int i; @@ -241,6 +243,10 @@ void openair_rrc_top_init(int eMBMS_active, u8 cba_group_active) { if (NB_eNB_INST > 0) { eNB_rrc_inst = (eNB_RRC_INST*) malloc16(NB_eNB_INST*sizeof(eNB_RRC_INST)); memset (eNB_rrc_inst, 0, NB_eNB_INST * sizeof(eNB_RRC_INST)); + LOG_I(RRC,"[eNB] handover active state is %d \n", HO_active); + for (i=0;i<NB_eNB_INST;i++) { + eNB_rrc_inst[i].HO_flag = (uint8_t)HO_active; + } #ifdef Rel10 LOG_I(RRC,"[eNB] eMBMS active state is %d \n", eMBMS_active); for (i=0;i<NB_eNB_INST;i++) { @@ -280,14 +286,6 @@ void rrc_top_cleanup(void) { } -u16 T300[8] = - {100, 200, 300, 400, 600, 1000, 1500, 2000}; -u16 T310[8] = - {0, 50, 100, 200, 500, 1000, 2000}; -u16 N310[8] = - {1, 2, 3, 4, 6, 8, 10, 20}; -u16 N311[8] = - {1, 2, 3, 4, 6, 8, 10, 20}; void rrc_t310_expiration(u32 frame, u8 Mod_id, u8 eNB_index) { @@ -319,9 +317,9 @@ void rrc_t310_expiration(u32 frame, u8 Mod_id, u8 eNB_index) { } } -RRC_status_t rrc_rx_tx(u8 Mod_id, u32 frame, u8 eNB_flag, u8 index) { - - if (eNB_flag == 0) { +RRC_status_t rrc_rx_tx(u8 Mod_id,u32 frame, u8 eNB_flag,u8 index){ + + if(eNB_flag == 0) { // check timers if (UE_rrc_inst[Mod_id].Info[index].T300_active == 1) { @@ -350,7 +348,6 @@ RRC_status_t rrc_rx_tx(u8 Mod_id, u32 frame, u8 eNB_flag, u8 index) { return RRC_PHY_RESYNCH; } } - if (UE_rrc_inst[Mod_id].Info[index].T310_active == 1) { if (UE_rrc_inst[Mod_id].Info[index].N311_cnt == N311[UE_rrc_inst[Mod_id].sib2[index]->ue_TimersAndConstants.n311]) { @@ -367,7 +364,93 @@ RRC_status_t rrc_rx_tx(u8 Mod_id, u32 frame, u8 eNB_flag, u8 index) { } UE_rrc_inst[Mod_id].Info[index].T310_cnt++; } - } + + + if (UE_rrc_inst[Mod_id].Info[index].T304_active==1) { + if ((UE_rrc_inst[Mod_id].Info[index].T304_cnt % 10) == 0) + LOG_D(RRC,"[UE %d][RAPROC] Frame %d T304 Count %d ms\n",Mod_id,frame, + UE_rrc_inst[Mod_id].Info[index].T304_cnt); + if (UE_rrc_inst[Mod_id].Info[index].T304_cnt == 0) { + UE_rrc_inst[Mod_id].Info[index].T304_active = 0; + UE_rrc_inst[Mod_id].HandoverInfoUe.measFlag = 1; + LOG_E(RRC,"[UE %d] Handover failure..initiating connection re-establishment procedure... \n"); + //Implement 36.331, section 5.3.5.6 here + return(RRC_Handover_failed); + } + UE_rrc_inst[Mod_id].Info[index].T304_cnt--; + } + // Layer 3 filtering of RRC measurements + if (UE_rrc_inst[Mod_id].QuantityConfig[0] != NULL) { + ue_meas_filtering(Mod_id,frame,index); + } + ue_measurement_report_triggering(Mod_id,frame,index); + if (UE_rrc_inst[Mod_id].Info[0].handoverTarget > 0) + LOG_I(RRC,"[UE %d] Frame %d : RRC handover initiated\n", Mod_id, frame); + if((UE_rrc_inst[Mod_id].Info[index].State == RRC_HO_EXECUTION) && + (UE_rrc_inst[Mod_id].HandoverInfoUe.targetCellId != 0xFF)) { + UE_rrc_inst[Mod_id].Info[index].State= RRC_IDLE; + return(RRC_HO_STARTED); + } + } + else { + check_handovers(Mod_id,frame); + } + return (RRC_OK); } + +long binary_search_int(int elements[], long numElem, int value) { + long first, last, middle, search; + first = 0; + last = numElem-1; + middle = (first+last)/2; + if(value < elements[0]) + return first; + if(value > elements[last]) + return last; + + while (first <= last) { + if (elements[middle] < value) + first = middle+1; + else if (elements[middle] == value) { + search = middle+1; + break; + } + else + last = middle -1; + + middle = (first+last)/2; + } + if (first > last) + LOG_E(RRC,"Error in binary search!"); + return search; +} + +/* This is a binary search routine which operates on an array of floating + point numbers and returns the index of the range the value lies in + Used for RSRP and RSRQ measurement mapping. Can potentially be used for other things +*/ +long binary_search_float(float elements[], long numElem, float value) { + long first, last, middle, search; + first = 0; + last = numElem-1; + middle = (first+last)/2; + if(value <= elements[0]) + return first; + if(value >= elements[last]) + return last; + + while (last - first > 1) { + if (elements[middle] > value) + last = middle; + else + first = middle; + + middle = (first+last)/2; + } + if (first < 0 || first >= numElem) + LOG_E(RRC,"\n Error in binary search float!"); + return first; +} + diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index e6c7cf890032e31f9d4d9d8e1eae062bea9d32c3..7c198e77c32095e77bf44ff44865de35937eeae5 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -50,6 +50,7 @@ #include "UL-DCCH-Message.h" #include "DL-DCCH-Message.h" #include "TDD-Config.h" +#include "HandoverCommand.h" #include "rlc.h" #include "SIMULATION/ETH_TRANSPORT/extern.h" @@ -89,6 +90,7 @@ extern UE_MAC_INST *UE_mac_inst; extern void *bigphys_malloc (int); #endif +extern uint16_t two_tier_hexagonal_cellIds[7]; extern inline unsigned int taus (void); void init_SI (u8 Mod_id) { @@ -287,6 +289,7 @@ init_SI (u8 Mod_id) { (struct LogicalChannelConfig *) NULL, (MeasGapConfig_t *) NULL, eNB_rrc_inst[Mod_id].sib1->tdd_Config, + NULL, &SIwindowsize, &SIperiod, eNB_rrc_inst[Mod_id].sib2->freqInfo.ul_CarrierFreq, eNB_rrc_inst[Mod_id].sib2->freqInfo.ul_Bandwidth, @@ -302,7 +305,7 @@ init_SI (u8 Mod_id) { (PMCH_InfoList_r9_t *) NULL #endif #ifdef CBA - , 0, //eNB_rrc_inst[Mod_id].num_active_cba_groups, + ,0, //eNB_rrc_inst[Mod_id].num_active_cba_groups, 0 //eNB_rrc_inst[Mod_id].cba_rnti[0] #endif ); @@ -375,6 +378,7 @@ init_MCCH (u8 Mod_id) { (struct LogicalChannelConfig *) NULL, (MeasGapConfig_t *) NULL, (TDD_Config_t *) NULL, + NULL, (u8 *) NULL, (u16 *) NULL, NULL, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL @@ -570,18 +574,19 @@ get_next_UE_index (u8 Mod_id, u8 * UE_identity) { - if ((first_index == 255) - && (*(unsigned int *) eNB_rrc_inst[Mod_id].Info.UE_list[i] == - 0x00000000)) + if ((first_index == 255) && (*(unsigned int *) eNB_rrc_inst[Mod_id].Info.UE_list[i] == 0x00000000)) first_index = i; // save first free position - if ((eNB_rrc_inst[Mod_id].Info.UE_list[i][0] == UE_identity[0]) && (eNB_rrc_inst[Mod_id].Info.UE_list[i][1] == UE_identity[1]) && (eNB_rrc_inst[Mod_id].Info.UE_list[i][2] == UE_identity[2]) && (eNB_rrc_inst[Mod_id].Info.UE_list[i][3] == UE_identity[3]) && (eNB_rrc_inst[Mod_id].Info.UE_list[i][4] == UE_identity[4])) // UE_identity already registered + if ((eNB_rrc_inst[Mod_id].Info.UE_list[i][0] == UE_identity[0]) && + (eNB_rrc_inst[Mod_id].Info.UE_list[i][1] == UE_identity[1]) && + (eNB_rrc_inst[Mod_id].Info.UE_list[i][2] == UE_identity[2]) && + (eNB_rrc_inst[Mod_id].Info.UE_list[i][3] == UE_identity[3]) && + (eNB_rrc_inst[Mod_id].Info.UE_list[i][4] == UE_identity[4])) // UE_identity already registered reg = 1; } - if (reg == 0) - { + if (reg == 0) { LOG_I (RRC, "Adding UE %d\n", first_index); return (first_index); } @@ -652,7 +657,7 @@ rrc_eNB_decode_dcch (u8 Mod_id, u32 frame, u8 Srb_id, u8 UE_index, "[MSC_MSG][FRAME %05d][RLC][MOD %02d][RB %02d][--- RLC_DATA_IND " "%d bytes (measurementReport) --->][RRC_eNB][MOD %02d][]\n", frame, Mod_id, DCCH, sdu_size, Mod_id); - rrc_eNB_process_MeasurementReport (Mod_id, UE_index, + rrc_eNB_process_MeasurementReport (Mod_id, frame, UE_index, &ul_dcch_msg->message.choice.c1. choice.measurementReport. criticalExtensions.choice.c1. @@ -786,7 +791,7 @@ rrc_eNB_decode_dcch (u8 Mod_id, u32 frame, u8 Srb_id, u8 UE_index, #endif rrc_eNB_generate_defaultRRCConnectionReconfiguration (Mod_id, frame, UE_index, - NULL, 0); + NULL, 0, eNB_rrc_inst[Mod_id].HO_flag); break; case UL_DCCH_MessageType__c1_PR_ulHandoverPreparationTransfer: break; @@ -919,21 +924,17 @@ rrc_eNB_decode_ccch (u8 Mod_id, u32 frame, SRB_INFO * Srb_info) "[MSC_MSG][FRAME %05d][MAC_eNB][MOD %02d][][--- MAC_DATA_IND (rrcConnectionRequest on SRB0) -->][RRC_eNB][MOD %02d][]\n", frame, Mod_id, Mod_id); - rrcConnectionRequest = - &ul_ccch_msg->message.choice.c1.choice.rrcConnectionRequest. - criticalExtensions.choice.rrcConnectionRequest_r8; - UE_index = - get_next_UE_index (Mod_id, - (u8 *) rrcConnectionRequest->ue_Identity. - choice.randomValue.buf); + rrcConnectionRequest = &ul_ccch_msg->message.choice.c1.choice.rrcConnectionRequest.criticalExtensions.choice.rrcConnectionRequest_r8; + UE_index = get_next_UE_index (Mod_id, + (u8 *) rrcConnectionRequest->ue_Identity. + choice.randomValue.buf); if (UE_index != 255) { // memcpy(&Rrc_xface->UE_id[Mod_id][UE_index],(u8 *)rrcConnectionRequest->ue_Identity.choice.randomValue.buf,5); memcpy (&eNB_rrc_inst[Mod_id].Info.UE_list[UE_index], - (u8 *) rrcConnectionRequest->ue_Identity.choice. - randomValue.buf, 5); + (u8 *) rrcConnectionRequest->ue_Identity.choice.randomValue.buf, 5); LOG_I (RRC, "[eNB %d] Frame %d : Accept new connection from UE %d (%x%x%x%x%x)\n", @@ -953,7 +954,6 @@ rrc_eNB_decode_ccch (u8 Mod_id, u32 frame, SRB_INFO * Srb_info) send_msg (&S_rrc, msg_rrc_MR_attach_ind (Mod_id, Mac_id)); #else - Idx = (UE_index * NB_RB_MAX) + DCCH; // SRB1 eNB_rrc_inst[Mod_id].Srb1[UE_index].Active = 1; @@ -977,9 +977,7 @@ rrc_eNB_decode_ccch (u8 Mod_id, u32 frame, SRB_INFO * Srb_info) //LOG_D(RRC,"[eNB %d] RLC AM allocation index@0 is %d\n",Mod_id,rlc[Mod_id].m_rlc_am_array[0].allocation); //LOG_D(RRC,"[eNB %d] RLC AM allocation index@1 is %d\n",Mod_id,rlc[Mod_id].m_rlc_am_array[1].allocation); - LOG_I (RRC, - "[eNB %d] CALLING RLC CONFIG SRB1 (rbid %d) for UE %d\n", - Mod_id, Idx, UE_index); + LOG_I (RRC,"[eNB %d] CALLING RLC CONFIG SRB1 (rbid %d) for UE %d\n",Mod_id, Idx, UE_index); // rrc_pdcp_config_req (Mod_id, frame, 1, ACTION_ADD, idx, UNDEF_SECURITY_MODE); @@ -1051,8 +1049,7 @@ rrc_eNB_process_RRCConnectionSetupComplete (u8 Mod_id, * rrcConnectionSetupComplete) { - LOG_I (RRC, "[eNB %d][RAPROC] Frame %d : Logical Channel UL-DCCH, " - "processing RRCConnectionSetupComplete from UE %d\n", + LOG_I (RRC, "[eNB %d][RAPROC] Frame %d : Logical Channel UL-DCCH, ""processing RRCConnectionSetupComplete from UE %d\n", Mod_id, frame, UE_index); // Forward message to S1AP layer @@ -1122,16 +1119,15 @@ rrc_eNB_generate_UECapabilityEnquiry (u8 Mod_id, u32 frame, u16 UE_index) rrc_eNB_mui++, 0, size, buffer, 1); } - void rrc_eNB_generate_defaultRRCConnectionReconfiguration (u8 Mod_id, u32 frame, u16 UE_index, u8 * nas_pdu, - u32 nas_length) + u32 nas_length, + u8 ho_state) { - - u8 buffer[100]; + u8 buffer[RRC_BUF_SIZE]; u8 size; int i; @@ -1139,8 +1135,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration (u8 Mod_id, u32 frame, eNB_RRC_INST *rrc_inst = &eNB_rrc_inst[Mod_id]; - struct PhysicalConfigDedicated **physicalConfigDedicated = - &rrc_inst->physicalConfigDedicated[UE_index]; + struct PhysicalConfigDedicated **physicalConfigDedicated = &rrc_inst->physicalConfigDedicated[UE_index]; struct SRB_ToAddMod *SRB2_config; @@ -1175,8 +1170,9 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration (u8 Mod_id, u32 frame, long *logicalchannelgroup, *logicalchannelgroup_drb; long *maxHARQ_Tx, *periodicBSR_Timer; - // RSRP_Range_t *rsrp; - // struct MeasConfig__speedStatePars *Sparams; + RSRP_Range_t *rsrp=NULL; + struct MeasConfig__speedStatePars *Sparams=NULL; + QuantityConfig_t *quantityConfig=NULL; CellsToAddMod_t *CellToAdd; CellsToAddModList_t *CellsToAddModList; @@ -1211,10 +1207,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration (u8 Mod_id, u32 frame, #endif - - // // Configure SRB2 - /// SRB2 SRB2_config = CALLOC (1, sizeof (*SRB2_config)); SRB_configList2 = CALLOC (1, sizeof (*SRB_configList2)); @@ -1226,34 +1219,24 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration (u8 Mod_id, u32 frame, SRB2_rlc_config->present = SRB_ToAddMod__rlc_Config_PR_explicitValue; SRB2_rlc_config->choice.explicitValue.present = RLC_Config_PR_am; - SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = - T_PollRetransmit_ms15; - SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = - PollPDU_p8; - SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = - PollByte_kB1000; - SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = - UL_AM_RLC__maxRetxThreshold_t32; - SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = - T_Reordering_ms50; - SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = - T_StatusProhibit_ms10; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = T_PollRetransmit_ms15; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = PollPDU_p8; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = PollByte_kB1000; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = UL_AM_RLC__maxRetxThreshold_t32; + SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = T_Reordering_ms50; + SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms10; SRB2_lchan_config = CALLOC (1, sizeof (*SRB2_lchan_config)); SRB2_config->logicalChannelConfig = SRB2_lchan_config; - SRB2_lchan_config->present = - SRB_ToAddMod__logicalChannelConfig_PR_explicitValue; + SRB2_lchan_config->present = SRB_ToAddMod__logicalChannelConfig_PR_explicitValue; - SRB2_ul_SpecificParameters = - CALLOC (1, sizeof (*SRB2_ul_SpecificParameters)); + SRB2_ul_SpecificParameters = CALLOC (1, sizeof (*SRB2_ul_SpecificParameters)); SRB2_ul_SpecificParameters->priority = 1; - SRB2_ul_SpecificParameters->prioritisedBitRate = - LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; - SRB2_ul_SpecificParameters->bucketSizeDuration = - LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + SRB2_ul_SpecificParameters->prioritisedBitRate = LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + SRB2_ul_SpecificParameters->bucketSizeDuration = LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; // LCG for CCCH and DCCH is 0 as defined in 36331 logicalchannelgroup = CALLOC (1, sizeof (long)); @@ -1261,15 +1244,12 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration (u8 Mod_id, u32 frame, SRB2_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup; - SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters = - SRB2_ul_SpecificParameters; + SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters = SRB2_ul_SpecificParameters; ASN_SEQUENCE_ADD (&SRB_configList->list, SRB2_config); ASN_SEQUENCE_ADD (&SRB_configList2->list, SRB2_config); // Configure DRB - *DRB_configList = CALLOC (1, sizeof (*DRB_configList)); - /// DRB DRB_config = CALLOC (1, sizeof (*DRB_config)); @@ -1281,12 +1261,9 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration (u8 Mod_id, u32 frame, DRB_rlc_config = CALLOC (1, sizeof (*DRB_rlc_config)); DRB_config->rlc_Config = DRB_rlc_config; DRB_rlc_config->present = RLC_Config_PR_um_Bi_Directional; - DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = - SN_FieldLength_size10; - DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = - SN_FieldLength_size10; - DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = - T_Reordering_ms5; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = T_Reordering_ms5; DRB_pdcp_config = CALLOC (1, sizeof (*DRB_pdcp_config)); DRB_config->pdcp_Config = DRB_pdcp_config; @@ -1295,8 +1272,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration (u8 Mod_id, u32 frame, PDCP_rlc_UM = CALLOC (1, sizeof (*PDCP_rlc_UM)); DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; PDCP_rlc_UM->pdcp_SN_Size = PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; - DRB_pdcp_config->headerCompression.present = - PDCP_Config__headerCompression_PR_notUsed; + DRB_pdcp_config->headerCompression.present = PDCP_Config__headerCompression_PR_notUsed; DRB_lchan_config = CALLOC (1, sizeof (*DRB_lchan_config)); DRB_config->logicalChannelConfig = DRB_lchan_config; @@ -1305,42 +1281,33 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration (u8 Mod_id, u32 frame, DRB_ul_SpecificParameters->priority = 2; // lower priority than srb1, srb2 - DRB_ul_SpecificParameters->prioritisedBitRate = - LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; - DRB_ul_SpecificParameters->bucketSizeDuration = - LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + DRB_ul_SpecificParameters->prioritisedBitRate = LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + DRB_ul_SpecificParameters->bucketSizeDuration = LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM) logicalchannelgroup_drb = CALLOC (1, sizeof (long)); *logicalchannelgroup_drb = 1; DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; - ASN_SEQUENCE_ADD (&(*DRB_configList)->list, DRB_config); mac_MainConfig = CALLOC (1, sizeof (*mac_MainConfig)); eNB_rrc_inst[Mod_id].mac_MainConfig[UE_index] = mac_MainConfig; - mac_MainConfig->ul_SCH_Config = - CALLOC (1, sizeof (*mac_MainConfig->ul_SCH_Config)); + mac_MainConfig->ul_SCH_Config = CALLOC (1, sizeof (*mac_MainConfig->ul_SCH_Config)); maxHARQ_Tx = CALLOC (1, sizeof (long)); *maxHARQ_Tx = MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx; - periodicBSR_Timer = CALLOC (1, sizeof (long)); *periodicBSR_Timer = MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf64; mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; - - mac_MainConfig->ul_SCH_Config->retxBSR_Timer = - MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf320; - + mac_MainConfig->ul_SCH_Config->retxBSR_Timer = MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf320; mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE mac_MainConfig->drx_Config = NULL; - mac_MainConfig->phr_Config = - CALLOC (1, sizeof (*mac_MainConfig->phr_Config)); + mac_MainConfig->phr_Config = CALLOC (1, sizeof (*mac_MainConfig->phr_Config)); mac_MainConfig->phr_Config->present = MAC_MainConfig__phr_Config_PR_setup; mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; // sf20 = 20 subframes @@ -1409,35 +1376,29 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration (u8 Mod_id, u32 frame, memset ((void *) MeasObj, 0, sizeof (*MeasObj)); MeasObj->measObjectId = 1; - MeasObj->measObject.present = - MeasObjectToAddMod__measObject_PR_measObjectEUTRA; + MeasObj->measObject.present = MeasObjectToAddMod__measObject_PR_measObjectEUTRA; MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 36090; - MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = - AllowedMeasBandwidth_mbw25; + MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = AllowedMeasBandwidth_mbw25; MeasObj->measObject.choice.measObjectEUTRA.presenceAntennaPort1 = 1; - MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf = - CALLOC (1, sizeof (uint8_t)); + MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf = CALLOC (1, sizeof (uint8_t)); MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf[0] = 0; MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.size = 1; MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.bits_unused = 6; MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = NULL; // Default is 15 or 0dB - MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList = - (CellsToAddModList_t *) CALLOC (1, sizeof (*CellsToAddModList)); + MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList = (CellsToAddModList_t *) CALLOC (1, sizeof (*CellsToAddModList)); - CellsToAddModList = - MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList; + CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList; // Add adjacent cell lists (6 per eNB) - for (i = 0; i < 6; i++) - { + for (i = 0; i < 6; i++) { CellToAdd = (CellsToAddMod_t *) CALLOC (1, sizeof (*CellToAdd)); CellToAdd->cellIndex = i + 1; CellToAdd->physCellId = get_adjacent_cell_id (Mod_id, i); CellToAdd->cellIndividualOffset = Q_OffsetRange_dB0; ASN_SEQUENCE_ADD (&CellsToAddModList->list, CellToAdd); - } + } ASN_SEQUENCE_ADD (&MeasObj_list->list, MeasObj); // rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measObjectToAddModList = MeasObj_list; @@ -1465,146 +1426,161 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration (u8 Mod_id, u32 frame, memset ((void *) ReportConfig_A5, 0, sizeof (*ReportConfig_A5)); ReportConfig_per->reportConfigId = 1; - ReportConfig_per->reportConfig.present = - ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; - ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType. - present = ReportConfigEUTRA__triggerType_PR_periodical; - ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.choice. - periodical.purpose = - ReportConfigEUTRA__triggerType__periodical__purpose_reportStrongestCells; - ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerQuantity = - ReportConfigEUTRA__triggerQuantity_rsrp; - ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportQuantity = - ReportConfigEUTRA__reportQuantity_both; + ReportConfig_per->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.present = ReportConfigEUTRA__triggerType_PR_periodical; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.choice.periodical.purpose = ReportConfigEUTRA__triggerType__periodical__purpose_reportStrongestCells; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerQuantity = ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both; ReportConfig_per->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; - ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportInterval = - ReportInterval_ms120; - ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportAmount = - ReportConfigEUTRA__reportAmount_infinity; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportInterval = ReportInterval_ms120; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity; ASN_SEQUENCE_ADD (&ReportConfig_list->list, ReportConfig_per); - + ReportConfig_A1->reportConfigId = 2; - ReportConfig_A1->reportConfig.present = - ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; - ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.present = - ReportConfigEUTRA__triggerType_PR_event; - ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice. - event.eventId.present = - ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1; - ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice. - event.eventId.choice.eventA1.a1_Threshold.present = + ReportConfig_A1->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.present = ReportConfigEUTRA__triggerType_PR_event; + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1; + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA1.a1_Threshold.present = ThresholdEUTRA_PR_threshold_RSRP; - ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice. - event.eventId.choice.eventA1.a1_Threshold.choice.threshold_RSRP = 10; + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA1.a1_Threshold.choice.threshold_RSRP = 10; - ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerQuantity = - ReportConfigEUTRA__triggerQuantity_rsrp; - ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportQuantity = - ReportConfigEUTRA__reportQuantity_both; + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerQuantity = ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; - ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportInterval = - ReportInterval_ms120; - ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportAmount = - ReportConfigEUTRA__reportAmount_infinity; + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportInterval = ReportInterval_ms120; + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity; ASN_SEQUENCE_ADD (&ReportConfig_list->list, ReportConfig_A1); - /* - ReportConfig_A2->reportConfigId = 3; - ReportConfig_A2->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; - ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.present = ReportConfigEUTRA__triggerType_PR_event; - ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2; - ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA2.a2_Threshold.present = ThresholdEUTRA_PR_threshold_RSRP; - ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA2.a2_Threshold.choice.threshold_RSRP = 10; - - ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerQuantity = ReportConfigEUTRA__triggerQuantity_rsrp; - ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both; - ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; - ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportInterval = ReportInterval_ms120; - ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity; - - ASN_SEQUENCE_ADD(&ReportConfig_list->list,ReportConfig_A2); - - ReportConfig_A3->reportConfigId = 4; - ReportConfig_A3->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.present = ReportConfigEUTRA__triggerType_PR_event; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset = 10; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.reportOnLeave = 1; - - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerQuantity = ReportConfigEUTRA__triggerQuantity_rsrp; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportInterval = ReportInterval_ms120; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity; - - ASN_SEQUENCE_ADD(&ReportConfig_list->list,ReportConfig_A3); - - ReportConfig_A4->reportConfigId = 5; - ReportConfig_A4->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; - ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.present = ReportConfigEUTRA__triggerType_PR_event; - ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4; - ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA4.a4_Threshold.present = ThresholdEUTRA_PR_threshold_RSRP; - ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA4.a4_Threshold.choice.threshold_RSRP = 10; - - ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerQuantity = ReportConfigEUTRA__triggerQuantity_rsrp; - ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both; - ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; - ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportInterval = ReportInterval_ms120; - ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity; - - ASN_SEQUENCE_ADD(&ReportConfig_list->list,ReportConfig_A4); - - ReportConfig_A5->reportConfigId = 6; - ReportConfig_A5->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.present = ReportConfigEUTRA__triggerType_PR_event; - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = ReportConfigEUTRA__triggerType__event__eventId_PR_eventA5; - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA5.a5_Threshold1.present = ThresholdEUTRA_PR_threshold_RSRP; - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA5.a5_Threshold2.present = ThresholdEUTRA_PR_threshold_RSRP; - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA5.a5_Threshold1.choice.threshold_RSRP = 10; - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA5.a5_Threshold2.choice.threshold_RSRP = 10; - - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerQuantity = ReportConfigEUTRA__triggerQuantity_rsrp; - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both; - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportInterval = ReportInterval_ms120; - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity; - - ASN_SEQUENCE_ADD(&ReportConfig_list->list,ReportConfig_A5); - // rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list; - */ - /* - rsrp=CALLOC(1,sizeof(RSRP_Range_t)); - *rsrp=20; + if (ho_state == 1 /*HO_MEASURMENT*/ ){ + LOG_I(RRC,"[eNB %d] frame %d: requesting A2, A3, A4, A5, and A6 event reporting\n", Mod_id, frame); + ReportConfig_A2->reportConfigId = 3; + ReportConfig_A2->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.present = ReportConfigEUTRA__triggerType_PR_event; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present= ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA2.a2_Threshold.present = ThresholdEUTRA_PR_threshold_RSRP; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA2.a2_Threshold.choice.threshold_RSRP = 10; + + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerQuantity = ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportInterval = ReportInterval_ms120; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity; + + ASN_SEQUENCE_ADD(&ReportConfig_list->list,ReportConfig_A2); + + ReportConfig_A3->reportConfigId = 4; + ReportConfig_A3->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.present = ReportConfigEUTRA__triggerType_PR_event; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3; - Sparams = CALLOC(1,sizeof(*Sparams)); - Sparams->present=MeasConfig__speedStatePars_PR_setup; - Sparams->choice.setup.timeToTrigger_SF.sf_High=SpeedStateScaleFactors__sf_Medium_oDot75; - Sparams->choice.setup.timeToTrigger_SF.sf_Medium=SpeedStateScaleFactors__sf_High_oDot5; - Sparams->choice.setup.mobilityStateParameters.n_CellChangeHigh=10; - Sparams->choice.setup.mobilityStateParameters.n_CellChangeMedium=5; - Sparams->choice.setup.mobilityStateParameters.t_Evaluation=MobilityStateParameters__t_Evaluation_s60; - Sparams->choice.setup.mobilityStateParameters.t_HystNormal=MobilityStateParameters__t_HystNormal_s120; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset = 1;//10; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.reportOnLeave = 1; + + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerQuantity = ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportInterval = ReportInterval_ms120; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity; + + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis = 0.5; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger = TimeToTrigger_ms40; + ASN_SEQUENCE_ADD(&ReportConfig_list->list,ReportConfig_A3); + + ReportConfig_A4->reportConfigId = 5; + ReportConfig_A4->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.present = ReportConfigEUTRA__triggerType_PR_event; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA4.a4_Threshold.present = ThresholdEUTRA_PR_threshold_RSRP; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA4.a4_Threshold.choice.threshold_RSRP = 10; + + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerQuantity = ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportInterval = ReportInterval_ms120; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity; + + ASN_SEQUENCE_ADD(&ReportConfig_list->list,ReportConfig_A4); + + ReportConfig_A5->reportConfigId = 6; + ReportConfig_A5->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.present = ReportConfigEUTRA__triggerType_PR_event; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = ReportConfigEUTRA__triggerType__event__eventId_PR_eventA5; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA5.a5_Threshold1.present = ThresholdEUTRA_PR_threshold_RSRP; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA5.a5_Threshold2.present = ThresholdEUTRA_PR_threshold_RSRP; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA5.a5_Threshold1.choice.threshold_RSRP = 10; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA5.a5_Threshold2.choice.threshold_RSRP = 10; + + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerQuantity = ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportInterval = ReportInterval_ms120; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity; + + ASN_SEQUENCE_ADD(&ReportConfig_list->list,ReportConfig_A5); + // rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list; - speedStatePars=Sparams; - rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->s_Measure=rsrp; + rsrp=CALLOC(1,sizeof(RSRP_Range_t)); + *rsrp=20; + + Sparams = CALLOC(1,sizeof(*Sparams)); + Sparams->present=MeasConfig__speedStatePars_PR_setup; + Sparams->choice.setup.timeToTrigger_SF.sf_High=SpeedStateScaleFactors__sf_Medium_oDot75; + Sparams->choice.setup.timeToTrigger_SF.sf_Medium=SpeedStateScaleFactors__sf_High_oDot5; + Sparams->choice.setup.mobilityStateParameters.n_CellChangeHigh=10; + Sparams->choice.setup.mobilityStateParameters.n_CellChangeMedium=5; + Sparams->choice.setup.mobilityStateParameters.t_Evaluation=MobilityStateParameters__t_Evaluation_s60; + Sparams->choice.setup.mobilityStateParameters.t_HystNormal=MobilityStateParameters__t_HystNormal_s120; + + quantityConfig = CALLOC(1,sizeof(*quantityConfig)); + memset((void *)quantityConfig,0,sizeof(*quantityConfig)); + quantityConfig->quantityConfigEUTRA = CALLOC(1,sizeof(struct QuantityConfigEUTRA)); + memset((void *)quantityConfig->quantityConfigEUTRA,0,sizeof(*quantityConfig->quantityConfigEUTRA)); + quantityConfig->quantityConfigCDMA2000 = NULL; + quantityConfig->quantityConfigGERAN = NULL; + quantityConfig->quantityConfigUTRA = NULL; + quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = CALLOC(1,sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP))); + quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = CALLOC(1,sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ))); + *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = FilterCoefficient_fc4; + *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = FilterCoefficient_fc4; + + LOG_I(RRC,"[eNB %d] Frame %d: potential handover preparation: store the information in an intermediate structure in case of failure\n",Mod_id, frame); + // store the information in an intermediate structure for Hanodver management + //rrc_inst->handover_info.as_config.sourceRadioResourceConfig.srb_ToAddModList = CALLOC(1,sizeof()); + rrc_inst->handover_info[UE_index] = CALLOC(1,sizeof(*(rrc_inst->handover_info[UE_index]))); + //memcpy((void *)rrc_inst->handover_info[UE_index]->as_config.sourceRadioResourceConfig.srb_ToAddModList,(void *)SRB_list,sizeof(SRB_ToAddModList_t)); + rrc_inst->handover_info[UE_index]->as_config.sourceRadioResourceConfig.srb_ToAddModList = SRB_configList2; + //memcpy((void *)rrc_inst->handover_info[UE_index]->as_config.sourceRadioResourceConfig.drb_ToAddModList,(void *)DRB_list,sizeof(DRB_ToAddModList_t)); + rrc_inst->handover_info[UE_index]->as_config.sourceRadioResourceConfig.drb_ToAddModList = DRB_configList; + rrc_inst->handover_info[UE_index]->as_config.sourceRadioResourceConfig.drb_ToReleaseList = NULL; + rrc_inst->handover_info[UE_index]->as_config.sourceRadioResourceConfig.mac_MainConfig = CALLOC(1, sizeof(*rrc_inst->handover_info[UE_index]->as_config.sourceRadioResourceConfig.mac_MainConfig)); + memcpy((void *)rrc_inst->handover_info[UE_index]->as_config.sourceRadioResourceConfig.mac_MainConfig, + (void *)mac_MainConfig, + sizeof(MAC_MainConfig_t)); + rrc_inst->handover_info[UE_index]->as_config.sourceRadioResourceConfig.physicalConfigDedicated = CALLOC(1,sizeof(PhysicalConfigDedicated_t)); + memcpy((void *)rrc_inst->handover_info[UE_index]->as_config.sourceRadioResourceConfig.physicalConfigDedicated, + (void *)rrc_inst->physicalConfigDedicated[UE_index], + sizeof(PhysicalConfigDedicated_t)); + rrc_inst->handover_info[UE_index]->as_config.sourceRadioResourceConfig.sps_Config = NULL; + //memcpy((void *)rrc_inst->handover_info[UE_index]->as_config.sourceRadioResourceConfig.sps_Config,(void *)rrc_inst->sps_Config[UE_index],sizeof(SPS_Config_t)); - */ - memset (buffer, 0, 100); + } + + memset (buffer, 0, RRC_BUF_SIZE); size = do_RRCConnectionReconfiguration (Mod_id, buffer, UE_index, 0, //Transaction_id, SRB_configList2, *DRB_configList, NULL, // DRB2_list, NULL, //*sps_Config, - physicalConfigDedicated[UE_index], MeasObj_list, ReportConfig_list, NULL, //*QuantityConfig, - MeasId_list, mac_MainConfig, NULL, cba_RNTI, nas_pdu, nas_length); //*measGapConfig); + physicalConfigDedicated[UE_index], MeasObj_list, ReportConfig_list, + quantityConfig, + MeasId_list, mac_MainConfig, NULL,NULL,Sparams,rsrp, + cba_RNTI, nas_pdu, nas_length); - LOG_I (RRC, - "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration (bytes %d, UE id %d)\n", + LOG_I (RRC,"[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration (bytes %d, UE id %d)\n", Mod_id, frame, size, UE_index); - LOG_D (RRC, - "[MSC_MSG][FRAME %05d][RRC_eNB][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n", + LOG_D (RRC,"[MSC_MSG][FRAME %05d][RRC_eNB][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n", frame, Mod_id, size, UE_index, rrc_eNB_mui, Mod_id, (UE_index * NB_RB_MAX) + DCCH); //rrc_rlc_data_req(Mod_id,frame, 1,(UE_index*NB_RB_MAX)+DCCH,rrc_eNB_mui++,0,size,(char*)buffer); @@ -1612,29 +1588,21 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration (u8 Mod_id, u32 frame, rrc_eNB_mui++, 0, size, buffer, 1); } - void -rrc_eNB_process_MeasurementReport (u8 Mod_id, u16 UE_index, +rrc_eNB_process_MeasurementReport (u8 Mod_id, u32 frame, u16 UE_index, MeasResults_t * measResults2) { - LOG_I (RRC, "Received Measurement Report From UE %d (Measurement Id %d)\n", - UE_index, (int) measResults2->measId); - if (measResults2->measResultNeighCells->choice.measResultListEUTRA.list. - count > 0) - { + LOG_I (RRC,"[eNB %d] Frame %d: Process Measurement Report From UE %d (Measurement Id %d)\n", + Mod_id, frame, UE_index, (int) measResults2->measId); + if (measResults2->measResultNeighCells->choice.measResultListEUTRA.list.count > 0) { LOG_I (RRC, "Physical Cell Id %d\n", - (int) measResults2->measResultNeighCells->choice. - measResultListEUTRA.list.array[0]->physCellId); + (int) measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]->physCellId); LOG_I (RRC, "RSRP of Target %d\n", - (int) *(measResults2->measResultNeighCells->choice. - measResultListEUTRA.list.array[0]->measResult. - rsrpResult)); + (int) *(measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]->measResult.rsrpResult)); LOG_I (RRC, "RSRQ of Target %d\n", - (int) *(measResults2->measResultNeighCells->choice. - measResultListEUTRA.list.array[0]->measResult. - rsrqResult)); - } + (int) *(measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]->measResult.rsrqResult)); + } #ifdef Rel10 LOG_I (RRC, "RSRP of Source %d\n", measResults2->measResultPCell.rsrpResult); @@ -1647,6 +1615,14 @@ rrc_eNB_process_MeasurementReport (u8 Mod_id, u16 UE_index, measResults2->measResultServCell.rsrqResult); #endif + if(eNB_rrc_inst[Mod_id].handover_info[UE_index]->ho_prepare != 0xF0){ + rrc_eNB_generate_HandoverPreparationInformation(Mod_id, + frame, + UE_index, + measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]->physCellId); + }else{ + LOG_D(RRC,"[eNB %d] Frame %d: Ignoring MeasReport from UE %d as Handover is in progress... \n",Mod_id,frame, UE_index); + } //Look for IP address of the target eNB //Send Handover Request -> target eNB //Wait for Handover Acknowledgement <- target eNB @@ -1661,14 +1637,951 @@ rrc_eNB_process_MeasurementReport (u8 Mod_id, u16 UE_index, // send_check_message((char*)buffer,size); //send_handover_command(); +} +void +rrc_eNB_generate_HandoverPreparationInformation (u8 Mod_id, u32 frame, u8 UE_index, PhysCellId_t targetPhyId) { + + u8 buffer[100]; + u8 size,UE_id_target; + u8 mod_id_target = get_adjacent_cell_mod_id(targetPhyId); + HANDOVER_INFO *handoverInfo = CALLOC(1,sizeof(*handoverInfo)); + struct PhysicalConfigDedicated **physicalConfigDedicated = &eNB_rrc_inst[Mod_id].physicalConfigDedicated[UE_index]; + RadioResourceConfigDedicated_t *radioResourceConfigDedicated = CALLOC(1,sizeof(RadioResourceConfigDedicated_t)); + + + handoverInfo->as_config.antennaInfoCommon.antennaPortsCount = 0; //Not used 0- but check value + handoverInfo->as_config.sourceDl_CarrierFreq = 36090; //Verify! + memcpy((void*) &handoverInfo->as_config.sourceMasterInformationBlock, + (void*) &eNB_rrc_inst[Mod_id].mib, + sizeof(MasterInformationBlock_t)); + memcpy((void*) &handoverInfo->as_config.sourceMeasConfig, + (void*) &eNB_rrc_inst[Mod_id].measConfig[UE_index], + sizeof(MeasConfig_t)); + //to be configured + memset((void *)&eNB_rrc_inst[Mod_id].handover_info[UE_index]->as_config.sourceSecurityAlgorithmConfig, + 0, + sizeof(SecurityAlgorithmConfig_t)); + + memcpy((void *)&eNB_rrc_inst[Mod_id].handover_info[UE_index]->as_config.sourceSystemInformationBlockType1, + (void *)&eNB_rrc_inst[Mod_id].SIB1, + sizeof(SystemInformationBlockType1_t)); + memcpy((void *)&eNB_rrc_inst[Mod_id].handover_info[UE_index]->as_config.sourceSystemInformationBlockType2, + (void *)&eNB_rrc_inst[Mod_id].SIB23, + sizeof(SystemInformationBlockType2_t)); + + eNB_rrc_inst[Mod_id].handover_info[UE_index]->as_context.reestablishmentInfo = CALLOC(1,sizeof(ReestablishmentInfo_t)); + eNB_rrc_inst[Mod_id].handover_info[UE_index]->as_context.reestablishmentInfo->sourcePhysCellId = eNB_rrc_inst[Mod_id].physCellId; + eNB_rrc_inst[Mod_id].handover_info[UE_index]->as_context.reestablishmentInfo->targetCellShortMAC_I.buf = NULL; // Check values later + eNB_rrc_inst[Mod_id].handover_info[UE_index]->as_context.reestablishmentInfo->targetCellShortMAC_I.size = 0; + eNB_rrc_inst[Mod_id].handover_info[UE_index]->as_context.reestablishmentInfo->targetCellShortMAC_I.bits_unused = 0; + eNB_rrc_inst[Mod_id].handover_info[UE_index]->as_context.reestablishmentInfo->additionalReestabInfoList = NULL; + + eNB_rrc_inst[Mod_id].handover_info[UE_index]->ho_prepare = 0xFF;//0xF0; + eNB_rrc_inst[Mod_id].handover_info[UE_index]->ho_complete = 0; + + if (mod_id_target != 0xFF) { + //UE_id_target = rrc_find_free_ue_index(modid_target); + UE_id_target = get_next_UE_index(mod_id_target,(u8 *)eNB_rrc_inst[Mod_id].Info.UE_list[UE_index]); //this should return a new index + + if (UE_id_target!=0xFF) { + LOG_N(RRC,"[eNB %d] Frame %d : Emulate sending HandoverPreparationInformation msg from eNB source %d to eNB target %d: source UE_id %d target UE_id %d source_modId: %d target_modId: %d\n",Mod_id,frame,eNB_rrc_inst[Mod_id].physCellId,targetPhyId,UE_index,UE_id_target,Mod_id,mod_id_target); + eNB_rrc_inst[mod_id_target].handover_info[UE_id_target] = CALLOC(1,sizeof(*(eNB_rrc_inst[mod_id_target].handover_info[UE_id_target]))); + memcpy((void *)&eNB_rrc_inst[mod_id_target].handover_info[UE_id_target]->as_context, + (void *)&eNB_rrc_inst[Mod_id].handover_info[UE_index]->as_context, + sizeof(AS_Context_t)); + memcpy((void *)&eNB_rrc_inst[mod_id_target].handover_info[UE_id_target]->as_config, + (void *)&eNB_rrc_inst[Mod_id].handover_info[UE_index]->as_config, + sizeof(AS_Config_t)); + + eNB_rrc_inst[mod_id_target].handover_info[UE_id_target]->ho_prepare = 0xFF; + eNB_rrc_inst[mod_id_target].handover_info[UE_id_target]->ho_complete = 0; + + eNB_rrc_inst[Mod_id].handover_info[UE_index]->modid_t = mod_id_target; + eNB_rrc_inst[Mod_id].handover_info[UE_index]->ueid_s = UE_index; + eNB_rrc_inst[Mod_id].handover_info[UE_index]->modid_s = Mod_id; + eNB_rrc_inst[mod_id_target].handover_info[UE_id_target]->modid_t = mod_id_target; + eNB_rrc_inst[mod_id_target].handover_info[UE_id_target]->modid_s = Mod_id; + eNB_rrc_inst[mod_id_target].handover_info[UE_id_target]->ueid_t = UE_id_target; + } + else + LOG_E(RRC,"\nError in obtaining free UE id in target eNB %l for handover \n", targetPhyId); + } + else + LOG_E(RRC,"\nError in obtaining Module ID of target eNB for handover \n"); +} + +void check_handovers(u8 Mod_id, u32 frame) { + u8 i; + for (i=0;i<NUMBER_OF_UE_MAX;i++) { + if(eNB_rrc_inst[Mod_id].handover_info[i] != NULL) { + if(eNB_rrc_inst[Mod_id].handover_info[i]->ho_prepare == 0xFF) { + LOG_D(RRC,"[eNB %d] Frame %d: Incoming handover detected for new UE_idx %d (source eNB %d->target eNB %d) \n", + Mod_id, frame, i,Mod_id, eNB_rrc_inst[Mod_id].handover_info[i]->modid_t); + // source eNB generates rrcconnectionreconfiguration to prepare the HO + rrc_eNB_process_handoverPreparationInformation(Mod_id,frame,i); + eNB_rrc_inst[Mod_id].handover_info[i]->ho_prepare = 0xF1; + } + + if(eNB_rrc_inst[Mod_id].handover_info[i]->ho_complete == 0xF1) { + LOG_D(RRC,"[eNB %d] Frame %d: handover Command received for new UE_idx %d current eNB %d target eNB: %d \n", + Mod_id, frame, i,Mod_id,eNB_rrc_inst[Mod_id].handover_info[i]->modid_t); + //rrc_eNB_process_handoverPreparationInformation(Mod_id,frame,i); + pdcp_data_req(Mod_id,frame, 1, + (i* NB_RB_MAX)+DCCH, + rrc_eNB_mui++,0, + eNB_rrc_inst[Mod_id].handover_info[i]->size, + (char*)eNB_rrc_inst[Mod_id].handover_info[i]->buf,1); + eNB_rrc_inst[Mod_id].handover_info[i]->ho_complete = 0xF2; + } + } + } +} + +void rrc_eNB_process_handoverPreparationInformation(u8 Mod_id,u32 frame, u16 UE_index) { + + LOG_I(RRC,"[eNB %d] Frame %d : Logical Channel UL-DCCH, processing RRCHandoverPreparationInformation, sending RRCConnectionReconfiguration to UE %d \n",Mod_id,frame,UE_index); + + + //eNB_rrc_inst[Mod_id].Info.UE_list[UE_index] + rrc_eNB_generate_RRCConnectionReconfiguration_handover(Mod_id,frame,UE_index,NULL,0); + +} +// 5.3.5.4 RRCConnectionReconfiguration including the mobilityControlInfo to prepare the UE handover +void +rrc_eNB_generate_RRCConnectionReconfiguration_handover (u8 Mod_id, u32 frame,u16 UE_index,u8 *nas_pdu,u32 nas_length) { + + u8 buffer[RRC_BUF_SIZE]; + u8 size; + int i; + uint8_t rv[2]; + u16 Idx; + // configure SRB1/SRB2, PhysicalConfigDedicated, MAC_MainConfig for UE + eNB_RRC_INST *rrc_inst = &eNB_rrc_inst[Mod_id]; + + struct PhysicalConfigDedicated **physicalConfigDedicated = &rrc_inst->physicalConfigDedicated[UE_index]; + + struct SRB_ToAddMod *SRB2_config; + struct SRB_ToAddMod__rlc_Config *SRB2_rlc_config; + struct SRB_ToAddMod__logicalChannelConfig *SRB2_lchan_config; + struct LogicalChannelConfig__ul_SpecificParameters *SRB2_ul_SpecificParameters; + LogicalChannelConfig_t *SRB1_logicalChannelConfig; + SRB_ToAddModList_t *SRB_configList = rrc_inst->SRB_configList[UE_index]; // not used in this context: may be removed + SRB_ToAddModList_t *SRB_configList2; + + struct DRB_ToAddMod *DRB_config; + struct RLC_Config *DRB_rlc_config; + struct PDCP_Config *DRB_pdcp_config; + struct PDCP_Config__rlc_UM *PDCP_rlc_UM; + struct LogicalChannelConfig *DRB_lchan_config; + struct LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters; + DRB_ToAddModList_t **DRB_configList = &rrc_inst->DRB_configList[UE_index]; + DRB_ToAddModList_t *DRB_configList2; + + MAC_MainConfig_t *mac_MainConfig; + MeasObjectToAddModList_t *MeasObj_list; + MeasObjectToAddMod_t *MeasObj; + ReportConfigToAddModList_t *ReportConfig_list; + ReportConfigToAddMod_t *ReportConfig_per, *ReportConfig_A1, + *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5; + MeasIdToAddModList_t *MeasId_list; + MeasIdToAddMod_t *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5; + QuantityConfig_t *quantityConfig; + MobilityControlInfo_t *mobilityInfo; + HandoverCommand_t handoverCommand; + u8 sourceModId = get_adjacent_cell_mod_id(rrc_inst->handover_info[UE_index]->as_context.reestablishmentInfo->sourcePhysCellId); +#if Rel10 + long *sr_ProhibitTimer_r9; +#endif + + long *logicalchannelgroup, *logicalchannelgroup_drb; + long *maxHARQ_Tx, *periodicBSR_Timer; + + RSRP_Range_t *rsrp; + struct MeasConfig__speedStatePars *Sparams; + CellsToAddMod_t *CellToAdd; + CellsToAddModList_t *CellsToAddModList; + // srb 1: for HO + struct SRB_ToAddMod *SRB1_config; + struct SRB_ToAddMod__rlc_Config *SRB1_rlc_config; + struct SRB_ToAddMod__logicalChannelConfig *SRB1_lchan_config; + struct LogicalChannelConfig__ul_SpecificParameters *SRB1_ul_SpecificParameters; + // phy config dedicated + PhysicalConfigDedicated_t *physicalConfigDedicated2; + + + LOG_D(RRC,"[eNB %d] Frame %d: handover preparation: get the newSourceUEIdentity (C-RNTI): ", Mod_id, frame); + for (i=0;i<2;i++) { + rv[i]=taus()&0xff; + LOG_D(RRC," %x.",rv[i]); + } + + LOG_D(RRC,"[eNB %d] Frame %d : handover reparation: add target eNB SRB1 and PHYConfigDedicated reconfiguration\n",Mod_id, frame); + // 1st: reconfigure SRB + SRB_configList2 = CALLOC(1,sizeof(*SRB_configList)); + SRB1_config = CALLOC(1,sizeof(*SRB1_config)); + SRB1_config->srb_Identity = 1; + SRB1_rlc_config = CALLOC(1,sizeof(*SRB1_rlc_config)); + SRB1_config->rlc_Config = SRB1_rlc_config; + + SRB1_rlc_config->present = SRB_ToAddMod__rlc_Config_PR_explicitValue; + SRB1_rlc_config->choice.explicitValue.present=RLC_Config_PR_am; + SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit=T_PollRetransmit_ms15; + SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU=PollPDU_p8; + SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte=PollByte_kB1000; + SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold=UL_AM_RLC__maxRetxThreshold_t16; + SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering=T_Reordering_ms50; + SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit=T_StatusProhibit_ms10; + + SRB1_lchan_config = CALLOC(1,sizeof(*SRB1_lchan_config)); + SRB1_config->logicalChannelConfig = SRB1_lchan_config; + + SRB1_lchan_config->present = SRB_ToAddMod__logicalChannelConfig_PR_explicitValue; + SRB1_ul_SpecificParameters = CALLOC(1,sizeof(*SRB1_ul_SpecificParameters)); + + SRB1_lchan_config->choice.explicitValue.ul_SpecificParameters = SRB1_ul_SpecificParameters; + + SRB1_ul_SpecificParameters->priority = 1; + + //assign_enum(&SRB1_ul_SpecificParameters->prioritisedBitRate,LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity); + SRB1_ul_SpecificParameters->prioritisedBitRate=LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + + //assign_enum(&SRB1_ul_SpecificParameters->bucketSizeDuration,LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50); + SRB1_ul_SpecificParameters->bucketSizeDuration=LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + + logicalchannelgroup = CALLOC(1,sizeof(long)); + *logicalchannelgroup=0; + SRB1_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup; + + ASN_SEQUENCE_ADD(&SRB_configList2->list,SRB1_config); + + //2nd: now reconfigure phy config dedicated + physicalConfigDedicated2 = CALLOC(1,sizeof(*physicalConfigDedicated2)); + *physicalConfigDedicated = physicalConfigDedicated2; + + physicalConfigDedicated2->pdsch_ConfigDedicated = CALLOC(1,sizeof(*physicalConfigDedicated2->pdsch_ConfigDedicated)); + physicalConfigDedicated2->pucch_ConfigDedicated = CALLOC(1,sizeof(*physicalConfigDedicated2->pucch_ConfigDedicated)); + physicalConfigDedicated2->pusch_ConfigDedicated = CALLOC(1,sizeof(*physicalConfigDedicated2->pusch_ConfigDedicated)); + physicalConfigDedicated2->uplinkPowerControlDedicated = CALLOC(1,sizeof(*physicalConfigDedicated2->uplinkPowerControlDedicated)); + physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH = CALLOC(1,sizeof(*physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH)); + physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH = CALLOC(1,sizeof(*physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH)); + physicalConfigDedicated2->cqi_ReportConfig = NULL;//CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig)); + physicalConfigDedicated2->soundingRS_UL_ConfigDedicated = NULL;//CALLOC(1,sizeof(*physicalConfigDedicated2->soundingRS_UL_ConfigDedicated)); + physicalConfigDedicated2->antennaInfo = CALLOC(1,sizeof(*physicalConfigDedicated2->antennaInfo)); + physicalConfigDedicated2->schedulingRequestConfig = CALLOC(1,sizeof(*physicalConfigDedicated2->schedulingRequestConfig)); + // PDSCH + //assign_enum(&physicalConfigDedicated2->pdsch_ConfigDedicated->p_a, + // PDSCH_ConfigDedicated__p_a_dB0); + physicalConfigDedicated2->pdsch_ConfigDedicated->p_a= PDSCH_ConfigDedicated__p_a_dB0; + + // PUCCH + physicalConfigDedicated2->pucch_ConfigDedicated->ackNackRepetition.present=PUCCH_ConfigDedicated__ackNackRepetition_PR_release; + physicalConfigDedicated2->pucch_ConfigDedicated->ackNackRepetition.choice.release=0; + physicalConfigDedicated2->pucch_ConfigDedicated->tdd_AckNackFeedbackMode=NULL;//PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing; + + // Pusch_config_dedicated + physicalConfigDedicated2->pusch_ConfigDedicated->betaOffset_ACK_Index = 0; // 2.00 + physicalConfigDedicated2->pusch_ConfigDedicated->betaOffset_RI_Index = 0; // 1.25 + physicalConfigDedicated2->pusch_ConfigDedicated->betaOffset_CQI_Index = 8; // 2.25 + + // UplinkPowerControlDedicated + physicalConfigDedicated2->uplinkPowerControlDedicated->p0_UE_PUSCH = 0; // 0 dB + //assign_enum(&physicalConfigDedicated2->uplinkPowerControlDedicated->deltaMCS_Enabled, + // UplinkPowerControlDedicated__deltaMCS_Enabled_en1); + physicalConfigDedicated2->uplinkPowerControlDedicated->deltaMCS_Enabled= UplinkPowerControlDedicated__deltaMCS_Enabled_en1; + physicalConfigDedicated2->uplinkPowerControlDedicated->accumulationEnabled = 1; // FALSE + physicalConfigDedicated2->uplinkPowerControlDedicated->p0_UE_PUCCH = 0; // 0 dB + physicalConfigDedicated2->uplinkPowerControlDedicated->pSRS_Offset = 0; // 0 dB + physicalConfigDedicated2->uplinkPowerControlDedicated->filterCoefficient = CALLOC(1,sizeof(*physicalConfigDedicated2->uplinkPowerControlDedicated->filterCoefficient)); + // assign_enum(physicalConfigDedicated2->uplinkPowerControlDedicated->filterCoefficient,FilterCoefficient_fc4); // fc4 dB + *physicalConfigDedicated2->uplinkPowerControlDedicated->filterCoefficient=FilterCoefficient_fc4; // fc4 dB + + // TPC-PDCCH-Config + physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->present=TPC_PDCCH_Config_PR_setup; + physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_Index.present = TPC_Index_PR_indexOfFormat3; + physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_Index.choice.indexOfFormat3 = 1; + physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_RNTI.buf=CALLOC(1,2); + physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_RNTI.size=2; + physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_RNTI.buf[0]=0x12; + physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_RNTI.buf[1]=0x34+UE_index; + physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_RNTI.bits_unused=0; + + physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->present=TPC_PDCCH_Config_PR_setup; + physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_Index.present = TPC_Index_PR_indexOfFormat3; + physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_Index.choice.indexOfFormat3 = 1; + physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.buf=CALLOC(1,2); + physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.size=2; + physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.buf[0]=0x22; + physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.buf[1]=0x34+UE_index; + physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.bits_unused=0; + + // CQI ReportConfig + /* + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic=CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic)); + assign_enum(physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic, + CQI_ReportConfig__cqi_ReportModeAperiodic_rm30); // HLC CQI, no PMI + physicalConfigDedicated2->cqi_ReportConfig->nomPDSCH_RS_EPRE_Offset = 0; // 0 dB + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic=CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic)); + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->present = CQI_ReportPeriodic_PR_setup; + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex = 0; // n2_pucch + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex = 0; // Icqi/pmi + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present = CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI; // subband CQI + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.choice.subbandCQI.k=4; + + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex=NULL; + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.simultaneousAckNackAndCQI=0; + */ + + //soundingRS-UL-ConfigDedicated + /* + physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->present = SoundingRS_UL_ConfigDedicated_PR_setup; + assign_enum(&physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth, + SoundingRS_UL_ConfigDedicated__setup__srs_Bandwidth_bw0); + assign_enum(&physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth, + SoundingRS_UL_ConfigDedicated__setup__srs_HoppingBandwidth_hbw0); + physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition=0; + physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.duration=1; + physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex=1; + physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb=0; + assign_enum(&physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift, + SoundingRS_UL_ConfigDedicated__setup__cyclicShift_cs0); + */ + + //AntennaInfoDedicated + physicalConfigDedicated2->antennaInfo = CALLOC(1,sizeof(*physicalConfigDedicated2->antennaInfo)); + physicalConfigDedicated2->antennaInfo->present = PhysicalConfigDedicated__antennaInfo_PR_explicitValue; + //assign_enum(&physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode, + // AntennaInfoDedicated__transmissionMode_tm2); + /* + switch (transmission_mode){ + case 1: + physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= AntennaInfoDedicated__transmissionMode_tm1; + break; + case 2: + physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= AntennaInfoDedicated__transmissionMode_tm2; + break; + case 4: + physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= AntennaInfoDedicated__transmissionMode_tm4; + break; + case 5: + physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= AntennaInfoDedicated__transmissionMode_tm5; + break; + case 6: + physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= AntennaInfoDedicated__transmissionMode_tm6; + break; + } + */ + physicalConfigDedicated2->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.present = AntennaInfoDedicated__ue_TransmitAntennaSelection_PR_release; + physicalConfigDedicated2->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.release = 0; + + // SchedulingRequestConfig + physicalConfigDedicated2->schedulingRequestConfig->present = SchedulingRequestConfig_PR_setup; + physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = UE_index; + + if (mac_xface->lte_frame_parms->frame_type == 0){ // FDD + physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 5+(UE_index%10); // Isr = 5 (every 10 subframes, offset=2+UE_id mod3) +} else { + switch (mac_xface->lte_frame_parms->tdd_config) { + case 1: + physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 7+(UE_index&1)+((UE_index&3)>>1)*5; // Isr = 5 (every 10 subframes, offset=2 for UE0, 3 for UE1, 7 for UE2, 8 for UE3 , 2 for UE4 etc..) + break; + case 3: + physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 7+(UE_index%3); // Isr = 5 (every 10 subframes, offset=2 for UE0, 3 for UE1, 3 for UE2, 2 for UE3 , etc..) + break; + case 4: + physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 7+(UE_index&1); // Isr = 5 (every 10 subframes, offset=2 for UE0, 3 for UE1, 3 for UE2, 2 for UE3 , etc..) + break; + default: + physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 7; // Isr = 5 (every 10 subframes, offset=2 for all UE0 etc..) + break; + } + } + + // assign_enum(&physicalConfigDedicated2->schedulingRequestConfig->choice.setup.dsr_TransMax, + //SchedulingRequestConfig__setup__dsr_TransMax_n4); + // assign_enum(&physicalConfigDedicated2->schedulingRequestConfig->choice.setup.dsr_TransMax = SchedulingRequestConfig__setup__dsr_TransMax_n4; + physicalConfigDedicated2->schedulingRequestConfig->choice.setup.dsr_TransMax = SchedulingRequestConfig__setup__dsr_TransMax_n4; + + LOG_D(RRC,"handover_config [MSC_MSG][FRAME %05d][RRC_eNB][MOD %02d][][--- MAC_CONFIG_REQ (SRB1 UE %d) --->][MAC_eNB][MOD %02d][]\n", + frame, Mod_id, UE_index, Mod_id); + rrc_mac_config_req (Mod_id, 1, UE_index, 0, + (RadioResourceConfigCommonSIB_t *) NULL, + eNB_rrc_inst[Mod_id].physicalConfigDedicated[UE_index], + (MeasObjectToAddMod_t **) NULL, + eNB_rrc_inst[Mod_id].mac_MainConfig[UE_index], + 1, + SRB1_logicalChannelConfig, + eNB_rrc_inst[Mod_id].measGapConfig[UE_index], + (TDD_Config_t *) NULL, + (MobilityControlInfo_t *)NULL, + (u8 *) NULL,(u16 *) NULL, NULL, NULL, NULL, + (MBSFN_SubframeConfigList_t *) NULL +#ifdef Rel10 + , + 0, + (MBSFN_AreaInfoList_r9_t *) NULL, + (PMCH_InfoList_r9_t *) NULL +#endif +#ifdef CBA + , + eNB_rrc_inst[Mod_id]. + num_active_cba_groups, + eNB_rrc_inst[Mod_id].cba_rnti[0] +#endif + ); + + + // Configure target eNB SRB2 + /// SRB2 + SRB2_config = CALLOC (1, sizeof (*SRB2_config)); + SRB_configList2 = CALLOC (1, sizeof (*SRB_configList2)); + memset (SRB_configList2, 0, sizeof (*SRB_configList2)); + + SRB2_config->srb_Identity = 2; + SRB2_rlc_config = CALLOC (1, sizeof (*SRB2_rlc_config)); + SRB2_config->rlc_Config = SRB2_rlc_config; + + SRB2_rlc_config->present = SRB_ToAddMod__rlc_Config_PR_explicitValue; + SRB2_rlc_config->choice.explicitValue.present = RLC_Config_PR_am; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = T_PollRetransmit_ms15; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = PollPDU_p8; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = PollByte_kB1000; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = UL_AM_RLC__maxRetxThreshold_t32; + SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = T_Reordering_ms50; + SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms10; + + SRB2_lchan_config = CALLOC (1, sizeof (*SRB2_lchan_config)); + SRB2_config->logicalChannelConfig = SRB2_lchan_config; + + SRB2_lchan_config->present = SRB_ToAddMod__logicalChannelConfig_PR_explicitValue; + + SRB2_ul_SpecificParameters = CALLOC (1, sizeof (*SRB2_ul_SpecificParameters)); + + SRB2_ul_SpecificParameters->priority = 1; + SRB2_ul_SpecificParameters->prioritisedBitRate = LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + SRB2_ul_SpecificParameters->bucketSizeDuration = LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + + // LCG for CCCH and DCCH is 0 as defined in 36331 + logicalchannelgroup = CALLOC (1, sizeof (long)); + *logicalchannelgroup = 0; + + SRB2_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup; + SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters = SRB2_ul_SpecificParameters; + ASN_SEQUENCE_ADD (&SRB_configList->list, SRB2_config); + ASN_SEQUENCE_ADD (&SRB_configList2->list, SRB2_config); + + // Configure target eNB DRB + DRB_configList2 = CALLOC (1, sizeof (*DRB_configList2)); + /// DRB + DRB_config = CALLOC (1, sizeof (*DRB_config)); + + //DRB_config->drb_Identity = (DRB_Identity_t) 1; //allowed values 1..32 + // NN: this is the 1st DRB for this ue, so set it to 1 + DRB_config->drb_Identity = (DRB_Identity_t) 1; // (UE_index+1); //allowed values 1..32 + DRB_config->logicalChannelIdentity = CALLOC (1, sizeof (long)); + *(DRB_config->logicalChannelIdentity) = (long) 3; + DRB_rlc_config = CALLOC (1, sizeof (*DRB_rlc_config)); + DRB_config->rlc_Config = DRB_rlc_config; + DRB_rlc_config->present = RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = T_Reordering_ms5; + + DRB_pdcp_config = CALLOC (1, sizeof (*DRB_pdcp_config)); + DRB_config->pdcp_Config = DRB_pdcp_config; + DRB_pdcp_config->discardTimer = NULL; + DRB_pdcp_config->rlc_AM = NULL; + PDCP_rlc_UM = CALLOC (1, sizeof (*PDCP_rlc_UM)); + DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; + PDCP_rlc_UM->pdcp_SN_Size = PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; + DRB_pdcp_config->headerCompression.present = PDCP_Config__headerCompression_PR_notUsed; + + DRB_lchan_config = CALLOC (1, sizeof (*DRB_lchan_config)); + DRB_config->logicalChannelConfig = DRB_lchan_config; + DRB_ul_SpecificParameters = CALLOC (1, sizeof (*DRB_ul_SpecificParameters)); + DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; + + + DRB_ul_SpecificParameters->priority = 2; // lower priority than srb1, srb2 + DRB_ul_SpecificParameters->prioritisedBitRate = LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + DRB_ul_SpecificParameters->bucketSizeDuration = LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + + // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM) + logicalchannelgroup_drb = CALLOC (1, sizeof (long)); + *logicalchannelgroup_drb = 1; + DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; + + + ASN_SEQUENCE_ADD (&DRB_configList2->list, DRB_config); + + mac_MainConfig = CALLOC (1, sizeof (*mac_MainConfig)); + eNB_rrc_inst[Mod_id].mac_MainConfig[UE_index] = mac_MainConfig; + + mac_MainConfig->ul_SCH_Config = CALLOC (1, sizeof (*mac_MainConfig->ul_SCH_Config)); + + maxHARQ_Tx = CALLOC (1, sizeof (long)); + *maxHARQ_Tx = MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; + mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx; + + periodicBSR_Timer = CALLOC (1, sizeof (long)); + *periodicBSR_Timer = MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf64; + mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; + + mac_MainConfig->ul_SCH_Config->retxBSR_Timer = MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf320; + + mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE + + mac_MainConfig->drx_Config = NULL; + + mac_MainConfig->phr_Config = CALLOC (1, sizeof (*mac_MainConfig->phr_Config)); + + mac_MainConfig->phr_Config->present = MAC_MainConfig__phr_Config_PR_setup; + mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; // sf20 = 20 subframes + + mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; // sf20 = 20 subframes + + mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; // Value dB1 =1 dB, dB3 = 3 dB + +#ifdef Rel10 + sr_ProhibitTimer_r9 = CALLOC (1, sizeof (long)); + *sr_ProhibitTimer_r9 = 0; // SR tx on PUCCH, Value in number of SR period(s). Value 0 = no timer for SR, Value 2= 2*SR + mac_MainConfig->sr_ProhibitTimer_r9 = sr_ProhibitTimer_r9; + //sps_RA_ConfigList_rlola = NULL; +#endif + // Measurement ID list + MeasId_list = CALLOC (1, sizeof (*MeasId_list)); + memset ((void *) MeasId_list, 0, sizeof (*MeasId_list)); + + MeasId0 = CALLOC (1, sizeof (*MeasId0)); + MeasId0->measId = 1; + MeasId0->measObjectId = 1; + MeasId0->reportConfigId = 1; + ASN_SEQUENCE_ADD (&MeasId_list->list, MeasId0); + + MeasId1 = CALLOC (1, sizeof (*MeasId1)); + MeasId1->measId = 2; + MeasId1->measObjectId = 1; + MeasId1->reportConfigId = 2; + ASN_SEQUENCE_ADD (&MeasId_list->list, MeasId1); + + MeasId2 = CALLOC (1, sizeof (*MeasId2)); + MeasId2->measId = 3; + MeasId2->measObjectId = 1; + MeasId2->reportConfigId = 3; + ASN_SEQUENCE_ADD (&MeasId_list->list, MeasId2); + + MeasId3 = CALLOC (1, sizeof (*MeasId3)); + MeasId3->measId = 4; + MeasId3->measObjectId = 1; + MeasId3->reportConfigId = 4; + ASN_SEQUENCE_ADD (&MeasId_list->list, MeasId3); + + MeasId4 = CALLOC (1, sizeof (*MeasId4)); + MeasId4->measId = 5; + MeasId4->measObjectId = 1; + MeasId4->reportConfigId = 5; + ASN_SEQUENCE_ADD (&MeasId_list->list, MeasId4); + + MeasId5 = CALLOC (1, sizeof (*MeasId5)); + MeasId5->measId = 6; + MeasId5->measObjectId = 1; + MeasId5->reportConfigId = 6; + ASN_SEQUENCE_ADD (&MeasId_list->list, MeasId5); + + // rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measIdToAddModList = MeasId_list; + + // Add one EUTRA Measurement Object + MeasObj_list = CALLOC (1, sizeof (*MeasObj_list)); + memset ((void *) MeasObj_list, 0, sizeof (*MeasObj_list)); + + // Configure MeasObject + + MeasObj = CALLOC (1, sizeof (*MeasObj)); + memset ((void *) MeasObj, 0, sizeof (*MeasObj)); + + MeasObj->measObjectId = 1; + MeasObj->measObject.present = MeasObjectToAddMod__measObject_PR_measObjectEUTRA; + MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 36090; + MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = AllowedMeasBandwidth_mbw25; + MeasObj->measObject.choice.measObjectEUTRA.presenceAntennaPort1 = 1; + MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf = CALLOC (1, sizeof (uint8_t)); + MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf[0] = 0; + MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.size = 1; + MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.bits_unused = 6; + MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = NULL; // Default is 15 or 0dB + + MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList = (CellsToAddModList_t *) CALLOC (1, sizeof (*CellsToAddModList)); + CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList; + + // Add adjacent cell lists (6 per eNB) + for (i = 0; i < 6; i++) { + CellToAdd = (CellsToAddMod_t *) CALLOC (1, sizeof (*CellToAdd)); + CellToAdd->cellIndex = i + 1; + CellToAdd->physCellId = get_adjacent_cell_id (Mod_id, i); + CellToAdd->cellIndividualOffset = Q_OffsetRange_dB0; + + ASN_SEQUENCE_ADD (&CellsToAddModList->list, CellToAdd); + } + + ASN_SEQUENCE_ADD (&MeasObj_list->list, MeasObj); + // rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measObjectToAddModList = MeasObj_list; + + // Report Configurations for periodical, A1-A5 events + ReportConfig_list = CALLOC (1, sizeof (*ReportConfig_list)); + memset ((void *) ReportConfig_list, 0, sizeof (*ReportConfig_list)); + + ReportConfig_per = CALLOC (1, sizeof (*ReportConfig_per)); + memset ((void *) ReportConfig_per, 0, sizeof (*ReportConfig_per)); + + ReportConfig_A1 = CALLOC (1, sizeof (*ReportConfig_A1)); + memset ((void *) ReportConfig_A1, 0, sizeof (*ReportConfig_A1)); + + ReportConfig_A2 = CALLOC (1, sizeof (*ReportConfig_A2)); + memset ((void *) ReportConfig_A2, 0, sizeof (*ReportConfig_A2)); + + ReportConfig_A3 = CALLOC (1, sizeof (*ReportConfig_A3)); + memset ((void *) ReportConfig_A3, 0, sizeof (*ReportConfig_A3)); + + ReportConfig_A4 = CALLOC (1, sizeof (*ReportConfig_A4)); + memset ((void *) ReportConfig_A4, 0, sizeof (*ReportConfig_A4)); + + ReportConfig_A5 = CALLOC (1, sizeof (*ReportConfig_A5)); + memset ((void *) ReportConfig_A5, 0, sizeof (*ReportConfig_A5)); + + ReportConfig_per->reportConfigId = 1; + ReportConfig_per->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.present = ReportConfigEUTRA__triggerType_PR_periodical; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.choice.periodical.purpose =ReportConfigEUTRA__triggerType__periodical__purpose_reportStrongestCells; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerQuantity = ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportInterval = ReportInterval_ms120; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity; + + ASN_SEQUENCE_ADD (&ReportConfig_list->list, ReportConfig_per); + + ReportConfig_A1->reportConfigId = 2; + ReportConfig_A1->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.present = ReportConfigEUTRA__triggerType_PR_event; + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1; + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA1.a1_Threshold.present = ThresholdEUTRA_PR_threshold_RSRP; + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA1.a1_Threshold.choice.threshold_RSRP = 10; + + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerQuantity = ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both; + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportInterval = ReportInterval_ms120; + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity; + + ASN_SEQUENCE_ADD (&ReportConfig_list->list, ReportConfig_A1); + + ReportConfig_A2->reportConfigId = 3; + ReportConfig_A2->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.present = ReportConfigEUTRA__triggerType_PR_event; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA2.a2_Threshold.present = ThresholdEUTRA_PR_threshold_RSRP; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA2.a2_Threshold.choice.threshold_RSRP = 10; + + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerQuantity = ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportInterval = ReportInterval_ms120; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity; + + ASN_SEQUENCE_ADD(&ReportConfig_list->list,ReportConfig_A2); + + ReportConfig_A3->reportConfigId = 4; + ReportConfig_A3->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.present = ReportConfigEUTRA__triggerType_PR_event; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present= ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset = 10; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.reportOnLeave = 1; + + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerQuantity = ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportInterval = ReportInterval_ms120; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity; + + ASN_SEQUENCE_ADD(&ReportConfig_list->list,ReportConfig_A3); + + ReportConfig_A4->reportConfigId = 5; + ReportConfig_A4->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.present = ReportConfigEUTRA__triggerType_PR_event; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present= ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA4.a4_Threshold.present = ThresholdEUTRA_PR_threshold_RSRP; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA4.a4_Threshold.choice.threshold_RSRP = 10; + + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerQuantity = ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportInterval = ReportInterval_ms120; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity; + + ASN_SEQUENCE_ADD(&ReportConfig_list->list,ReportConfig_A4); + + ReportConfig_A5->reportConfigId = 6; + ReportConfig_A5->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.present = ReportConfigEUTRA__triggerType_PR_event; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = ReportConfigEUTRA__triggerType__event__eventId_PR_eventA5; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA5.a5_Threshold1.present = ThresholdEUTRA_PR_threshold_RSRP; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA5.a5_Threshold2.present = ThresholdEUTRA_PR_threshold_RSRP; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA5.a5_Threshold1.choice.threshold_RSRP = 10; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA5.a5_Threshold2.choice.threshold_RSRP = 10; + + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerQuantity = ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportInterval = ReportInterval_ms120; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity; + + ASN_SEQUENCE_ADD(&ReportConfig_list->list,ReportConfig_A5); + + Sparams = CALLOC(1,sizeof(*Sparams)); + Sparams->present=MeasConfig__speedStatePars_PR_setup; + Sparams->choice.setup.timeToTrigger_SF.sf_High=SpeedStateScaleFactors__sf_Medium_oDot75; + Sparams->choice.setup.timeToTrigger_SF.sf_Medium=SpeedStateScaleFactors__sf_High_oDot5; + Sparams->choice.setup.mobilityStateParameters.n_CellChangeHigh=10; + Sparams->choice.setup.mobilityStateParameters.n_CellChangeMedium=5; + Sparams->choice.setup.mobilityStateParameters.t_Evaluation=MobilityStateParameters__t_Evaluation_s60; + Sparams->choice.setup.mobilityStateParameters.t_HystNormal=MobilityStateParameters__t_HystNormal_s120; + + quantityConfig = CALLOC(1,sizeof(*quantityConfig)); + memset((void *)quantityConfig,0,sizeof(*quantityConfig)); + quantityConfig->quantityConfigEUTRA = CALLOC(1,sizeof(*quantityConfig->quantityConfigEUTRA)); + memset((void *)quantityConfig->quantityConfigEUTRA,0,sizeof(*quantityConfig->quantityConfigEUTRA)); + quantityConfig->quantityConfigCDMA2000 = NULL; + quantityConfig->quantityConfigGERAN = NULL; + quantityConfig->quantityConfigUTRA = NULL; + quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = CALLOC(1,sizeof(*quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP)); + quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = CALLOC(1,sizeof(*quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ)); + *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = FilterCoefficient_fc4; + *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = FilterCoefficient_fc4; + + + /* mobilityinfo */ + + mobilityInfo = CALLOC(1,sizeof(*mobilityInfo)); + memset((void *)mobilityInfo,0,sizeof(*mobilityInfo)); + mobilityInfo->targetPhysCellId = (PhysCellId_t) two_tier_hexagonal_cellIds[Mod_id, rrc_inst->handover_info[UE_index]->modid_t]; + LOG_D(RRC,"[eNB %d] Frame %d: handover preparation: targetPhysCellId: %d mod_id: %d UE_index: %d \n", + Mod_id,frame, mobilityInfo->targetPhysCellId,Mod_id,UE_index); + + mobilityInfo->additionalSpectrumEmission = CALLOC(1,sizeof(*mobilityInfo->additionalSpectrumEmission)); + *mobilityInfo->additionalSpectrumEmission = 1; //Check this value! + + mobilityInfo->t304 = MobilityControlInfo__t304_ms50; // need to configure an appropriate value here + + // New UE Identity (C-RNTI) to identify an UE uniquely in a cell + mobilityInfo->newUE_Identity.size = 2; + mobilityInfo->newUE_Identity.bits_unused = 0; + mobilityInfo->newUE_Identity.buf = rv; + mobilityInfo->newUE_Identity.buf[0] = rv[0]; + mobilityInfo->newUE_Identity.buf[1] = rv[1]; + + //memset((void *)&mobilityInfo->radioResourceConfigCommon,(void *)&rrc_inst->sib2->radioResourceConfigCommon,sizeof(RadioResourceConfigCommon_t)); + //memset((void *)&mobilityInfo->radioResourceConfigCommon,0,sizeof(RadioResourceConfigCommon_t)); + + // Configuring radioResourceConfigCommon + mobilityInfo->radioResourceConfigCommon.rach_ConfigCommon = CALLOC(1,sizeof(*mobilityInfo->radioResourceConfigCommon.rach_ConfigCommon)); + memcpy((void *)mobilityInfo->radioResourceConfigCommon.rach_ConfigCommon, + (void *)&rrc_inst->sib2->radioResourceConfigCommon.rach_ConfigCommon, + sizeof(RACH_ConfigCommon_t)); + mobilityInfo->radioResourceConfigCommon.prach_Config.prach_ConfigInfo = CALLOC(1,sizeof(*mobilityInfo->radioResourceConfigCommon.prach_Config.prach_ConfigInfo)); + memcpy((void *)mobilityInfo->radioResourceConfigCommon.prach_Config.prach_ConfigInfo, + (void *)&rrc_inst->sib2->radioResourceConfigCommon.prach_Config.prach_ConfigInfo, + sizeof(PRACH_ConfigInfo_t)); + + mobilityInfo->radioResourceConfigCommon.prach_Config.rootSequenceIndex = rrc_inst->sib2->radioResourceConfigCommon.prach_Config.rootSequenceIndex; + mobilityInfo->radioResourceConfigCommon.pdsch_ConfigCommon = CALLOC(1,sizeof(*mobilityInfo->radioResourceConfigCommon.pdsch_ConfigCommon)); + memcpy((void *)mobilityInfo->radioResourceConfigCommon.pdsch_ConfigCommon, + (void *)&rrc_inst->sib2->radioResourceConfigCommon.pdsch_ConfigCommon, + sizeof(PDSCH_ConfigCommon_t)); + memcpy((void *)&mobilityInfo->radioResourceConfigCommon.pusch_ConfigCommon, + (void *)&rrc_inst->sib2->radioResourceConfigCommon.pusch_ConfigCommon, + sizeof(PUSCH_ConfigCommon_t)); + mobilityInfo->radioResourceConfigCommon.phich_Config = NULL; + mobilityInfo->radioResourceConfigCommon.pucch_ConfigCommon = CALLOC(1,sizeof(*mobilityInfo->radioResourceConfigCommon.pucch_ConfigCommon)); + memcpy((void *)mobilityInfo->radioResourceConfigCommon.pucch_ConfigCommon, + (void *)&rrc_inst->sib2->radioResourceConfigCommon.pucch_ConfigCommon, + sizeof(PUCCH_ConfigCommon_t)); + mobilityInfo->radioResourceConfigCommon.soundingRS_UL_ConfigCommon = CALLOC(1,sizeof(*mobilityInfo->radioResourceConfigCommon.soundingRS_UL_ConfigCommon)); + memcpy((void *)mobilityInfo->radioResourceConfigCommon.soundingRS_UL_ConfigCommon, + (void *)&rrc_inst->sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon, + sizeof(SoundingRS_UL_ConfigCommon_t)); + mobilityInfo->radioResourceConfigCommon.uplinkPowerControlCommon = CALLOC(1,sizeof(*mobilityInfo->radioResourceConfigCommon.uplinkPowerControlCommon)); + memcpy((void *)mobilityInfo->radioResourceConfigCommon.uplinkPowerControlCommon, + (void *)&rrc_inst->sib2->radioResourceConfigCommon.uplinkPowerControlCommon, + sizeof(UplinkPowerControlCommon_t)); + mobilityInfo->radioResourceConfigCommon.antennaInfoCommon = NULL; + mobilityInfo->radioResourceConfigCommon.p_Max = NULL; // CALLOC(1,sizeof(*mobilityInfo->radioResourceConfigCommon.p_Max)); + //memcpy((void *)mobilityInfo->radioResourceConfigCommon.p_Max,(void *)rrc_inst->sib1->p_Max,sizeof(P_Max_t)); + mobilityInfo->radioResourceConfigCommon.tdd_Config = NULL; //CALLOC(1,sizeof(TDD_Config_t)); + //memcpy((void *)mobilityInfo->radioResourceConfigCommon.tdd_Config,(void *)rrc_inst->sib1->tdd_Config,sizeof(TDD_Config_t)); + mobilityInfo->radioResourceConfigCommon.ul_CyclicPrefixLength = rrc_inst->sib2->radioResourceConfigCommon.ul_CyclicPrefixLength; + //End of configuration of radioResourceConfigCommon + + mobilityInfo->carrierFreq = CALLOC(1,sizeof(*mobilityInfo->carrierFreq)); //CALLOC(1,sizeof(CarrierFreqEUTRA_t)); 36090 + mobilityInfo->carrierFreq->dl_CarrierFreq = 36090; + mobilityInfo->carrierFreq->ul_CarrierFreq = NULL; + + mobilityInfo->carrierBandwidth = CALLOC(1,sizeof(*mobilityInfo->carrierBandwidth)); //CALLOC(1,sizeof(struct CarrierBandwidthEUTRA)); AllowedMeasBandwidth_mbw25 + mobilityInfo->carrierBandwidth->dl_Bandwidth = CarrierBandwidthEUTRA__dl_Bandwidth_n25; + mobilityInfo->carrierBandwidth->ul_Bandwidth = NULL; + mobilityInfo->rach_ConfigDedicated = NULL; + + + // store the srb and drb list for ho management, mainly in case of failure + + memcpy((void *)rrc_inst->handover_info[UE_index]->as_config.sourceRadioResourceConfig.srb_ToAddModList, + (void *)SRB_configList2, + sizeof(SRB_ToAddModList_t)); + memcpy((void *)rrc_inst->handover_info[UE_index]->as_config.sourceRadioResourceConfig.drb_ToAddModList, + (void *)DRB_configList2, + sizeof(DRB_ToAddModList_t)); + rrc_inst->handover_info[UE_index]->as_config.sourceRadioResourceConfig.drb_ToReleaseList = NULL; + memcpy((void *)rrc_inst->handover_info[UE_index]->as_config.sourceRadioResourceConfig.mac_MainConfig, + (void *)mac_MainConfig, + sizeof(MAC_MainConfig_t)); + memcpy((void *)rrc_inst->handover_info[UE_index]->as_config.sourceRadioResourceConfig.physicalConfigDedicated, + (void *)rrc_inst->physicalConfigDedicated[UE_index], + sizeof(PhysicalConfigDedicated_t)); + /* memcpy((void *)rrc_inst->handover_info[UE_index]->as_config.sourceRadioResourceConfig.sps_Config, + (void *)rrc_inst->sps_Config[UE_index], + sizeof(SPS_Config_t)); + */ + LOG_I(RRC,"[eNB %d] Frame %d: adding new UE\n"); + Idx = (UE_index * NB_RB_MAX) + DCCH; + // SRB1 + eNB_rrc_inst[Mod_id].Srb1[UE_index].Active = 1; + eNB_rrc_inst[Mod_id].Srb1[UE_index].Srb_info.Srb_id = Idx; + memcpy (&eNB_rrc_inst[Mod_id].Srb1[UE_index].Srb_info.Lchan_desc[0], + &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE); + memcpy (&eNB_rrc_inst[Mod_id].Srb1[UE_index].Srb_info.Lchan_desc[1], + &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE); + + // SRB2 + eNB_rrc_inst[Mod_id].Srb2[UE_index].Active = 1; + eNB_rrc_inst[Mod_id].Srb2[UE_index].Srb_info.Srb_id = Idx; + memcpy (&eNB_rrc_inst[Mod_id].Srb2[UE_index].Srb_info.Lchan_desc[0], + &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE); + memcpy (&eNB_rrc_inst[Mod_id].Srb2[UE_index].Srb_info.Lchan_desc[1], + &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE); + + LOG_I (RRC,"[eNB %d] CALLING RLC CONFIG SRB1 (rbid %d) for UE %d\n",Mod_id, Idx, UE_index); + + // rrc_pdcp_config_req (Mod_id, frame, 1, ACTION_ADD, idx, UNDEF_SECURITY_MODE); + // rrc_rlc_config_req(Mod_id,frame,1,ACTION_ADD,Idx,SIGNALLING_RADIO_BEARER,Rlc_info_am_config); + + rrc_pdcp_config_asn1_req (Mod_id, frame, 1, UE_index, + eNB_rrc_inst[Mod_id].SRB_configList[UE_index], + (DRB_ToAddModList_t *) NULL, + (DRB_ToReleaseList_t *) NULL, + 0xff, + NULL, + NULL, + NULL +#ifdef Rel10 + , (PMCH_InfoList_r9_t *) NULL +#endif + ); + + rrc_rlc_config_asn1_req (Mod_id, frame, 1, UE_index, + eNB_rrc_inst[Mod_id].SRB_configList[UE_index], + (DRB_ToAddModList_t *) NULL, + (DRB_ToReleaseList_t *) NULL +#ifdef Rel10 + , (MBMS_SessionInfoList_r9_t *) NULL +#endif + ); + + + // rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list; + memset (buffer, 0, RRC_BUF_SIZE); + + size = do_RRCConnectionReconfiguration (Mod_id, buffer, UE_index, 0, //Transaction_id, + SRB_configList2, DRB_configList2, NULL, // DRB2_list, + NULL, //*sps_Config, + physicalConfigDedicated[UE_index], MeasObj_list, ReportConfig_list, + NULL, //quantityConfig, + MeasId_list, mac_MainConfig, NULL, mobilityInfo,Sparams, + NULL, NULL, nas_pdu, nas_length); + + LOG_I (RRC,"[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration for handover (bytes %d, UE id %d)\n", + Mod_id, frame, size, UE_index); + // to be updated if needed + /*if (eNB_rrc_inst[Mod_id].SRB1_config[UE_index]->logicalChannelConfig) { + if (eNB_rrc_inst[Mod_id].SRB1_config[UE_index]->logicalChannelConfig->present == SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { + SRB1_logicalChannelConfig = &eNB_rrc_inst[Mod_id].SRB1_config[UE_index]->logicalChannelConfig->choice.explicitValue; + } + else { + SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; + } + } + else { + SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; + } + */ + + LOG_D (RRC,"[MSC_MSG][FRAME %05d][RRC_eNB][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration_handover to UE %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n", + frame, Mod_id, size, UE_index, rrc_eNB_mui, Mod_id, + (UE_index * NB_RB_MAX) + DCCH); + + //rrc_rlc_data_req(Mod_id,frame, 1,(UE_index*NB_RB_MAX)+DCCH,rrc_eNB_mui++,0,size,(char*)buffer); + //pdcp_data_req (Mod_id, frame, 1, (UE_index * NB_RB_MAX) + DCCH,rrc_eNB_mui++, 0, size, (char *) buffer, 1); + rrc_mac_config_req (Mod_id, 1, UE_index, 0, + (RadioResourceConfigCommonSIB_t *) NULL, + eNB_rrc_inst[Mod_id].physicalConfigDedicated[UE_index], + (MeasObjectToAddMod_t **) NULL, + eNB_rrc_inst[Mod_id].mac_MainConfig[UE_index], + 1, + SRB1_logicalChannelConfig, + eNB_rrc_inst[Mod_id].measGapConfig[UE_index], + (TDD_Config_t *) NULL, + (MobilityControlInfo_t *)mobilityInfo, + (u8 *) NULL,(u16 *) NULL, NULL, NULL, NULL, + (MBSFN_SubframeConfigList_t *) NULL +#ifdef Rel10 + , + 0, + (MBSFN_AreaInfoList_r9_t *) NULL, + (PMCH_InfoList_r9_t *) NULL +#endif +#ifdef CBA + , + 0, + 0, +#endif + ); + + + handoverCommand.criticalExtensions.present = HandoverCommand__criticalExtensions_PR_c1; + handoverCommand.criticalExtensions.choice.c1.present = HandoverCommand__criticalExtensions__c1_PR_handoverCommand_r8; + handoverCommand.criticalExtensions.choice.c1.choice.handoverCommand_r8.handoverCommandMessage.buf = buffer; + handoverCommand.criticalExtensions.choice.c1.choice.handoverCommand_r8.handoverCommandMessage.size = size; + + if (sourceModId != 0xFF) { + memcpy(eNB_rrc_inst[sourceModId].handover_info[eNB_rrc_inst[Mod_id].handover_info[UE_index]->ueid_s]->buf, + (void *)buffer, + size); + eNB_rrc_inst[sourceModId].handover_info[eNB_rrc_inst[Mod_id].handover_info[UE_index]->ueid_s]->size = size; + eNB_rrc_inst[sourceModId].handover_info[eNB_rrc_inst[Mod_id].handover_info[UE_index]->ueid_s]->ho_complete = 0xF1; + //eNB_rrc_inst[Mod_id].handover_info[UE_index]->ho_complete = 0xFF; + LOG_D(RRC,"[eNB %d] Frame %d: setting handover complete to 0xF1 for (%d,%d) and to 0xFF for (%d,%d)\n", + Mod_id, frame, + sourceModId,eNB_rrc_inst[Mod_id].handover_info[UE_index]->ueid_s, + Mod_id, UE_index); + } + else + LOG_W(RRC,"[eNB %d] Frame %d: rrc_eNB_generate_RRCConnectionReconfiguration_handover: Could not find source eNB mod_id.\n", + Mod_id, frame); + + } void rrc_eNB_process_RRCConnectionReconfigurationComplete (u8 Mod_id, u32 frame, u8 UE_index, - RRCConnectionReconfigurationComplete_r8_IEs_t - * - rrcConnectionReconfigurationComplete) + RRCConnectionReconfigurationComplete_r8_IEs_t *rrcConnectionReconfigurationComplete) { int i; #ifdef NAS_NETLINK @@ -1680,10 +2593,8 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete (u8 Mod_id, u32 frame, uint8_t *kRRCint = NULL; uint8_t *kUPenc = NULL; - DRB_ToAddModList_t *DRB_configList = - eNB_rrc_inst[Mod_id].DRB_configList[UE_index]; - SRB_ToAddModList_t *SRB_configList = - eNB_rrc_inst[Mod_id].SRB_configList[UE_index]; + DRB_ToAddModList_t *DRB_configList = eNB_rrc_inst[Mod_id].DRB_configList[UE_index]; + SRB_ToAddModList_t *SRB_configList = eNB_rrc_inst[Mod_id].SRB_configList[UE_index]; #if defined(ENABLE_SECURITY) /* Derive the keys from kenb */ @@ -1802,16 +2713,15 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete (u8 Mod_id, u32 frame, DRB_configList->list.array[i]->logicalChannelIdentity; rrc_mac_config_req (Mod_id, 1, UE_index, 0, (RadioResourceConfigCommonSIB_t *) NULL, - eNB_rrc_inst[Mod_id]. - physicalConfigDedicated[UE_index], + eNB_rrc_inst[Mod_id].physicalConfigDedicated[UE_index], (MeasObjectToAddMod_t **) NULL, - eNB_rrc_inst[Mod_id]. - mac_MainConfig[UE_index], DRB2LCHAN[i], - DRB_configList->list.array[i]-> - logicalChannelConfig, - eNB_rrc_inst[Mod_id]. - measGapConfig[UE_index], - (TDD_Config_t *) NULL, (u8 *) NULL, + eNB_rrc_inst[Mod_id].mac_MainConfig[UE_index], + DRB2LCHAN[i], + DRB_configList->list.array[i]->logicalChannelConfig, + eNB_rrc_inst[Mod_id].measGapConfig[UE_index], + (TDD_Config_t *) NULL, + NULL, + (u8 *) NULL, (u16 *) NULL, NULL, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL #ifdef Rel10 @@ -1826,7 +2736,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete (u8 Mod_id, u32 frame, num_active_cba_groups, eNB_rrc_inst[Mod_id].cba_rnti[0] #endif - ); + ); } else @@ -1850,23 +2760,24 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete (u8 Mod_id, u32 frame, rrc_mac_config_req (Mod_id, 1, UE_index, 0, (RadioResourceConfigCommonSIB_t *) NULL, - eNB_rrc_inst[Mod_id]. - physicalConfigDedicated[UE_index], + eNB_rrc_inst[Mod_id].physicalConfigDedicated[UE_index], (MeasObjectToAddMod_t **) NULL, - eNB_rrc_inst[Mod_id]. - mac_MainConfig[UE_index], DRB2LCHAN[i], + eNB_rrc_inst[Mod_id].mac_MainConfig[UE_index], + DRB2LCHAN[i], (LogicalChannelConfig_t *) NULL, (MeasGapConfig_t *) NULL, - (TDD_Config_t *) NULL, (u8 *) NULL, + (TDD_Config_t *) NULL, + NULL, + (u8 *) NULL, (u16 *) NULL, NULL, NULL, NULL, NULL #ifdef Rel10 - , - 0, + ,0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) NULL #endif #ifdef CBA - , 0, 0 + ,0, + 0 #endif ); } @@ -1877,12 +2788,10 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete (u8 Mod_id, u32 frame, void -rrc_eNB_generate_RRCConnectionSetup (u8 Mod_id, u32 frame, u16 UE_index) -{ +rrc_eNB_generate_RRCConnectionSetup (u8 Mod_id, u32 frame, u16 UE_index) { LogicalChannelConfig_t *SRB1_logicalChannelConfig; //,*SRB2_logicalChannelConfig; - SRB_ToAddModList_t **SRB_configList = - &eNB_rrc_inst[Mod_id].SRB_configList[UE_index]; + SRB_ToAddModList_t **SRB_configList = &eNB_rrc_inst[Mod_id].SRB_configList[UE_index]; SRB_ToAddMod_t *SRB1_config; int cnt; @@ -1904,29 +2813,22 @@ rrc_eNB_generate_RRCConnectionSetup (u8 Mod_id, u32 frame, u16 UE_index) for (cnt = 0; cnt < (*SRB_configList)->list.count; cnt++) { if ((*SRB_configList)->list.array[cnt]->srb_Identity == 1) - { - + { SRB1_config = (*SRB_configList)->list.array[cnt]; - if (SRB1_config->logicalChannelConfig) { - if (SRB1_config->logicalChannelConfig->present == - SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) + if (SRB1_config->logicalChannelConfig->present == SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { - SRB1_logicalChannelConfig = - &SRB1_config->logicalChannelConfig->choice. - explicitValue; + SRB1_logicalChannelConfig = &SRB1_config->logicalChannelConfig->choice.explicitValue; } else { - SRB1_logicalChannelConfig = - &SRB1_logicalChannelConfig_defaultValue; + SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; } } else { - SRB1_logicalChannelConfig = - &SRB1_logicalChannelConfig_defaultValue; + SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; } LOG_D (RRC, @@ -1934,25 +2836,25 @@ rrc_eNB_generate_RRCConnectionSetup (u8 Mod_id, u32 frame, u16 UE_index) frame, Mod_id, UE_index, Mod_id); rrc_mac_config_req (Mod_id, 1, UE_index, 0, (RadioResourceConfigCommonSIB_t *) NULL, - eNB_rrc_inst[Mod_id]. - physicalConfigDedicated[UE_index], + eNB_rrc_inst[Mod_id].physicalConfigDedicated[UE_index], (MeasObjectToAddMod_t **) NULL, - eNB_rrc_inst[Mod_id]. - mac_MainConfig[UE_index], 1, + eNB_rrc_inst[Mod_id].mac_MainConfig[UE_index], + 1, SRB1_logicalChannelConfig, - eNB_rrc_inst[Mod_id]. - measGapConfig[UE_index], - (TDD_Config_t *) NULL, (u8 *) NULL, + eNB_rrc_inst[Mod_id].measGapConfig[UE_index], + (TDD_Config_t *) NULL, + NULL, + (u8 *) NULL, (u16 *) NULL, NULL, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL #ifdef Rel10 - , - 0, + ,0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) NULL #endif #ifdef CBA - , 0, 0 + ,0, + 0 #endif ); break; diff --git a/openair2/RRC/LITE/vars.h b/openair2/RRC/LITE/vars.h index 58b4af5fbda72fe7124aa14b2fbdf0f265b9673d..6c99a3e41d59a0617555b1faf0b766a9b6b08529 100644 --- a/openair2/RRC/LITE/vars.h +++ b/openair2/RRC/LITE/vars.h @@ -1,9 +1,40 @@ -/*________________________openair_rrc_vars.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 vars.hles +* \brief rrc variables +* \author Raymond Knopp and Navid Nikaein +* \date 2013 +* \version 1.0 +* \company Eurecom +* \email: navid.nikaein@eurecom.fr +*/ #ifndef __OPENAIR_RRC_VARS_H__ @@ -38,6 +69,8 @@ unsigned short Header_read_idx,Data_read_idx,Header_size; unsigned short Data_to_read; #endif //NO_RRM +#define MAX_U32 0xFFFFFFFF + u8 DRB2LCHAN[8]; long logicalChannelGroup0 = 0; @@ -66,7 +99,7 @@ LogicalChannelConfig_t SRB2_logicalChannelConfig_defaultValue = {&LCSRB2 , &logicalChannelSR_Mask_r9 #endif - }; + }; //CONSTANTS rlc_info_t Rlc_info_um,Rlc_info_am_config; @@ -75,4 +108,152 @@ u16 RACH_FREQ_ALLOC; LCHAN_DESC BCCH_LCHAN_DESC,CCCH_LCHAN_DESC,DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC; MAC_MEAS_T BCCH_MEAS_TRIGGER,CCCH_MEAS_TRIGGER,DCCH_MEAS_TRIGGER,DTCH_MEAS_TRIGGER; MAC_AVG_T BCCH_MEAS_AVG, CCCH_MEAS_AVG,DCCH_MEAS_AVG, DTCH_MEAS_AVG; + +// timers +u16 T300[8] = {100,200,300,400,600,1000,1500,2000}; +u16 T310[8] = {0,50,100,200,500,1000,2000}; +u16 N310[8] = {1,2,3,4,6,8,10,20}; +u16 N311[8] = {1,2,3,4,6,8,10,20}; +u32 T304[8] = {50,100,150,200,500,1000,2000,MAX_U32}; + +// TimeToTrigger enum mapping table (36.331 TimeToTrigger IE) +u32 timeToTrigger_ms[16] = {0,40,64,80,100,128,160,256,320,480,512,640,1024,1280,2560,5120}; + +/* 36.133 Section 9.1.4 RSRP Measurement Report Mapping, Table: 9.1.4-1 */ +float RSRP_meas_mapping[100] = { + -140, + -139, + -138, + -137, + -136, + -135, + -134, + -133, + -132, + -131, + -130, + -129, + -128, + -127, + -126, + -125, + -124, + -123, + -122, + -121, + -120, + -119, + -118, + -117, + -116, + -115, + -114, + -113, + -112, + -111, + -110, + -109, + -108, + -107, + -106, + -105, + -104, + -103, + -102, + -101, + -100, + -99, + -98, + -97, + -96, + -95, + -94, + -93, + -92, + -91, + -90, + -89, + -88, + -87, + -86, + -85, + -84, + -83, + -82, + -81, + -80, + -79, + -78, + -77, + -76, + -75, + -74, + -73, + -72, + -71, + -70, + -69, + -68, + -67, + -66, + -65, + -64, + -63, + -62, + -61, + -60, + -59, + -58, + -57, + -56, + -55, + -54, + -53, + -52, + -51, + -50, + -49, + -48, + -47, + -46, + -45, + -44 +}; + +float RSRQ_meas_mapping[33] = { + -19, + -18.5, + -18, + -17.5, + -17, + -16.5, + -16, + -15.5, + -15, + -14.5, + -14, + -13.5, + -13, + -12.5, + -12, + -11.5, + -11, + -10.5, + -10, + -9.5, + -9, + -8.5, + -8, + -7.5, + -7, + -6.5, + -6, + -5.5, + -5, + -4.5, + -4, + -3.5, + -3 +}; + #endif diff --git a/openair2/UTIL/OCG/OCG.h b/openair2/UTIL/OCG/OCG.h index 9a7e18b066b69db056afc632277c44055ee67134..23d5c9be6b1ed486eeaca859a3395ea0aa9fc966 100644 --- a/openair2/UTIL/OCG/OCG.h +++ b/openair2/UTIL/OCG/OCG.h @@ -661,6 +661,7 @@ The following diagram is based on graphviz (http://www.graphviz.org/), you need unsigned char vcd_enabled; unsigned char eMBMS_active_state; unsigned char cba_group_active; + unsigned char handover_active; char * otg_traffic; unsigned char otg_bg_traffic_enabled; unsigned char omg_model_rn; diff --git a/targets/RTAI/USER/lte-softmodem-usrp.c b/targets/RTAI/USER/lte-softmodem-usrp.c index 173dda2ef111ff179de6e6d6242f0b95066ccd5f..374861641cc984e516182d99c3ebddf3d51b3922 100644 --- a/targets/RTAI/USER/lte-softmodem-usrp.c +++ b/targets/RTAI/USER/lte-softmodem-usrp.c @@ -1109,7 +1109,8 @@ int main(int argc, char **argv) //print [MAC][I]... messages //l2_init(frame_parms,eMBMS_active); l2_init(frame_parms,eMBMS_active, - 0); // cba_group_active + 0,// cba_group_active + 0); // HO flag if (UE_flag == 1) mac_xface->dl_phy_sync_success (0, 0, 0, 1); else diff --git a/targets/RTAI/USER/lte-softmodem.c b/targets/RTAI/USER/lte-softmodem.c index cc4ed9778cbfc1214e1f48559ce7fbf904098864..dae158d599d733e19227ac8a1731a8858078d124 100644 --- a/targets/RTAI/USER/lte-softmodem.c +++ b/targets/RTAI/USER/lte-softmodem.c @@ -63,6 +63,7 @@ #include "PHY/vars.h" #include "MAC_INTERFACE/vars.h" +//#include "SCHED/defs.h" #include "SCHED/vars.h" #include "LAYER2/MAC/vars.h" @@ -1253,8 +1254,8 @@ int main(int argc, char **argv) { } PHY_vars_UE_g[0]->tx_power_max_dBm = tx_max_power; - - printf("tx_max_power = %d -> amp %d\n",tx_max_power,get_tx_amp(tx_max_power,tx_max_power)); + + // printf("tx_max_power = %d -> amp %d\n",tx_max_power,get_tx_amp(tx_max_power,tx_max_power)); } else { //this is eNB g_log->log_component[HW].level = LOG_DEBUG; @@ -1394,7 +1395,8 @@ int main(int argc, char **argv) { #ifdef OPENAIR2 int eMBMS_active=0; l2_init(frame_parms,eMBMS_active, - 0); // cba_group_active + 0,// cba_group_active + 0); // HO flag if (UE_flag == 1) mac_xface->dl_phy_sync_success (0, 0, 0, 1); else diff --git a/targets/SCRIPTS/svn-merge-meld.py b/targets/SCRIPTS/svn-merge-meld.py new file mode 100755 index 0000000000000000000000000000000000000000..a05d697f2e0f1d4db9332b302f86e371a62c00c0 --- /dev/null +++ b/targets/SCRIPTS/svn-merge-meld.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python +# svn merge-tool python wrapper for meld +# to use: edit ~/.subversion/config and uncomment the line merge-tool-cmd = +# and set the path to your command + +# Note that when a conflict occurs, you will be prompted what to do with it. You need to type a single 'l' and for svn to run this script. When you've finished your merge, you need to type an 'r' to resolve the conflict and copy the merged version to the working copy. + +import os, sys +import subprocess +import shutil + +try: + # path to meld + meld = "/usr/bin/meld" + + print "Set the file paths for mine, theirs, and merged\n" + print "When you've finished your merge, you need to type an 'r' to resolve the conflict and copy the merged version to the working copy\n" + + # the base or "left" revision version of the file you're merging with + base = sys.argv[1] + + # this is "later" or "right"revision version of the file you're merging with + theirs = sys.argv[2] + + # this is my version, recommandations: sync your copy to the latest version + mine = sys.argv[3] + + #this starts out as a copy of 'mine' (your working copy), and this is where you want the final results of the merge to end up. + merged = sys.argv[4] + + print "Calling meld: the order of the files is (merged, theirs, and mine)" + # all 4 versions: worke right-to-left, reslut being stored in the left file + # cmd = [meld, mine, base, theirs, merged] + # only 3 versions + cmd = [meld, merged, theirs, mine] + + # Call meld, making sure it exits correctly + subprocess.check_call(cmd) +except: + print "Oh, an error!\n" + sys.exit(-1) diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index a39dbf92e47a739d48c99c2ac29482c07eaf56b0..391517e0603a5e0827c5ebd2597dcdcb3ceebf92 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -150,27 +150,28 @@ int otg_enabled; #endif // this should reflect the channel models in openair1/SIMULATION/TOOLS/defs.h -mapping small_scale_names[] = - { - {"custom", custom}, - {"SCM_A", SCM_A}, - {"SCM_B", SCM_B}, - {"SCM_C", SCM_C}, - {"SCM_D", SCM_D}, - {"EPA", EPA}, - {"EVA", EVA}, - {"ETU", ETU}, - {"Rayleigh8", Rayleigh8}, - {"Rayleigh1", Rayleigh1}, - {"Rayleigh1_800", Rayleigh1_800}, - {"Rayleigh1_corr", Rayleigh1_corr}, - {"Rayleigh1_anticorr", Rayleigh1_anticorr}, - {"Rice8", Rice8}, - {"Rice1", Rice1}, - {"Rice1_corr", Rice1_corr}, - {"Rice1_anticorr", Rice1_anticorr}, - {"AWGN", AWGN}, - {NULL, -1}}; +mapping small_scale_names[] = { + {"custom", custom}, + {"SCM_A", SCM_A}, + {"SCM_B", SCM_B}, + {"SCM_C", SCM_C}, + {"SCM_D", SCM_D}, + {"EPA", EPA}, + {"EVA", EVA}, + {"ETU", ETU}, + {"MBSFN", MBSFN}, + {"Rayleigh8", Rayleigh8}, + {"Rayleigh1", Rayleigh1}, + {"Rayleigh1_800", Rayleigh1_800}, + {"Rayleigh1_corr", Rayleigh1_corr}, + {"Rayleigh1_anticorr", Rayleigh1_anticorr}, + {"Rice8", Rice8}, + {"Rice1", Rice1}, + {"Rice1_corr", Rice1_corr}, + {"Rice1_anticorr", Rice1_anticorr}, + {"AWGN", AWGN}, + {NULL, -1} +}; //static void *sigh(void *arg); void terminate(void); @@ -194,6 +195,7 @@ void help(void) { printf ("-F Activates FDD transmission (TDD is default)\n"); printf ("-g Set multicast group ID (0,1,2,3) - valid if M is set\n"); printf ("-G Enable background traffic \n"); + printf ("-H Enable handover operation (default disabled) \n"); printf ("-I Enable CLI interface (to connect use telnet localhost 1352)\n"); printf ("-k Set the Ricean factor (linear)\n"); printf ("-l Set the global log level (8:trace, 7:debug, 6:info, 4:warn, 3:error) \n"); diff --git a/targets/SIMU/USER/oaisim_config.c b/targets/SIMU/USER/oaisim_config.c index a46c8678beba22b4fb3e0c9a7e42293727e4e404..575c1b30f88b97cb673bbaeb6cfa7f8a73869935 100644 --- a/targets/SIMU/USER/oaisim_config.c +++ b/targets/SIMU/USER/oaisim_config.c @@ -325,12 +325,15 @@ void init_oai_emulation() { oai_emulation.info.vcd_enabled=0; oai_emulation.info.cba_group_active=0; oai_emulation.info.eMBMS_active_state=0; + oai_emulation.info.handover_active=0; oai_emulation.info.omg_model_enb=STATIC; //default to static mobility model oai_emulation.info.omg_model_rn=STATIC; //default to static mobility model oai_emulation.info.omg_model_ue=STATIC; //default to static mobility model oai_emulation.info.omg_model_ue_current=STATIC; //default to static mobility model oai_emulation.info.otg_traffic="no_predefined_traffic"; oai_emulation.info.otg_bg_traffic_enabled = 0; // G flag + oai_emulation.info.max_predefined_traffic_config_index = 0; + oai_emulation.info.max_customized_traffic_config_index = 0; oai_emulation.info.frame = 0; // frame counter of emulation oai_emulation.info.time_s = 0; // time of emulation oai_emulation.info.time_ms = 0; // time of emulation @@ -664,6 +667,7 @@ int ocg_config_app(){ init_seeds(g_otg->seed); // initialize all the nodes, then configure the nodes the user specifically did in the XML in the following LOG_I(OTG,"oai_emulation.info.max_predefined_traffic_config_index = %d\n", oai_emulation.info.max_predefined_traffic_config_index); + LOG_I(OTG,"oai_emulation.info.max_customized_traffic_config_index = %d\n", oai_emulation.info.max_customized_traffic_config_index); if (oai_emulation.info.ocg_ok) { @@ -964,7 +968,9 @@ g_otg->application_idx[source_id_index][destination_id_index]+=1; } } } - if ( oai_emulation.info.otg_enabled==1){ // OCG not used, but -T option is used, so config here + if ((oai_emulation.info.max_predefined_traffic_config_index == 0) && + (oai_emulation.info.max_customized_traffic_config_index == 0) && + (oai_emulation.info.otg_enabled==1)){ // OCG not used to configure OTG, but -T option is used, so config here LOG_I(OTG,"configure OTG through options %s\n", oai_emulation.info.otg_traffic); for (i=0; i<g_otg->num_nodes; i++){ for (j=0; j<g_otg->num_nodes; j++){ diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index 7bdda0f7c10e07e00812b108d572175c8db02c60..c349e2fbdad93af24ce5c6b909417216c6369639 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -114,7 +114,7 @@ void get_simulation_options(int argc, char *argv[]) { {NULL, 0, NULL, 0} }; - while ((c = getopt_long (argc, argv, "aA:b:B:c:C:D:d:eE:f:FGg:hi:IJ:j:k:K:L:l:m:M:n:N:oO:p:P:Q:rR:s:S:t:T:u:U:vVw:W:x:X:y:Y:z:Z:", long_options, &option_index)) != -1) { + while ((c = getopt_long (argc, argv, "aA:b:B:c:C:D:d:eE:f:FGg:hHi:IJ:j:k:l:L:m:M:n:N:oO:p:P:Q:rR:s:S:t:T:u:U:vVw:W:x:X:y:Y:z:Z:", long_options, &option_index)) != -1) { switch (c) { case 0: if (! strcmp(long_options[option_index].name, "pdcp_period")) { @@ -139,7 +139,7 @@ void get_simulation_options(int argc, char *argv[]) { case 'C': oai_emulation.info.tdd_config = atoi (optarg); if (oai_emulation.info.tdd_config > 6) { - LOG_E(EMU,"Illegal tdd_config %d (should be 0-6)\n", oai_emulation.info.tdd_config); + printf("Illegal tdd_config %d (should be 0-6)\n", oai_emulation.info.tdd_config); exit (-1); } break; @@ -152,23 +152,28 @@ void get_simulation_options(int argc, char *argv[]) { oai_emulation.info.N_RB_DL = atoi (optarg); if ((oai_emulation.info.N_RB_DL != 6) && (oai_emulation.info.N_RB_DL != 15) && (oai_emulation.info.N_RB_DL != 25) && (oai_emulation.info.N_RB_DL != 50) && (oai_emulation.info.N_RB_DL != 75) && (oai_emulation.info.N_RB_DL != 100)) { - LOG_E(EMU,"Illegal N_RB_DL %d (should be one of 6,15,25,50,75,100)\n", oai_emulation.info.N_RB_DL); + printf("Illegal N_RB_DL %d (should be one of 6,15,25,50,75,100)\n", oai_emulation.info.N_RB_DL); exit (-1); } case 'N': Nid_cell = atoi (optarg); if (Nid_cell > 503) { - LOG_E(EMU,"Illegal Nid_cell %d (should be 0 ... 503)\n", Nid_cell); + printf("Illegal Nid_cell %d (should be 0 ... 503)\n", Nid_cell); exit(-1); } break; case 'h': help (); exit (1); + break; + case 'H': + oai_emulation.info.handover_active=1; + printf("Activate the handover procedure at RRC\n"); + break; case 'x': oai_emulation.info.transmission_mode = atoi (optarg); if ((oai_emulation.info.transmission_mode != 1) && (oai_emulation.info.transmission_mode != 2) && (oai_emulation.info.transmission_mode != 5) && (oai_emulation.info.transmission_mode != 6)) { - LOG_E(EMU, "Unsupported transmission mode %d\n",oai_emulation.info.transmission_mode); + printf("Unsupported transmission mode %d\n",oai_emulation.info.transmission_mode); exit(-1); } break; @@ -211,7 +216,7 @@ void get_simulation_options(int argc, char *argv[]) { break; case 'k': //ricean_factor = atof (optarg); - LOG_E(EMU,"[SIM] Option k is no longer supported on the command line. Please specify your channel model in the xml template\n"); + printf("[SIM] Option k is no longer supported on the command line. Please specify your channel model in the xml template\n"); exit(-1); break; case 'K': @@ -219,7 +224,7 @@ void get_simulation_options(int argc, char *argv[]) { break; case 't': //Td = atof (optarg); - LOG_E(EMU,"[SIM] Option t is no longer supported on the command line. Please specify your channel model in the xml template\n"); + printf("[SIM] Option t is no longer supported on the command line. Please specify your channel model in the xml template\n"); exit(-1); break; case 'f': @@ -575,7 +580,7 @@ void init_openair2() { #ifdef OPENAIR2 s32 i; s32 UE_id; - + #if defined(ENABLE_ITTI) if (NB_eNB_INST > 0) { if (itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL) < 0) { @@ -594,13 +599,12 @@ void init_openair2() { } #endif - l2_init (&PHY_vars_eNB_g[0]->lte_frame_parms,oai_emulation.info.eMBMS_active_state, oai_emulation.info.cba_group_active); - printf ("after L2 init: Nid_cell %d\n", PHY_vars_eNB_g[0]->lte_frame_parms.Nid_cell); - printf ("after L2 init: frame_type %d,tdd_config %d\n", - PHY_vars_eNB_g[0]->lte_frame_parms.frame_type, - PHY_vars_eNB_g[0]->lte_frame_parms.tdd_config); + l2_init (&PHY_vars_eNB_g[0]->lte_frame_parms, + oai_emulation.info.eMBMS_active_state, + oai_emulation.info.cba_group_active, + oai_emulation.info.handover_active); - for (i = 0; i < NB_eNB_INST; i++) + for (i = 0; i < NB_eNB_INST; i++) mac_xface->mrbch_phy_sync_failure (i, 0, i); if (abstraction_flag == 1) {